Decode + validate. Returns NULL on success, else a static teaching error. */
| 6123 | |
| 6124 | /* Decode + validate. Returns NULL on success, else a static teaching error. */ |
| 6125 | static const char *trace_cursor_decode(const char *token, const char *current_generation, |
| 6126 | uint64_t expected_qhash, trace_cursor_t *out) { |
| 6127 | memset(out, 0, sizeof(*out)); |
| 6128 | if (!token || strncmp(token, "c1.", 3) != 0) { |
| 6129 | return "invalid_cursor: unrecognized token — re-run the original query without 'cursor'"; |
| 6130 | } |
| 6131 | const char *p = token + 3; |
| 6132 | if (*p != 'o' && *p != 'i') { |
| 6133 | return "invalid_cursor: unrecognized token — re-run the original query without 'cursor'"; |
| 6134 | } |
| 6135 | out->leg = *p; |
| 6136 | p += 2; /* leg + '.' */ |
| 6137 | const char *gen_end = strchr(p, '.'); |
| 6138 | if (!gen_end || (size_t)(gen_end - p) >= sizeof(out->generation)) { |
| 6139 | return "invalid_cursor: unrecognized token — re-run the original query without 'cursor'"; |
| 6140 | } |
| 6141 | memcpy(out->generation, p, (size_t)(gen_end - p)); |
| 6142 | out->generation[gen_end - p] = '\0'; |
| 6143 | unsigned long long qh = 0; |
| 6144 | long long nid = 0; |
| 6145 | if (sscanf(gen_end + 1, "%16llx.%d.%lld", &qh, &out->hop, &nid) != 3) { |
| 6146 | return "invalid_cursor: unrecognized token — re-run the original query without 'cursor'"; |
| 6147 | } |
| 6148 | out->qhash = qh; |
| 6149 | out->node_id = nid; |
| 6150 | if (out->qhash != expected_qhash) { |
| 6151 | return "cursor_params_mismatch: this cursor was issued for different arguments — " |
| 6152 | "pass the cursor back with ALL other arguments identical"; |
| 6153 | } |
| 6154 | if (strcmp(out->generation, current_generation) != 0) { |
| 6155 | return "stale_cursor: the project was reindexed since this cursor was issued — " |
| 6156 | "re-run the original query without 'cursor' (node identities changed)"; |
| 6157 | } |
| 6158 | return NULL; |
| 6159 | } |
| 6160 | |
| 6161 | /* Slice a canonically-ordered traversal at the watermark: index of the first |
| 6162 | * row strictly AFTER (hop, id). */ |
no outgoing calls
no test coverage detected