fixed checks in Proxy defineProperty

This commit is contained in:
Fabrice Bellard 2025-04-21 14:00:32 +02:00
parent e7264d6f94
commit e1f6dfe61a

View File

@ -9363,15 +9363,13 @@ static BOOL check_define_prop_flags(int prop_flags, int flags)
if ((flags & JS_PROP_HAS_ENUMERABLE) && if ((flags & JS_PROP_HAS_ENUMERABLE) &&
(flags & JS_PROP_ENUMERABLE) != (prop_flags & JS_PROP_ENUMERABLE)) (flags & JS_PROP_ENUMERABLE) != (prop_flags & JS_PROP_ENUMERABLE))
return FALSE; return FALSE;
} if (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE |
if (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE | JS_PROP_HAS_GET | JS_PROP_HAS_SET)) {
JS_PROP_HAS_GET | JS_PROP_HAS_SET)) {
if (!(prop_flags & JS_PROP_CONFIGURABLE)) {
has_accessor = ((flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) != 0); has_accessor = ((flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) != 0);
is_getset = ((prop_flags & JS_PROP_TMASK) == JS_PROP_GETSET); is_getset = ((prop_flags & JS_PROP_TMASK) == JS_PROP_GETSET);
if (has_accessor != is_getset) if (has_accessor != is_getset)
return FALSE; return FALSE;
if (!has_accessor && !is_getset && !(prop_flags & JS_PROP_WRITABLE)) { if (!is_getset && !(prop_flags & JS_PROP_WRITABLE)) {
/* not writable: cannot set the writable bit */ /* not writable: cannot set the writable bit */
if ((flags & (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) == if ((flags & (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) ==
(JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE))
@ -46443,13 +46441,11 @@ static int js_proxy_define_own_property(JSContext *ctx, JSValueConst obj,
if (!p->extensible || setting_not_configurable) if (!p->extensible || setting_not_configurable)
goto fail; goto fail;
} else { } else {
if (!check_define_prop_flags(desc.flags, flags) || if (!check_define_prop_flags(desc.flags, flags))
((desc.flags & JS_PROP_CONFIGURABLE) && setting_not_configurable)) {
goto fail1; goto fail1;
} /* do the missing check from check_define_prop_flags() */
if (flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) { if (!(desc.flags & JS_PROP_CONFIGURABLE)) {
if ((desc.flags & (JS_PROP_GETSET | JS_PROP_CONFIGURABLE)) == if ((desc.flags & JS_PROP_TMASK) == JS_PROP_GETSET) {
JS_PROP_GETSET) {
if ((flags & JS_PROP_HAS_GET) && if ((flags & JS_PROP_HAS_GET) &&
!js_same_value(ctx, getter, desc.getter)) { !js_same_value(ctx, getter, desc.getter)) {
goto fail1; goto fail1;
@ -46458,27 +46454,26 @@ static int js_proxy_define_own_property(JSContext *ctx, JSValueConst obj,
!js_same_value(ctx, setter, desc.setter)) { !js_same_value(ctx, setter, desc.setter)) {
goto fail1; goto fail1;
} }
} } else if (!(desc.flags & JS_PROP_WRITABLE)) {
} else if (flags & JS_PROP_HAS_VALUE) { if ((flags & JS_PROP_HAS_VALUE) &&
if ((desc.flags & (JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE)) == !js_same_value(ctx, val, desc.value)) {
JS_PROP_WRITABLE && !(flags & JS_PROP_WRITABLE)) { goto fail1;
/* missing-proxy-check feature */ }
goto fail1;
} else if ((desc.flags & (JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE)) == 0 &&
!js_same_value(ctx, val, desc.value)) {
goto fail1;
} }
} }
if (flags & JS_PROP_HAS_WRITABLE) {
if ((desc.flags & (JS_PROP_GETSET | JS_PROP_CONFIGURABLE | /* additional checks */
JS_PROP_WRITABLE)) == JS_PROP_WRITABLE) { if ((desc.flags & JS_PROP_CONFIGURABLE) && setting_not_configurable)
/* proxy-missing-checks */ goto fail1;
fail1:
js_free_desc(ctx, &desc); if ((desc.flags & JS_PROP_TMASK) != JS_PROP_GETSET &&
fail: (desc.flags & (JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE)) == JS_PROP_WRITABLE &&
JS_ThrowTypeError(ctx, "proxy: inconsistent defineProperty"); (flags & (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) == JS_PROP_HAS_WRITABLE) {
return -1; fail1:
} js_free_desc(ctx, &desc);
fail:
JS_ThrowTypeError(ctx, "proxy: inconsistent defineProperty");
return -1;
} }
js_free_desc(ctx, &desc); js_free_desc(ctx, &desc);
} }