[njs] Fixed Error.prototype.toString().
Dmitry Volyntsev
xeioex at nginx.com
Wed Aug 7 18:28:58 UTC 2019
details: https://hg.nginx.org/njs/rev/e47f82b5f2ca
branches:
changeset: 1115:e47f82b5f2ca
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Mon Aug 05 17:10:59 2019 +0300
description:
Fixed Error.prototype.toString().
1) with UTF8 string properties.
1) with non-string values for "name" and "message" properties.
This closes #199 issue on Github.
diffstat:
src/njs_error.c | 50 +++++++++++++++++++++++++++++++++++------------
src/test/njs_unit_test.c | 27 ++++++++++++++++++++++++-
2 files changed, 63 insertions(+), 14 deletions(-)
diffs (137 lines):
diff -r b9d9f2813d9a -r e47f82b5f2ca src/njs_error.c
--- a/src/njs_error.c Tue Aug 06 22:54:13 2019 -0400
+++ b/src/njs_error.c Mon Aug 05 17:10:59 2019 +0300
@@ -617,12 +617,12 @@ njs_error_prototype_to_string(njs_vm_t *
njs_int_t
njs_error_to_string(njs_vm_t *vm, njs_value_t *retval, const njs_value_t *error)
{
- size_t size;
+ size_t length;
u_char *p;
njs_int_t ret;
- njs_str_t name, message;
njs_value_t value1, value2;
- const njs_value_t *name_value, *message_value;
+ njs_value_t *name_value, *message_value;
+ njs_string_prop_t name, message;
njs_lvlhsh_query_t lhq;
static const njs_value_t default_name = njs_string("Error");
@@ -635,9 +635,18 @@ njs_error_to_string(njs_vm_t *vm, njs_va
return ret;
}
- name_value = (ret == NJS_OK) ? &value1 : &default_name;
+ name_value = (ret == NJS_OK) ? &value1 : njs_value_arg(&default_name);
- njs_string_get(name_value, &name);
+ if (njs_slow_path(!njs_is_string(name_value))) {
+ ret = njs_value_to_string(vm, &value1, name_value);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
+ name_value = &value1;
+ }
+
+ (void) njs_string_prop(&name, name_value);
lhq.key_hash = NJS_MESSAGE_HASH;
lhq.key = njs_str_value("message");
@@ -648,29 +657,44 @@ njs_error_to_string(njs_vm_t *vm, njs_va
return ret;
}
- message_value = (ret == NJS_OK) ? &value2 : &njs_string_empty;
+ message_value = (ret == NJS_OK) ? &value2
+ : njs_value_arg(&njs_string_empty);
- njs_string_get(message_value, &message);
+ if (njs_slow_path(!njs_is_string(message_value))) {
+ ret = njs_value_to_string(vm, &value2, message_value);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
- if (name.length == 0) {
+ message_value = &value2;
+ }
+
+ (void) njs_string_prop(&message, message_value);
+
+ if (name.size == 0) {
*retval = *message_value;
return NJS_OK;
}
- if (message.length == 0) {
+ if (message.size == 0) {
*retval = *name_value;
return NJS_OK;
}
- size = name.length + message.length + 2;
+ if (name.length != 0 && message.length != 0) {
+ length = name.length + message.length + 2;
- p = njs_string_alloc(vm, retval, size, size);
+ } else {
+ length = 0;
+ }
+
+ p = njs_string_alloc(vm, retval, name.size + message.size + 2, length);
if (njs_fast_path(p != NULL)) {
- p = njs_cpymem(p, name.start, name.length);
+ p = njs_cpymem(p, name.start, name.size);
*p++ = ':';
*p++ = ' ';
- memcpy(p, message.start, message.length);
+ memcpy(p, message.start, message.size);
return NJS_OK;
}
diff -r b9d9f2813d9a -r e47f82b5f2ca src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Tue Aug 06 22:54:13 2019 -0400
+++ b/src/test/njs_unit_test.c Mon Aug 05 17:10:59 2019 +0300
@@ -7835,7 +7835,25 @@ static njs_unit_test_t njs_test[] =
{ njs_str("Error('e')"),
njs_str("Error: e") },
- { njs_str("var e = Error('e'); e.name = 'E'; e"),
+ { njs_str("Error(123)"),
+ njs_str("Error: 123") },
+
+ { njs_str("Error({toString(){return 'e'}})"),
+ njs_str("Error: e") },
+
+ { njs_str("Error([1,'α'])"),
+ njs_str("Error: 1,α") },
+
+ { njs_str("var e = TypeError(Error('e')); e"),
+ njs_str("TypeError: Error: e") },
+
+ { njs_str("Error('α'.repeat(33)).toString().length"),
+ njs_str("40") },
+
+ { njs_str("var e = Error('e'); e.name = {toString(){return 'E'}}; e"),
+ njs_str("E: e") },
+
+ { njs_str("var e = Error('e'); Object.defineProperty(e, 'name', {get(){return 'E'}}); e"),
njs_str("E: e") },
{ njs_str("var e = Error('e'); e.name = ''; e"),
@@ -7850,6 +7868,13 @@ static njs_unit_test_t njs_test[] =
{ njs_str("Error('e').name + ': ' + Error('e').message"),
njs_str("Error: e") },
+ { njs_str("Error(String.bytesFrom(Array(1).fill(0x9d))).toString().length"),
+ njs_str("8") },
+
+ { njs_str("var e = Error('α'); e.name = String.bytesFrom(Array(1).fill(0x9d)); "
+ "e.toString().length"),
+ njs_str("5") },
+
{ njs_str("Error(1)"),
njs_str("Error: 1") },
More information about the nginx-devel
mailing list