[njs] Improved String.prototype.concat() with scalar values.
noreply at nginx.com
noreply at nginx.com
Wed Jul 9 19:18:02 UTC 2025
details: https://github.com/nginx/njs/commit/82d76e7a28104f24235ba93c7d277ff724d3feae
branches: master
commit: 82d76e7a28104f24235ba93c7d277ff724d3feae
user: Vadim Zhestikov <v.zhestikov at f5.com>
date: Thu, 3 Jul 2025 14:14:43 -0700
description:
Improved String.prototype.concat() with scalar values.
---
src/njs_string.c | 64 ++++++++++++++++++++++++++++++++++++++----------
src/test/njs_unit_test.c | 24 ++++++++++++++++++
2 files changed, 75 insertions(+), 13 deletions(-)
diff --git a/src/njs_string.c b/src/njs_string.c
index d3991451..1a2b2333 100644
--- a/src/njs_string.c
+++ b/src/njs_string.c
@@ -608,7 +608,9 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_int_t ret;
njs_uint_t i;
njs_string_prop_t string;
- char buf[512], tmp[NJS_DTOA_MAX_LEN];
+ char buf[512];
+
+#define NJS_SZ_LAST 64
if (njs_is_null_or_undefined(&args[0])) {
njs_type_error(vm, "\"this\" argument is null or undefined");
@@ -620,6 +622,7 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
np = buf;
np_end = buf + sizeof(buf);
+ *np = 0;
for (i = 0; i < nargs; i++) {
if (njs_is_number(&args[i])) {
@@ -640,20 +643,42 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
}
} else {
- if (njs_fast_path(np < np_end - NJS_DTOA_MAX_LEN)) {
- sz = njs_dtoa(num, np + sizeof(uint8_t));
-
- *np = (uint8_t) sz;
- np += sizeof(uint8_t) + sz;
-
- } else {
- sz = njs_dtoa(num, tmp);
+ sz = njs_dtoa(num, np + sizeof(uint8_t));
+
+ if (*np == 0) {
+ if (np + sizeof(uint8_t) + sz
+ < np_end - NJS_DTOA_MAX_LEN - sizeof(uint8_t))
+ {
+ *np = (uint8_t) sz;
+ np += sizeof(uint8_t) + sz;
+ *np = 0;
+
+ } else {
+ *np = NJS_SZ_LAST;
+ }
}
size += sz;
length += sz;
}
+ } else if (njs_is_boolean(&args[i])) {
+ if (njs_is_true(&args[i])) {
+ size += njs_length("true");
+ length += njs_length("true");
+ } else {
+ size += njs_length("false");
+ length += njs_length("false");
+ }
+
+ } else if (njs_is_null(&args[i])) {
+ size += njs_length("null");
+ length += njs_length("null");
+
+ } else if (njs_is_undefined(&args[i])) {
+ size += njs_length("undefined");
+ length += njs_length("undefined");
+
} else {
if (!njs_is_string(&args[i])) {
ret = njs_value_to_string(vm, &args[i], &args[i]);
@@ -693,10 +718,10 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
}
} else {
- if (njs_fast_path(np < np_end - NJS_DTOA_MAX_LEN)) {
- length = *np++;
- p = njs_cpymem(p, np, length);
- np += length;
+ if (*np != NJS_SZ_LAST) {
+ sz = *np++;
+ p = njs_cpymem(p, np, sz);
+ np += sz;
} else {
sz = njs_dtoa(num, (char *) p);
@@ -704,6 +729,19 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
}
}
+ } else if (njs_is_boolean(&args[i])) {
+ if (njs_is_true(&args[i])) {
+ p = njs_cpymem(p, "true", njs_length("true"));
+ } else {
+ p = njs_cpymem(p, "false", njs_length("false"));
+ }
+
+ } else if (njs_is_null(&args[i])) {
+ p = njs_cpymem(p, "null", njs_length("null"));
+
+ } else if (njs_is_undefined(&args[i])) {
+ p = njs_cpymem(p, "undefined", njs_length("undefined"));
+
} else {
njs_string_prop(vm, &string, &args[i]);
diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c
index 541e3327..fd98dbb5 100644
--- a/src/test/njs_unit_test.c
+++ b/src/test/njs_unit_test.c
@@ -11003,6 +11003,30 @@ static njs_unit_test_t njs_test[] =
"f.apply(123, {})"),
njs_str("123") },
+ { njs_str("'Hello'.concat(' ', 'World')"),
+ njs_str("Hello World") },
+
+ { njs_str("'Value: '.concat(42, ' and ', 3.14)"),
+ njs_str("Value: 42 and 3.14") },
+
+ { njs_str("'Flags: '.concat(true, ' and ', false)"),
+ njs_str("Flags: true and false") },
+
+ { njs_str("'Values: '.concat(null, ' and ', undefined)"),
+ njs_str("Values: null and undefined") },
+
+ { njs_str("'Mixed: '.concat(123, ' ', true, ' ', null, ' ', undefined)"),
+ njs_str("Mixed: 123 true null undefined") },
+
+ { njs_str("'Special: '.concat(NaN, ' ', Infinity, ' ', -Infinity)"),
+ njs_str("Special: NaN Infinity -Infinity") },
+
+ { njs_str("'Numbers: '.concat(1234567890, ' ', 0.123456789, ' ', 1.23e-10)"),
+ njs_str("Numbers: 1234567890 0.123456789 1.23e-10") },
+
+ { njs_str("'Zero: '.concat(0, ' ', -0)"),
+ njs_str("Zero: 0 0") },
+
{ njs_str("(function(index, ...rest){ return rest[index];})"
".apply({}, [1022].concat(Array(1023).fill(1).map((v,i)=>i.toString(16))))"),
njs_str("3fe") },
More information about the nginx-devel
mailing list