v0.1.12 - Fix if-else chain bug preventing SELECTOR_ROLE_PATH derivation; fix parser to not treat 44' as variable; handle hardened markers on range/set segments
This commit is contained in:
+28
-9
@@ -800,8 +800,8 @@ int socket_name_random(char *out, size_t out_len);
|
||||
/* Version information (auto-updated by build/version tooling) */
|
||||
#define NSIGNER_VERSION_MAJOR 0
|
||||
#define NSIGNER_VERSION_MINOR 1
|
||||
#define NSIGNER_VERSION_PATCH 11
|
||||
#define NSIGNER_VERSION "v0.1.11"
|
||||
#define NSIGNER_VERSION_PATCH 12
|
||||
#define NSIGNER_VERSION "v0.1.12"
|
||||
|
||||
|
||||
/* NSIGNER_HEADERLESS_DECLS_END */
|
||||
@@ -2063,8 +2063,21 @@ static int parse_path_template_for_role(const char *token,
|
||||
seg[seg_len] = '\0';
|
||||
|
||||
if (!found_range) {
|
||||
/* Check for range/set markers first. Only strip hardened marker
|
||||
* (' or h) from segments that contain - or + (range/set forms).
|
||||
* A plain number with ' (like 44') is a literal hardened constant,
|
||||
* NOT a variable. */
|
||||
char *plus = strchr(seg, '+');
|
||||
char *dash = strchr(seg, '-');
|
||||
int is_range_or_set = (plus != NULL || dash != NULL);
|
||||
|
||||
int seg_hardened = 0;
|
||||
if (is_range_or_set && seg_len > 0 &&
|
||||
(seg[seg_len - 1] == '\'' || seg[seg_len - 1] == 'h' || seg[seg_len - 1] == 'H')) {
|
||||
seg_hardened = 1;
|
||||
seg[seg_len - 1] = '\0';
|
||||
seg_len--;
|
||||
}
|
||||
|
||||
if (plus != NULL) {
|
||||
/* Set form: "1+34+54" or "1+3-5+10" */
|
||||
@@ -2104,11 +2117,12 @@ static int parse_path_template_for_role(const char *token,
|
||||
*allowed_count_out = set_count;
|
||||
*range_lo = allowed_indices_out[0];
|
||||
*range_hi = allowed_indices_out[set_count - 1];
|
||||
if (strlen(template_out) + 3 >= template_sz) return -1;
|
||||
if (strlen(template_out) + 5 >= template_sz) return -1;
|
||||
strcat(template_out, "%d");
|
||||
if (seg_hardened) strcat(template_out, "'");
|
||||
strcat(template_out, "/");
|
||||
} else {
|
||||
if (strlen(template_out) + seg_len + 2 >= template_sz) return -1;
|
||||
if (strlen(template_out) + seg_len + 3 >= template_sz) return -1;
|
||||
strcat(template_out, seg);
|
||||
strcat(template_out, "/");
|
||||
}
|
||||
@@ -2119,30 +2133,35 @@ static int parse_path_template_for_role(const char *token,
|
||||
long lo = strtol(seg, &e1, 10);
|
||||
long hi = strtol(dash + 1, &e2, 10);
|
||||
if (*e1 != '\0' || *e2 != '\0' || lo < 0 || hi < 0 || lo > hi) {
|
||||
if (strlen(template_out) + seg_len + 2 >= template_sz) return -1;
|
||||
*dash = '-'; /* restore dash */
|
||||
if (strlen(template_out) + seg_len + 3 >= template_sz) return -1;
|
||||
strcat(template_out, seg);
|
||||
strcat(template_out, "/");
|
||||
} else {
|
||||
found_range = 1;
|
||||
*range_lo = (int)lo;
|
||||
*range_hi = (int)hi;
|
||||
if (strlen(template_out) + 3 >= template_sz) return -1;
|
||||
if (strlen(template_out) + 5 >= template_sz) return -1;
|
||||
strcat(template_out, "%d");
|
||||
if (seg_hardened) strcat(template_out, "'");
|
||||
strcat(template_out, "/");
|
||||
}
|
||||
} else {
|
||||
/* Single number */
|
||||
/* Single number — only treat as variable if NO hardened marker.
|
||||
* A segment like "44'" is a literal hardened constant. */
|
||||
char *e = NULL;
|
||||
long v = strtol(seg, &e, 10);
|
||||
if (*e != '\0' || v < 0) {
|
||||
if (strlen(template_out) + seg_len + 2 >= template_sz) return -1;
|
||||
/* Not a plain number (has ' or other chars) — literal */
|
||||
if (strlen(template_out) + seg_len + 3 >= template_sz) return -1;
|
||||
strcat(template_out, seg);
|
||||
strcat(template_out, "/");
|
||||
} else {
|
||||
/* Plain number without ' — this is the variable */
|
||||
found_range = 1;
|
||||
*range_lo = (int)v;
|
||||
*range_hi = (int)v;
|
||||
if (strlen(template_out) + 3 >= template_sz) return -1;
|
||||
if (strlen(template_out) + 5 >= template_sz) return -1;
|
||||
strcat(template_out, "%d");
|
||||
strcat(template_out, "/");
|
||||
}
|
||||
|
||||
+6
-1
@@ -2374,7 +2374,8 @@ int server_handle_one(server_ctx_t *ctx, server_activity_cb cb, void *cb_data) {
|
||||
if (extract_method_and_selector(request, method, sizeof(method), &selector_req) == 0) {
|
||||
if (ctx->dispatcher->role_table != NULL) {
|
||||
selector_rc = selector_resolve(&selector_req, ctx->dispatcher->role_table, &role);
|
||||
if (selector_rc == SELECTOR_OK && role != NULL) {
|
||||
if (selector_rc == SELECTOR_OK && role != NULL &&
|
||||
role->selector_type == SELECTOR_NOSTR_INDEX) {
|
||||
json_copy_string(role_name, sizeof(role_name), role->name, "main");
|
||||
json_copy_string(purpose, sizeof(purpose), role_purpose_to_str(role->purpose), "nostr");
|
||||
} else if (selector_rc == SELECTOR_ERR_NOT_FOUND && selector_req.has_nostr_index) {
|
||||
@@ -2398,6 +2399,8 @@ int server_handle_one(server_ctx_t *ctx, server_activity_cb cb, void *cb_data) {
|
||||
role->selector_type == SELECTOR_ROLE_PATH &&
|
||||
strstr(role->role_path, "%d") == NULL) {
|
||||
/* Fixed-path named role — no index needed, derive if not yet done */
|
||||
json_copy_string(role_name, sizeof(role_name), role->name, "main");
|
||||
json_copy_string(purpose, sizeof(purpose), role_purpose_to_str(role->purpose), "nostr");
|
||||
if (!role->derived) {
|
||||
pending_derivation = 1;
|
||||
}
|
||||
@@ -2405,6 +2408,8 @@ int server_handle_one(server_ctx_t *ctx, server_activity_cb cb, void *cb_data) {
|
||||
role->selector_type == SELECTOR_ROLE_PATH &&
|
||||
strstr(role->role_path, "%d") != NULL) {
|
||||
/* Named path-role with template — resolve the concrete path from index */
|
||||
json_copy_string(role_name, sizeof(role_name), role->name, "main");
|
||||
json_copy_string(purpose, sizeof(purpose), role_purpose_to_str(role->purpose), "nostr");
|
||||
int chosen_index;
|
||||
if (selector_req.has_index) {
|
||||
chosen_index = selector_req.index;
|
||||
|
||||
Reference in New Issue
Block a user