fix text header chasing

This commit is contained in:
2026-02-06 23:20:48 -06:00
parent 1e4646999d
commit 168f7c71d5

View File

@@ -21907,32 +21907,18 @@ static JSValue js_cell_text_trim (JSContext *ctx, JSValue this_val, int argc, JS
if (argc < 1) return JS_NULL;
if (!JS_IsText (argv[0])) return JS_NULL;
JSGCRef str_ref;
JS_PushGCRef (ctx, &str_ref);
str_ref.val = JS_ToString (ctx, argv[0]);
if (JS_IsException (str_ref.val)) {
JS_PopGCRef (ctx, &str_ref);
return str_ref.val;
}
JSText *p = JS_VALUE_GET_STRING (str_ref.val);
JSValue str = argv[0];
int start = 0;
int end = (int)JSText_len (p);
int end = js_string_value_len (str);
if (argc > 1 && !JS_IsNull (argv[1])) {
/* Custom trim with reject characters */
const char *reject = JS_ToCString (ctx, argv[1]);
if (!reject) {
JS_PopGCRef (ctx, &str_ref);
return JS_EXCEPTION;
}
if (!reject) return JS_EXCEPTION;
size_t reject_len = strlen (reject);
/* Re-chase p after JS_ToCString which can trigger GC */
p = JS_VALUE_GET_STRING (str_ref.val);
while (start < end) {
uint32_t c = string_get (p, start);
uint32_t c = js_string_value_get (str, start);
int found = 0;
for (size_t i = 0; i < reject_len; i++) {
if (c == (uint8_t)reject[i]) {
@@ -21944,7 +21930,7 @@ static JSValue js_cell_text_trim (JSContext *ctx, JSValue this_val, int argc, JS
start++;
}
while (end > start) {
uint32_t c = string_get (p, end - 1);
uint32_t c = js_string_value_get (str, end - 1);
int found = 0;
for (size_t i = 0; i < reject_len; i++) {
if (c == (uint8_t)reject[i]) {
@@ -21958,17 +21944,13 @@ static JSValue js_cell_text_trim (JSContext *ctx, JSValue this_val, int argc, JS
JS_FreeCString (ctx, reject);
} else {
/* Default: trim whitespace */
while (start < end && lre_is_space (string_get (p, start)))
while (start < end && lre_is_space (js_string_value_get (str, start)))
start++;
while (end > start && lre_is_space (string_get (p, end - 1)))
while (end > start && lre_is_space (js_string_value_get (str, end - 1)))
end--;
}
/* Re-chase before js_sub_string */
p = JS_VALUE_GET_STRING (str_ref.val);
JSValue result = js_sub_string (ctx, p, start, end);
JS_PopGCRef (ctx, &str_ref);
return result;
return js_sub_string_val (ctx, str, start, end);
}
/* text.codepoint(str) - get first codepoint */
@@ -22386,9 +22368,7 @@ static JSValue js_cell_text_search (JSContext *ctx, JSValue this_val, int argc,
if (JS_SetPropertyStr (ctx, rx, "lastIndex", JS_NewInt32 (ctx, 0)) < 0)
goto fail_rx_search;
/* Re-chase p before js_sub_string */
JSText *p = JS_VALUE_GET_STRING (str);
JSValue sub_str = js_sub_string (ctx, p, from, len);
JSValue sub_str = js_sub_string_val (ctx, str, from, len);
if (JS_IsException (sub_str)) goto fail_rx_search;
JSValue exec_res = JS_Invoke (ctx, rx, JS_KEY_exec, 1, (JSValue *)&sub_str);
@@ -22499,9 +22479,7 @@ static JSValue js_cell_text_extract (JSContext *ctx, JSValue this_val, int argc,
if (from == 0 && to == len) {
sub_str = str;
} else {
/* Re-chase p before js_sub_string */
JSText *p = JS_VALUE_GET_STRING (str);
sub_str = js_sub_string (ctx, p, from, to);
sub_str = js_sub_string_val (ctx, str, from, to);
if (JS_IsException (sub_str)) goto fail_rx;
}
@@ -22566,28 +22544,35 @@ static JSValue js_cell_text_extract (JSContext *ctx, JSValue this_val, int argc,
JSValue needle_val = JS_ToString (ctx, argv[1]);
if (JS_IsException (needle_val)) return JS_EXCEPTION;
int needle_len = (int)JSText_len (JS_VALUE_GET_STRING (needle_val));
int needle_len = js_string_value_len (needle_val);
/* Re-chase both p and needle right before js_str_find_range */
JSText *p = JS_VALUE_GET_STRING (str);
JSText *needle = JS_VALUE_GET_STRING (needle_val);
int pos = js_str_find_range (p, from, to, needle);
/* Find needle in str[from..to) */
int pos = -1;
if (needle_len == 0) {
pos = from;
} else if (needle_len <= (to - from)) {
int limit = to - needle_len;
for (int i = from; i <= limit; i++) {
int j = 0;
for (; j < needle_len; j++) {
if (js_string_value_get (str, i + j) != js_string_value_get (needle_val, j))
break;
}
if (j == needle_len) { pos = i; break; }
}
}
if (pos < 0) return JS_NULL;
JSValue arr = JS_NewArrayLen (ctx, 1);
if (JS_IsException (arr)) return JS_EXCEPTION;
/* Re-chase p before js_sub_string */
p = JS_VALUE_GET_STRING (str);
JSValue match = js_sub_string (ctx, p, pos, pos + needle_len);
if (JS_IsException (match)) {
JSValue match = js_sub_string_val (ctx, str, pos, pos + needle_len);
if (JS_IsException (match))
return JS_EXCEPTION;
}
if (JS_SetPropertyUint32 (ctx, arr, 0, match) < 0) {
if (JS_SetPropertyUint32 (ctx, arr, 0, match) < 0)
return JS_EXCEPTION;
}
return arr;
}
@@ -22609,20 +22594,17 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
int is_record = JS_IsRecord (collection);
if (!is_array && !is_record) return JS_NULL;
int len = (int)JSText_len (JS_VALUE_GET_STRING (text_val));
int len = js_string_value_len (text_val);
JSText *result = pretext_init (ctx, len);
if (!result) return JS_EXCEPTION;
int pos = 0;
while (pos < len) {
/* Re-chase sp at the start of each loop iteration */
JSText *sp = JS_VALUE_GET_STRING (text_val);
/* Find next '{' */
int brace_start = -1;
for (int i = pos; i < len; i++) {
if (string_get (sp, i) == '{') {
if (js_string_value_get (text_val, i) == '{') {
brace_start = i;
break;
}
@@ -22630,8 +22612,7 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
if (brace_start < 0) {
/* No more braces, copy rest of string */
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
JSValue tail = js_sub_string (ctx, sp, pos, len);
JSValue tail = js_sub_string_val (ctx, text_val, pos, len);
if (JS_IsException (tail)) return JS_EXCEPTION;
result = pretext_concat_value (ctx, result, tail);
break;
@@ -22639,20 +22620,16 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
/* Copy text before brace */
if (brace_start > pos) {
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
JSValue prefix = js_sub_string (ctx, sp, pos, brace_start);
JSValue prefix = js_sub_string_val (ctx, text_val, pos, brace_start);
if (JS_IsException (prefix)) return JS_EXCEPTION;
result = pretext_concat_value (ctx, result, prefix);
if (!result) return JS_EXCEPTION;
}
/* Re-chase sp before searching for closing brace */
sp = JS_VALUE_GET_STRING (text_val);
/* Find closing '}' */
int brace_end = -1;
for (int i = brace_start + 1; i < len; i++) {
if (string_get (sp, i) == '}') {
if (js_string_value_get (text_val, i) == '}') {
brace_end = i;
break;
}
@@ -22660,8 +22637,7 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
if (brace_end < 0) {
/* No closing brace, copy '{' and continue */
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
JSValue ch = js_sub_string (ctx, sp, brace_start, brace_start + 1);
JSValue ch = js_sub_string_val (ctx, text_val, brace_start, brace_start + 1);
if (JS_IsException (ch)) return JS_EXCEPTION;
result = pretext_concat_value (ctx, result, ch);
if (!result) return JS_EXCEPTION;
@@ -22670,17 +22646,15 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
}
/* Extract content between braces */
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
JSValue middle = js_sub_string (ctx, sp, brace_start + 1, brace_end);
JSValue middle = js_sub_string_val (ctx, text_val, brace_start + 1, brace_end);
if (JS_IsException (middle)) return JS_EXCEPTION;
/* Split on ':' to get name and format_spec */
JSText *middle_str = JS_VALUE_GET_STRING (middle);
int middle_len = (int)JSText_len (middle_str);
int middle_len = js_string_value_len (middle);
int colon_pos = -1;
for (int i = 0; i < middle_len; i++) {
if (string_get (middle_str, i) == ':') {
if (js_string_value_get (middle, i) == ':') {
colon_pos = i;
break;
}
@@ -22688,10 +22662,8 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
JSValue name_val, format_spec;
if (colon_pos >= 0) {
middle_str = JS_VALUE_GET_STRING (middle); /* Re-chase before js_sub_string */
name_val = js_sub_string (ctx, middle_str, 0, colon_pos);
middle_str = JS_VALUE_GET_STRING (middle); /* Re-chase before js_sub_string */
format_spec = js_sub_string (ctx, middle_str, colon_pos + 1, middle_len);
name_val = js_sub_string_val (ctx, middle, 0, colon_pos);
format_spec = js_sub_string_val (ctx, middle, colon_pos + 1, middle_len);
} else {
name_val = middle;
format_spec = JS_KEY_empty;
@@ -22763,8 +22735,7 @@ static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc,
if (!result) return JS_EXCEPTION;
} else {
/* No substitution, keep original {name} or {name:format} */
sp = JS_VALUE_GET_STRING (text_val); /* Re-chase before js_sub_string */
JSValue orig = js_sub_string (ctx, sp, brace_start, brace_end + 1);
JSValue orig = js_sub_string_val (ctx, text_val, brace_start, brace_end + 1);
if (JS_IsException (orig)) return JS_EXCEPTION;
result = pretext_concat_value (ctx, result, orig);
if (!result) return JS_EXCEPTION;