@@ -41109,26 +41109,6 @@ static BOOL test_final_sigma(JSString *p, int sigma_pos)
41109
41109
return !lre_is_cased(c1);
41110
41110
}
41111
41111
41112
- static JSValue js_string_localeCompare(JSContext *ctx, JSValueConst this_val,
41113
- int argc, JSValueConst *argv)
41114
- {
41115
- JSValue a, b;
41116
- int cmp;
41117
-
41118
- a = JS_ToStringCheckObject(ctx, this_val);
41119
- if (JS_IsException(a))
41120
- return JS_EXCEPTION;
41121
- b = JS_ToString(ctx, argv[0]);
41122
- if (JS_IsException(b)) {
41123
- JS_FreeValue(ctx, a);
41124
- return JS_EXCEPTION;
41125
- }
41126
- cmp = js_string_compare(ctx, JS_VALUE_GET_STRING(a), JS_VALUE_GET_STRING(b));
41127
- JS_FreeValue(ctx, a);
41128
- JS_FreeValue(ctx, b);
41129
- return JS_NewInt32(ctx, cmp);
41130
- }
41131
-
41132
41112
static JSValue js_string_toLowerCase(JSContext *ctx, JSValueConst this_val,
41133
41113
int argc, JSValueConst *argv, int to_lower)
41134
41114
{
@@ -41214,23 +41194,38 @@ static JSValue JS_NewUTF32String(JSContext *ctx, const uint32_t *buf, int len)
41214
41194
return JS_EXCEPTION;
41215
41195
}
41216
41196
41197
+ static int js_string_normalize1(JSContext *ctx, uint32_t **pout_buf,
41198
+ JSValueConst val,
41199
+ UnicodeNormalizationEnum n_type)
41200
+ {
41201
+ int buf_len, out_len;
41202
+ uint32_t *buf, *out_buf;
41203
+
41204
+ buf_len = JS_ToUTF32String(ctx, &buf, val);
41205
+ if (buf_len < 0)
41206
+ return -1;
41207
+ out_len = unicode_normalize(&out_buf, buf, buf_len, n_type,
41208
+ ctx->rt, (DynBufReallocFunc *)js_realloc_rt);
41209
+ js_free(ctx, buf);
41210
+ if (out_len < 0)
41211
+ return -1;
41212
+ *pout_buf = out_buf;
41213
+ return out_len;
41214
+ }
41215
+
41217
41216
static JSValue js_string_normalize(JSContext *ctx, JSValueConst this_val,
41218
41217
int argc, JSValueConst *argv)
41219
41218
{
41220
41219
const char *form, *p;
41221
41220
size_t form_len;
41222
- int is_compat, buf_len, out_len;
41221
+ int is_compat, out_len;
41223
41222
UnicodeNormalizationEnum n_type;
41224
41223
JSValue val;
41225
- uint32_t *buf, * out_buf;
41224
+ uint32_t *out_buf;
41226
41225
41227
41226
val = JS_ToStringCheckObject(ctx, this_val);
41228
41227
if (JS_IsException(val))
41229
41228
return val;
41230
- buf_len = JS_ToUTF32String(ctx, &buf, val);
41231
- JS_FreeValue(ctx, val);
41232
- if (buf_len < 0)
41233
- return JS_EXCEPTION;
41234
41229
41235
41230
if (argc == 0 || JS_IsUndefined(argv[0])) {
41236
41231
n_type = UNICODE_NFC;
@@ -41256,22 +41251,96 @@ static JSValue js_string_normalize(JSContext *ctx, JSValueConst this_val,
41256
41251
JS_FreeCString(ctx, form);
41257
41252
JS_ThrowRangeError(ctx, "bad normalization form");
41258
41253
fail1:
41259
- js_free (ctx, buf );
41254
+ JS_FreeValue (ctx, val );
41260
41255
return JS_EXCEPTION;
41261
41256
}
41262
41257
JS_FreeCString(ctx, form);
41263
41258
}
41264
41259
41265
- out_len = unicode_normalize(&out_buf, buf, buf_len, n_type,
41266
- ctx->rt, (DynBufReallocFunc *)js_realloc_rt);
41267
- js_free(ctx, buf);
41260
+ out_len = js_string_normalize1(ctx, &out_buf, val, n_type);
41261
+ JS_FreeValue(ctx, val);
41268
41262
if (out_len < 0)
41269
41263
return JS_EXCEPTION;
41270
41264
val = JS_NewUTF32String(ctx, out_buf, out_len);
41271
41265
js_free(ctx, out_buf);
41272
41266
return val;
41273
41267
}
41274
- #endif /* CONFIG_ALL_UNICODE */
41268
+
41269
+ /* return < 0, 0 or > 0 */
41270
+ static int js_UTF32_compare(const uint32_t *buf1, int buf1_len,
41271
+ const uint32_t *buf2, int buf2_len)
41272
+ {
41273
+ int i, len, c, res;
41274
+ len = min_int(buf1_len, buf2_len);
41275
+ for(i = 0; i < len; i++) {
41276
+ /* Note: range is limited so a subtraction is valid */
41277
+ c = buf1[i] - buf2[i];
41278
+ if (c != 0)
41279
+ return c;
41280
+ }
41281
+ if (buf1_len == buf2_len)
41282
+ res = 0;
41283
+ else if (buf1_len < buf2_len)
41284
+ res = -1;
41285
+ else
41286
+ res = 1;
41287
+ return res;
41288
+ }
41289
+
41290
+ static JSValue js_string_localeCompare(JSContext *ctx, JSValueConst this_val,
41291
+ int argc, JSValueConst *argv)
41292
+ {
41293
+ JSValue a, b;
41294
+ int cmp, a_len, b_len;
41295
+ uint32_t *a_buf, *b_buf;
41296
+
41297
+ a = JS_ToStringCheckObject(ctx, this_val);
41298
+ if (JS_IsException(a))
41299
+ return JS_EXCEPTION;
41300
+ b = JS_ToString(ctx, argv[0]);
41301
+ if (JS_IsException(b)) {
41302
+ JS_FreeValue(ctx, a);
41303
+ return JS_EXCEPTION;
41304
+ }
41305
+ a_len = js_string_normalize1(ctx, &a_buf, a, UNICODE_NFC);
41306
+ JS_FreeValue(ctx, a);
41307
+ if (a_len < 0) {
41308
+ JS_FreeValue(ctx, b);
41309
+ return JS_EXCEPTION;
41310
+ }
41311
+
41312
+ b_len = js_string_normalize1(ctx, &b_buf, b, UNICODE_NFC);
41313
+ JS_FreeValue(ctx, b);
41314
+ if (b_len < 0) {
41315
+ js_free(ctx, a_buf);
41316
+ return JS_EXCEPTION;
41317
+ }
41318
+ cmp = js_UTF32_compare(a_buf, a_len, b_buf, b_len);
41319
+ js_free(ctx, a_buf);
41320
+ js_free(ctx, b_buf);
41321
+ return JS_NewInt32(ctx, cmp);
41322
+ }
41323
+ #else /* CONFIG_ALL_UNICODE */
41324
+ static JSValue js_string_localeCompare(JSContext *ctx, JSValueConst this_val,
41325
+ int argc, JSValueConst *argv)
41326
+ {
41327
+ JSValue a, b;
41328
+ int cmp;
41329
+
41330
+ a = JS_ToStringCheckObject(ctx, this_val);
41331
+ if (JS_IsException(a))
41332
+ return JS_EXCEPTION;
41333
+ b = JS_ToString(ctx, argv[0]);
41334
+ if (JS_IsException(b)) {
41335
+ JS_FreeValue(ctx, a);
41336
+ return JS_EXCEPTION;
41337
+ }
41338
+ cmp = js_string_compare(ctx, JS_VALUE_GET_STRING(a), JS_VALUE_GET_STRING(b));
41339
+ JS_FreeValue(ctx, a);
41340
+ JS_FreeValue(ctx, b);
41341
+ return JS_NewInt32(ctx, cmp);
41342
+ }
41343
+ #endif /* !CONFIG_ALL_UNICODE */
41275
41344
41276
41345
/* also used for String.prototype.valueOf */
41277
41346
static JSValue js_string_toString(JSContext *ctx, JSValueConst this_val,
0 commit comments