]> git.kaiwu.me - njs.git/commitdiff
Added support for accessor properties in JSON.stringify().
authorDmitry Volyntsev <xeioex@nginx.com>
Thu, 8 Aug 2019 11:19:56 +0000 (14:19 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Thu, 8 Aug 2019 11:19:56 +0000 (14:19 +0300)
This closes #203 issue on Github.

src/njs_json.c
src/test/njs_unit_test.c

index 2092d9534e08ac90cd62ed687682b21c49ba4a7d..5663681683b2216902a1c8c759130546e13de678 100644 (file)
@@ -1214,7 +1214,7 @@ njs_json_stringify_iterator(njs_vm_t *vm, njs_json_stringify_t *stringify)
     njs_value_t         *key, *value;
     njs_function_t      *to_json;
     njs_json_state_t    *state;
-    njs_object_prop_t   *prop;
+    njs_object_prop_t   *prop, scratch;
     njs_lvlhsh_query_t  lhq;
 
 start:
@@ -1255,10 +1255,27 @@ start:
 
             prop = lhq.value;
 
-            if (!prop->enumerable
-                || njs_is_undefined(&prop->value)
-                || !njs_is_valid(&prop->value)
-                || njs_is_function(&prop->value))
+            if (!prop->enumerable) {
+                break;
+            }
+
+            if (njs_is_accessor_descriptor(prop)
+                && njs_is_function(&prop->getter))
+            {
+                scratch = *prop;
+                prop = &scratch;
+
+                ret = njs_function_apply(vm, njs_function(&prop->getter),
+                                         &state->value, 1, &prop->value);
+
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return ret;
+                }
+            }
+
+            if (njs_is_undefined(&prop->value)
+                || njs_is_function(&prop->value)
+                || !njs_is_valid(&prop->value))
             {
                 break;
             }
index 8de40a91d2720beda822e3345c083ea956da50ca..f29a8b0ead15b1c6f08c9db7a1b3558f1922fb79 100644 (file)
@@ -12766,6 +12766,14 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("JSON.stringify([{a:1,b:{c:2}},1], undefined, new Date())"),
       njs_str("[{\"a\":1,\"b\":{\"c\":2}},1]") },
 
+    { njs_str("var o = Object.defineProperty({}, 'a', { get() { return ()=> 1}, enumerable: true });"
+              "JSON.stringify(o)"),
+      njs_str("{}") },
+
+    { njs_str("var o = Object.defineProperty({}, 'a', { get: () => ({b:1, c:2}), enumerable: true });"
+              "JSON.stringify(o)"),
+      njs_str("{\"a\":{\"b\":1,\"c\":2}}") },
+
     { njs_str("JSON.stringify({toJSON:function(k){}})"),
       njs_str("undefined") },