mirror of
https://github.com/DoneJS-Runtime/quickjs-done-nextgen.git
synced 2025-01-09 17:43:15 +00:00
Prevent JS_SetOpaque from overriding internal class state
Fixes: https://github.com/quickjs-ng/quickjs/issues/657
This commit is contained in:
parent
e30da0e8bc
commit
c8be383367
2 changed files with 38 additions and 20 deletions
56
quickjs.c
56
quickjs.c
|
@ -1302,6 +1302,8 @@ static void js_new_callsite_data(JSContext *ctx, JSCallSiteData *csd, JSStackFra
|
||||||
static void js_new_callsite_data2(JSContext *ctx, JSCallSiteData *csd, const char *filename, int line_num, int col_num);
|
static void js_new_callsite_data2(JSContext *ctx, JSCallSiteData *csd, const char *filename, int line_num, int col_num);
|
||||||
static void _JS_AddIntrinsicCallSite(JSContext *ctx);
|
static void _JS_AddIntrinsicCallSite(JSContext *ctx);
|
||||||
|
|
||||||
|
static void JS_SetOpaqueInternal(JSValue obj, void *opaque);
|
||||||
|
|
||||||
static const JSClassExoticMethods js_arguments_exotic_methods;
|
static const JSClassExoticMethods js_arguments_exotic_methods;
|
||||||
static const JSClassExoticMethods js_string_exotic_methods;
|
static const JSClassExoticMethods js_string_exotic_methods;
|
||||||
static const JSClassExoticMethods js_proxy_exotic_methods;
|
static const JSClassExoticMethods js_proxy_exotic_methods;
|
||||||
|
@ -5226,7 +5228,7 @@ JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func,
|
||||||
s->magic = magic;
|
s->magic = magic;
|
||||||
for(i = 0; i < data_len; i++)
|
for(i = 0; i < data_len; i++)
|
||||||
s->data[i] = js_dup(data[i]);
|
s->data[i] = js_dup(data[i]);
|
||||||
JS_SetOpaque(func_obj, s);
|
JS_SetOpaqueInternal(func_obj, s);
|
||||||
js_function_set_properties(ctx, func_obj,
|
js_function_set_properties(ctx, func_obj,
|
||||||
JS_ATOM_empty_string, length);
|
JS_ATOM_empty_string, length);
|
||||||
return func_obj;
|
return func_obj;
|
||||||
|
@ -10072,13 +10074,29 @@ void JS_ResetUncatchableError(JSContext *ctx)
|
||||||
JS_SetUncatchableError(ctx, ctx->rt->current_exception, FALSE);
|
JS_SetUncatchableError(ctx, ctx->rt->current_exception, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JS_SetOpaque(JSValue obj, void *opaque)
|
JS_BOOL JS_SetOpaque(JSValue obj, void *opaque)
|
||||||
{
|
{
|
||||||
JSObject *p;
|
JSObject *p;
|
||||||
if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) {
|
if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) {
|
||||||
p = JS_VALUE_GET_OBJ(obj);
|
p = JS_VALUE_GET_OBJ(obj);
|
||||||
p->u.opaque = opaque;
|
// User code can't set the opaque of internal objects.
|
||||||
|
if (p->class_id >= JS_CLASS_INIT_COUNT) {
|
||||||
|
p->u.opaque = opaque;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* |obj| must be a JSObject of an internal class. */
|
||||||
|
static void JS_SetOpaqueInternal(JSValue obj, void *opaque)
|
||||||
|
{
|
||||||
|
JSObject *p;
|
||||||
|
assert(JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT);
|
||||||
|
p = JS_VALUE_GET_OBJ(obj);
|
||||||
|
assert(p->class_id < JS_CLASS_INIT_COUNT);
|
||||||
|
p->u.opaque = opaque;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return NULL if not an object of class class_id */
|
/* return NULL if not an object of class class_id */
|
||||||
|
@ -17807,7 +17825,7 @@ static JSValue js_generator_function_call(JSContext *ctx, JSValue func_obj,
|
||||||
obj = js_create_from_ctor(ctx, func_obj, JS_CLASS_GENERATOR);
|
obj = js_create_from_ctor(ctx, func_obj, JS_CLASS_GENERATOR);
|
||||||
if (JS_IsException(obj))
|
if (JS_IsException(obj))
|
||||||
goto fail;
|
goto fail;
|
||||||
JS_SetOpaque(obj, s);
|
JS_SetOpaqueInternal(obj, s);
|
||||||
return obj;
|
return obj;
|
||||||
fail:
|
fail:
|
||||||
free_generator_stack_rt(ctx->rt, s);
|
free_generator_stack_rt(ctx->rt, s);
|
||||||
|
@ -18438,7 +18456,7 @@ static JSValue js_async_generator_function_call(JSContext *ctx, JSValue func_obj
|
||||||
if (JS_IsException(obj))
|
if (JS_IsException(obj))
|
||||||
goto fail;
|
goto fail;
|
||||||
s->generator = JS_VALUE_GET_OBJ(obj);
|
s->generator = JS_VALUE_GET_OBJ(obj);
|
||||||
JS_SetOpaque(obj, s);
|
JS_SetOpaqueInternal(obj, s);
|
||||||
return obj;
|
return obj;
|
||||||
fail:
|
fail:
|
||||||
js_async_generator_free(ctx->rt, s);
|
js_async_generator_free(ctx->rt, s);
|
||||||
|
@ -39862,7 +39880,7 @@ static JSValue js_create_array_iterator(JSContext *ctx, JSValue this_val,
|
||||||
it->obj = arr;
|
it->obj = arr;
|
||||||
it->kind = kind;
|
it->kind = kind;
|
||||||
it->idx = 0;
|
it->idx = 0;
|
||||||
JS_SetOpaque(enum_obj, it);
|
JS_SetOpaqueInternal(enum_obj, it);
|
||||||
return enum_obj;
|
return enum_obj;
|
||||||
fail1:
|
fail1:
|
||||||
JS_FreeValue(ctx, enum_obj);
|
JS_FreeValue(ctx, enum_obj);
|
||||||
|
@ -43862,7 +43880,7 @@ static JSValue js_regexp_Symbol_matchAll(JSContext *ctx, JSValue this_val,
|
||||||
it->global = string_indexof_char(strp, 'g', 0) >= 0;
|
it->global = string_indexof_char(strp, 'g', 0) >= 0;
|
||||||
it->unicode = string_indexof_char(strp, 'u', 0) >= 0;
|
it->unicode = string_indexof_char(strp, 'u', 0) >= 0;
|
||||||
it->done = FALSE;
|
it->done = FALSE;
|
||||||
JS_SetOpaque(iter, it);
|
JS_SetOpaqueInternal(iter, it);
|
||||||
|
|
||||||
JS_FreeValue(ctx, C);
|
JS_FreeValue(ctx, C);
|
||||||
JS_FreeValue(ctx, flags);
|
JS_FreeValue(ctx, flags);
|
||||||
|
@ -46112,7 +46130,7 @@ static JSValue js_proxy_constructor(JSContext *ctx, JSValue this_val,
|
||||||
s->handler = js_dup(handler);
|
s->handler = js_dup(handler);
|
||||||
s->is_func = JS_IsFunction(ctx, target);
|
s->is_func = JS_IsFunction(ctx, target);
|
||||||
s->is_revoked = FALSE;
|
s->is_revoked = FALSE;
|
||||||
JS_SetOpaque(obj, s);
|
JS_SetOpaqueInternal(obj, s);
|
||||||
JS_SetConstructorBit(ctx, obj, JS_IsConstructor(ctx, target));
|
JS_SetConstructorBit(ctx, obj, JS_IsConstructor(ctx, target));
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -46345,7 +46363,7 @@ static JSValue js_map_constructor(JSContext *ctx, JSValue new_target,
|
||||||
goto fail;
|
goto fail;
|
||||||
init_list_head(&s->records);
|
init_list_head(&s->records);
|
||||||
s->is_weak = is_weak;
|
s->is_weak = is_weak;
|
||||||
JS_SetOpaque(obj, s);
|
JS_SetOpaqueInternal(obj, s);
|
||||||
s->hash_size = 1;
|
s->hash_size = 1;
|
||||||
s->hash_table = js_malloc(ctx, sizeof(s->hash_table[0]) * s->hash_size);
|
s->hash_table = js_malloc(ctx, sizeof(s->hash_table[0]) * s->hash_size);
|
||||||
if (!s->hash_table)
|
if (!s->hash_table)
|
||||||
|
@ -46993,7 +47011,7 @@ static JSValue js_create_map_iterator(JSContext *ctx, JSValue this_val,
|
||||||
it->obj = js_dup(this_val);
|
it->obj = js_dup(this_val);
|
||||||
it->kind = kind;
|
it->kind = kind;
|
||||||
it->cur_record = NULL;
|
it->cur_record = NULL;
|
||||||
JS_SetOpaque(enum_obj, it);
|
JS_SetOpaqueInternal(enum_obj, it);
|
||||||
return enum_obj;
|
return enum_obj;
|
||||||
fail:
|
fail:
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
|
@ -48091,7 +48109,7 @@ static int js_create_resolving_functions(JSContext *ctx,
|
||||||
sr->ref_count++;
|
sr->ref_count++;
|
||||||
s->presolved = sr;
|
s->presolved = sr;
|
||||||
s->promise = js_dup(promise);
|
s->promise = js_dup(promise);
|
||||||
JS_SetOpaque(obj, s);
|
JS_SetOpaqueInternal(obj, s);
|
||||||
js_function_set_properties(ctx, obj, JS_ATOM_empty_string, 1);
|
js_function_set_properties(ctx, obj, JS_ATOM_empty_string, 1);
|
||||||
resolving_funcs[i] = obj;
|
resolving_funcs[i] = obj;
|
||||||
}
|
}
|
||||||
|
@ -48236,7 +48254,7 @@ static JSValue js_promise_constructor(JSContext *ctx, JSValue new_target,
|
||||||
for(i = 0; i < 2; i++)
|
for(i = 0; i < 2; i++)
|
||||||
init_list_head(&s->promise_reactions[i]);
|
init_list_head(&s->promise_reactions[i]);
|
||||||
s->promise_result = JS_UNDEFINED;
|
s->promise_result = JS_UNDEFINED;
|
||||||
JS_SetOpaque(obj, s);
|
JS_SetOpaqueInternal(obj, s);
|
||||||
if (js_create_resolving_functions(ctx, args, obj))
|
if (js_create_resolving_functions(ctx, args, obj))
|
||||||
goto fail;
|
goto fail;
|
||||||
ret = JS_Call(ctx, executor, JS_UNDEFINED, 2, args);
|
ret = JS_Call(ctx, executor, JS_UNDEFINED, 2, args);
|
||||||
|
@ -48991,7 +49009,7 @@ static JSValue JS_CreateAsyncFromSyncIterator(JSContext *ctx,
|
||||||
}
|
}
|
||||||
s->sync_iter = js_dup(sync_iter);
|
s->sync_iter = js_dup(sync_iter);
|
||||||
s->next_method = next_method;
|
s->next_method = next_method;
|
||||||
JS_SetOpaque(async_iter, s);
|
JS_SetOpaqueInternal(async_iter, s);
|
||||||
return async_iter;
|
return async_iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51202,7 +51220,7 @@ static JSValue js_array_buffer_constructor3(JSContext *ctx,
|
||||||
abuf->free_func = free_func;
|
abuf->free_func = free_func;
|
||||||
if (alloc_flag && buf)
|
if (alloc_flag && buf)
|
||||||
memcpy(abuf->data, buf, len);
|
memcpy(abuf->data, buf, len);
|
||||||
JS_SetOpaque(obj, abuf);
|
JS_SetOpaqueInternal(obj, abuf);
|
||||||
return obj;
|
return obj;
|
||||||
fail:
|
fail:
|
||||||
JS_FreeValue(ctx, obj);
|
JS_FreeValue(ctx, obj);
|
||||||
|
@ -54771,7 +54789,7 @@ static JSValue js_weakref_constructor(JSContext *ctx, JSValue new_target, int ar
|
||||||
wr->u.weak_ref_data = wrd;
|
wr->u.weak_ref_data = wrd;
|
||||||
insert_weakref_record(arg, wr);
|
insert_weakref_record(arg, wr);
|
||||||
|
|
||||||
JS_SetOpaque(obj, wrd);
|
JS_SetOpaqueInternal(obj, wrd);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54881,7 +54899,7 @@ static JSValue js_finrec_constructor(JSContext *ctx, JSValue new_target, int arg
|
||||||
init_list_head(&frd->entries);
|
init_list_head(&frd->entries);
|
||||||
frd->ctx = ctx;
|
frd->ctx = ctx;
|
||||||
frd->cb = js_dup(cb);
|
frd->cb = js_dup(cb);
|
||||||
JS_SetOpaque(obj, frd);
|
JS_SetOpaqueInternal(obj, frd);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55039,7 +55057,7 @@ static void reset_weak_ref(JSRuntime *rt, JSWeakRefRecord **first_weak_ref)
|
||||||
break;
|
break;
|
||||||
case JS_WEAK_REF_KIND_WEAK_REF:
|
case JS_WEAK_REF_KIND_WEAK_REF:
|
||||||
wrd = wr->u.weak_ref_data;
|
wrd = wr->u.weak_ref_data;
|
||||||
JS_SetOpaque(wrd->obj, &js_weakref_sentinel);
|
JS_SetOpaqueInternal(wrd->obj, &js_weakref_sentinel);
|
||||||
js_free_rt(rt, wrd);
|
js_free_rt(rt, wrd);
|
||||||
break;
|
break;
|
||||||
case JS_WEAK_REF_KIND_FINALIZATION_REGISTRY_ENTRY: {
|
case JS_WEAK_REF_KIND_FINALIZATION_REGISTRY_ENTRY: {
|
||||||
|
@ -55271,7 +55289,7 @@ static JSValue js_new_callsite(JSContext *ctx, JSCallSiteData *csd) {
|
||||||
|
|
||||||
memcpy(csd1, csd, sizeof(*csd));
|
memcpy(csd1, csd, sizeof(*csd));
|
||||||
|
|
||||||
JS_SetOpaque(obj, csd1);
|
JS_SetOpaqueInternal(obj, csd1);
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
|
@ -755,7 +755,7 @@ JS_EXTERN int JS_DefinePropertyValueStr(JSContext *ctx, JSValue this_obj,
|
||||||
JS_EXTERN int JS_DefinePropertyGetSet(JSContext *ctx, JSValue this_obj,
|
JS_EXTERN int JS_DefinePropertyGetSet(JSContext *ctx, JSValue this_obj,
|
||||||
JSAtom prop, JSValue getter, JSValue setter,
|
JSAtom prop, JSValue getter, JSValue setter,
|
||||||
int flags);
|
int flags);
|
||||||
JS_EXTERN void JS_SetOpaque(JSValue obj, void *opaque);
|
JS_EXTERN JS_BOOL JS_SetOpaque(JSValue obj, void *opaque);
|
||||||
JS_EXTERN void *JS_GetOpaque(JSValue obj, JSClassID class_id);
|
JS_EXTERN void *JS_GetOpaque(JSValue obj, JSClassID class_id);
|
||||||
JS_EXTERN void *JS_GetOpaque2(JSContext *ctx, JSValue obj, JSClassID class_id);
|
JS_EXTERN void *JS_GetOpaque2(JSContext *ctx, JSValue obj, JSClassID class_id);
|
||||||
JS_EXTERN void *JS_GetAnyOpaque(JSValue obj, JSClassID *class_id);
|
JS_EXTERN void *JS_GetAnyOpaque(JSValue obj, JSClassID *class_id);
|
||||||
|
|
Loading…
Reference in a new issue