Skip to content

Commit

Permalink
Fix exception in WeakRef.prototype.deref (#653)
Browse files Browse the repository at this point in the history
Set the object's opaque to a sentinel value instead of NULL, to stop
JS_GetOpaque2 from raising an "illegal class" exception.

Fixes: #651
  • Loading branch information
bnoordhuis authored Nov 6, 2024
1 parent 0a70623 commit 83fe8f1
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 2 deletions.
8 changes: 6 additions & 2 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -54737,10 +54737,12 @@ typedef struct JSWeakRefData {
JSValue obj;
} JSWeakRefData;

static JSWeakRefData js_weakref_sentinel;

static void js_weakref_finalizer(JSRuntime *rt, JSValue val)
{
JSWeakRefData *wrd = JS_GetOpaque(val, JS_CLASS_WEAK_REF);
if (!wrd)
if (!wrd || wrd == &js_weakref_sentinel)
return;

/* Delete weak ref */
Expand Down Expand Up @@ -54796,6 +54798,8 @@ static JSValue js_weakref_deref(JSContext *ctx, JSValue this_val, int argc, JSVa
JSWeakRefData *wrd = JS_GetOpaque2(ctx, this_val, JS_CLASS_WEAK_REF);
if (!wrd)
return JS_EXCEPTION;
if (wrd == &js_weakref_sentinel)
return JS_UNDEFINED;
return js_dup(wrd->target);
}

Expand Down Expand Up @@ -55055,7 +55059,7 @@ static void reset_weak_ref(JSRuntime *rt, JSWeakRefRecord **first_weak_ref)
break;
case JS_WEAK_REF_KIND_WEAK_REF:
wrd = wr->u.weak_ref_data;
JS_SetOpaque(wrd->obj, NULL);
JS_SetOpaque(wrd->obj, &js_weakref_sentinel);
js_free_rt(rt, wrd);
break;
case JS_WEAK_REF_KIND_FINALIZATION_REGISTRY_ENTRY: {
Expand Down
4 changes: 4 additions & 0 deletions tests/bug652.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { assert } from "./assert.js"
const ref = new WeakRef({})
const val = ref.deref() // should not throw
assert(val, undefined)

0 comments on commit 83fe8f1

Please sign in to comment.