Skip to content

Instantly share code, notes, and snippets.

@xeioex
Created November 20, 2019 17:25
Show Gist options
  • Save xeioex/dd31240f02ed6c8edb1707c8f11aaf08 to your computer and use it in GitHub Desktop.
Save xeioex/dd31240f02ed6c8edb1707c8f11aaf08 to your computer and use it in GitHub Desktop.
# HG changeset patch
# User Dmitry Volyntsev <xeioex@nginx.com>
# Date 1574270656 -10800
# Wed Nov 20 20:24:16 2019 +0300
# Node ID e998f1e895651fbbd0ae6fc880ca39c44d1aeeea
# Parent 20b3189456f57a74aba14dc664d2393bd05a1e64
[mq]: improve_symbol.patch
diff --git a/src/njs_symbol.c b/src/njs_symbol.c
--- a/src/njs_symbol.c
+++ b/src/njs_symbol.c
@@ -36,7 +36,7 @@ static const njs_value_t njs_symbol_uns
njs_long_string("Symbol.unscopables");
-static const njs_value_t *njs_symbol_names[NJS_SYMBOL_LAST + 1] = {
+static const njs_value_t *njs_symbol_names[NJS_SYMBOL_KNOWN_MAX] = {
&njs_string_invalid,
&njs_symbol_async_iterator_name,
&njs_symbol_has_instance_name,
@@ -66,7 +66,7 @@ njs_symbol_to_string(njs_vm_t *vm, njs_v
name = value->data.u.value;
if (name == NULL) {
- if (njs_fast_path(njs_symbol_key(value) <= NJS_SYMBOL_LAST)) {
+ if (njs_fast_path(njs_symbol_key(value) < NJS_SYMBOL_KNOWN_MAX)) {
name = njs_symbol_names[njs_symbol_key(value)];
@@ -129,9 +129,13 @@ njs_symbol_constructor(njs_vm_t *vm, njs
*name = *value;
}
- /* TODO: fail on overflow */
key = ++vm->symbol_generator;
+ if (njs_slow_path(key >= UINT32_MAX)) {
+ njs_internal_error(vm, "Symbol generator overflow");
+ return NJS_ERROR;
+ }
+
vm->retval.type = NJS_SYMBOL;
vm->retval.data.truth = 1;
vm->retval.data.magic32 = key;
@@ -363,7 +367,7 @@ njs_symbol_prototype_description(njs_vm_
name = value->data.u.value;
if (name == NULL) {
- if (njs_fast_path(njs_symbol_key(value) <= NJS_SYMBOL_LAST)) {
+ if (njs_fast_path(njs_symbol_key(value) < NJS_SYMBOL_KNOWN_MAX)) {
name = njs_symbol_names[njs_symbol_key(value)];
} else {
@@ -411,7 +415,6 @@ static const njs_object_prop_t njs_symb
.configurable = 1,
},
- /* Symbol.prototype.description */
{
.type = NJS_PROPERTY,
.name = njs_string("description"),
diff --git a/src/njs_symbol.h b/src/njs_symbol.h
--- a/src/njs_symbol.h
+++ b/src/njs_symbol.h
@@ -22,13 +22,10 @@ typedef enum {
NJS_SYMBOL_TO_PRIMITIVE = 11,
NJS_SYMBOL_TO_STRING_TAG = 12,
NJS_SYMBOL_UNSCOPABLES = 13,
-#define NJS_SYMBOL_LAST NJS_SYMBOL_UNSCOPABLES
+#define NJS_SYMBOL_KNOWN_MAX (NJS_SYMBOL_UNSCOPABLES + 1)
} njs_wellknown_symbol_t;
-#define NJS_SYMBOL_KNOWN_MAX 1024;
-
-
njs_int_t njs_symbol_to_string(njs_vm_t *vm, njs_value_t *dst,
const njs_value_t *value);
diff --git a/src/njs_value.h b/src/njs_value.h
--- a/src/njs_value.h
+++ b/src/njs_value.h
@@ -370,7 +370,7 @@ typedef struct {
}
-#define njs_wellknown_symbol(key) { \
+#define njs_wellknown_symbol(key) { \
.data = { \
.type = NJS_SYMBOL, \
.truth = 1, \
@@ -683,7 +683,7 @@ typedef struct {
#define njs_symbol_eq(value1, value2) \
- (value1)->data.magic32 == (value2)->data.magic32
+ (njs_symbol_key(value1) == njs_symbol_key(value2))
extern const njs_value_t njs_value_null;
diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c
--- a/src/njs_vmcode.c
+++ b/src/njs_vmcode.c
@@ -261,7 +261,9 @@ next:
value2 = &primitive2;
}
- if (njs_slow_path(njs_is_symbol(value1) || njs_is_symbol(value2))) {
+ if (njs_slow_path(njs_is_symbol(value1)
+ || njs_is_symbol(value2)))
+ {
njs_symbol_conversion_failed(vm,
(op == NJS_VMCODE_ADDITION) &&
(njs_is_string(value1) || njs_is_string(value2)));
diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c
+++ b/src/test/njs_unit_test.c
@@ -10178,6 +10178,9 @@ static njs_unit_test_t njs_test[] =
{ njs_str("Symbol('desc').toString()"),
njs_str("Symbol(desc)") },
+ { njs_str("Symbol('α'.repeat(16)).toString()"),
+ njs_str("Symbol(αααααααααααααααα)") },
+
{ njs_str("Symbol(undefined).toString()"),
njs_str("Symbol()") },
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment