[quickjs-devel] Re: [PATCH] [BUG] Proxy Test Not All References Freed

  • From: Connor Nolan <connor24nolan@xxxxxxxx>
  • To: "quickjs-devel@xxxxxxxxxxxxx" <quickjs-devel@xxxxxxxxxxxxx>
  • Date: Wed, 14 Aug 2019 16:40:11 +0000

Fixed it!

diff -u a/quickjs.c d/quickjs.c
--- a/quickjs.c 2019-08-10 06:58:42.000000000 -0400
+++ d/quickjs.c 2019-08-14 12:39:07.398500000 -0400
@@ -42320,12 +42320,16 @@
     JSValueConst args[3];

     s = get_proxy_method(ctx, &method, func_obj, JS_ATOM_apply);
-    if (!s)
+    if (!s) {
         return JS_EXCEPTION;
-    if (!s->is_func)
+    }
+    if (!s->is_func) {
+        JS_FreeValue(ctx, method);
         return JS_ThrowTypeError(ctx, "not a function");
-    if (JS_IsUndefined(method))
+    }
+    if (JS_IsUndefined(method)) {
         return JS_Call(ctx, s->target, this_obj, argc, argv);
+    }
     arg_array = js_create_array(ctx, argc, argv);
     if (JS_IsException(arg_array)) {
         ret = JS_EXCEPTION;

________________________________
From: quickjs-devel-bounce@xxxxxxxxxxxxx <quickjs-devel-bounce@xxxxxxxxxxxxx> 
on behalf of Ondřej Jirman <megi@xxxxxx>
Sent: Tuesday, August 13, 2019 4:27 PM
To: quickjs-devel@xxxxxxxxxxxxx <quickjs-devel@xxxxxxxxxxxxx>
Subject: [quickjs-devel] Re: [PATCH] [BUG] Proxy Test Not All References Freed

Hi,

On Tue, Aug 13, 2019 at 11:13:47PM +0000, Connor Nolan wrote:

diff -u a/quickjs.c d/quickjs.c
--- a/quickjs.c 2019-08-10 06:58:42.000000000 -0400
+++ d/quickjs.c 2019-08-13 19:11:33.126917000 -0400
@@ -42320,12 +42320,18 @@
     JSValueConst args[3];

     s = get_proxy_method(ctx, &method, func_obj, JS_ATOM_apply);
-    if (!s)
-        return JS_EXCEPTION;
-    if (!s->is_func)
-        return JS_ThrowTypeError(ctx, "not a function");
-    if (JS_IsUndefined(method))
-        return JS_Call(ctx, s->target, this_obj, argc, argv);
+    if (!s) {
+        ret = JS_EXCEPTION;
+        goto early_fail;
+    }
+    if (!s->is_func) {
+        ret = JS_ThrowTypeError(ctx, "not a function");
+        goto early_fail;

I think the extra free is necessary only for the !s->is_func branch.
The rest does nothing.

        o.

+    }
+    if (JS_IsUndefined(method)) {
+        ret = JS_Call(ctx, s->target, this_obj, argc, argv);
+        goto early_fail;
+    }
     arg_array = js_create_array(ctx, argc, argv);
     if (JS_IsException(arg_array)) {
         ret = JS_EXCEPTION;
@@ -42336,8 +42342,9 @@
     args[2] = arg_array;
     ret = JS_Call(ctx, method, s->handler, 3, args);
  fail:
-    JS_FreeValue(ctx, method);
     JS_FreeValue(ctx, arg_array);
+ early_fail:
+    JS_FreeValue(ctx, method);
     return ret;
 }

________________________________
From: quickjs-devel-bounce@xxxxxxxxxxxxx <quickjs-devel-bounce@xxxxxxxxxxxxx> 
on behalf of Connor Nolan <connor24nolan@xxxxxxxx>
Sent: Saturday, August 10, 2019 8:21 PM
To: quickjs-devel@xxxxxxxxxxxxx <quickjs-devel@xxxxxxxxxxxxx>
Subject: [quickjs-devel] Re: Proxy Test Not All References Freed

You can test this with:

function test() {
    var passed = false;
    new Proxy(function(){}, {
        apply: function () { passed = true; }
    })();
    // A Proxy exotic object only has a [[Call]] internal method if the
    // initial value of its [[ProxyTarget]] internal slot is an object
    // that has a [[Call]] internal method.
    try {
        new Proxy({}, {
            apply: function () {}
        })();
        return false;
    } catch(e) {}
    return passed;
}
console.log("Result: " + test());

________________________________
From: quickjs-devel-bounce@xxxxxxxxxxxxx <quickjs-devel-bounce@xxxxxxxxxxxxx> 
on behalf of Connor Nolan <connor24nolan@xxxxxxxx>
Sent: Saturday, August 10, 2019 8:12 PM
To: quickjs-devel@xxxxxxxxxxxxx <quickjs-devel@xxxxxxxxxxxxx>
Subject: [quickjs-devel] Proxy Test Not All References Freed

Hen running https://github.com/kangax/compat-table.git ES6 test suite, the ;
test "data-es6 -> Proxy -> "apply" handler invariant" crashed QuickJS with 
the error: "qjsbn: quickjs.c:1631: JS_FreeRuntime: Assertion 
`list_empty(&rt->obj_list)' failed.".


Other related posts: