/* Return -1 if exception,
FALSE if the property does not exist, TRUE if it exists. If TRUE is
- returned, the property descriptor 'desc' is filled present. */
+ returned, the property descriptor 'desc' is filled. */
static int JS_GetOwnPropertyInternal(JSContext *ctx, JSPropertyDescriptor *desc,
JSObject *p, JSAtom prop)
{
return ret;
}
+/* return FALSE if not OK */
+static BOOL check_define_prop_desc(JSContext *ctx, const JSPropertyDescriptor *desc,
+ JSValueConst val, JSValueConst getter, JSValueConst setter,
+ int flags)
+{
+ if (!check_define_prop_flags(desc->flags, flags))
+ return FALSE;
+
+ /* do the missing check from check_define_prop_flags() */
+ if (!(desc->flags & JS_PROP_CONFIGURABLE)) {
+ if ((desc->flags & JS_PROP_TMASK) == JS_PROP_GETSET) {
+ if ((flags & JS_PROP_HAS_GET) &&
+ !js_same_value(ctx, getter, desc->getter)) {
+ return FALSE;
+ }
+ if ((flags & JS_PROP_HAS_SET) &&
+ !js_same_value(ctx, setter, desc->setter)) {
+ return FALSE;
+ }
+ } else if (!(desc->flags & JS_PROP_WRITABLE)) {
+ if ((flags & JS_PROP_HAS_VALUE) &&
+ !js_same_value(ctx, val, desc->value)) {
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
static int js_proxy_get_own_property(JSContext *ctx, JSPropertyDescriptor *pdesc,
JSValueConst obj, JSAtom prop)
{
JS_FreeValue(ctx, trap_result_obj);
return -1;
}
- if (target_desc_ret)
- js_free_desc(ctx, &target_desc);
if (JS_IsUndefined(trap_result_obj)) {
if (target_desc_ret) {
- if (!(target_desc.flags & JS_PROP_CONFIGURABLE) || !p->extensible)
+ BOOL tmp;
+ tmp = !(target_desc.flags & JS_PROP_CONFIGURABLE) || !p->extensible;
+ js_free_desc(ctx, &target_desc);
+ if (tmp)
goto fail;
}
ret = FALSE;
extensible_target = JS_IsExtensible(ctx, s->target);
if (extensible_target < 0) {
JS_FreeValue(ctx, trap_result_obj);
+ if (target_desc_ret)
+ js_free_desc(ctx, &target_desc);
return -1;
}
res = js_obj_to_desc(ctx, &result_desc, trap_result_obj);
JS_FreeValue(ctx, trap_result_obj);
- if (res < 0)
+ if (res < 0) {
+ if (target_desc_ret)
+ js_free_desc(ctx, &target_desc);
return -1;
+ }
/* convert the result_desc.flags to property flags */
if (result_desc.flags & (JS_PROP_HAS_GET | JS_PROP_HAS_SET)) {
flags1 |= JS_PROP_HAS_GET | JS_PROP_HAS_SET;
else
flags1 |= JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE;
- /* XXX: not complete check: need to compare value &
- getter/setter as in defineproperty */
- if (!check_define_prop_flags(target_desc.flags, flags1))
+ if (!check_define_prop_desc(ctx, &target_desc, result_desc.value,
+ result_desc.getter, result_desc.setter, flags1)) {
goto fail1;
+ }
} else {
if (!extensible_target)
goto fail1;
/* proxy-missing-checks */
fail1:
js_free_desc(ctx, &result_desc);
+ if (target_desc_ret)
+ js_free_desc(ctx, &target_desc);
fail:
JS_ThrowTypeError(ctx, "proxy: inconsistent getOwnPropertyDescriptor");
return -1;
}
}
+ if (target_desc_ret)
+ js_free_desc(ctx, &target_desc);
ret = TRUE;
if (pdesc) {
*pdesc = result_desc;
if (!p->extensible || setting_not_configurable)
goto fail;
} else {
- if (!check_define_prop_flags(desc.flags, flags))
+ if (!check_define_prop_desc(ctx, &desc, val, getter, setter, flags))
goto fail1;
- /* do the missing check from check_define_prop_flags() */
- if (!(desc.flags & JS_PROP_CONFIGURABLE)) {
- if ((desc.flags & JS_PROP_TMASK) == JS_PROP_GETSET) {
- if ((flags & JS_PROP_HAS_GET) &&
- !js_same_value(ctx, getter, desc.getter)) {
- goto fail1;
- }
- if ((flags & JS_PROP_HAS_SET) &&
- !js_same_value(ctx, setter, desc.setter)) {
- goto fail1;
- }
- } else if (!(desc.flags & JS_PROP_WRITABLE)) {
- if ((flags & JS_PROP_HAS_VALUE) &&
- !js_same_value(ctx, val, desc.value)) {
- goto fail1;
- }
- }
- }
/* additional checks */
if ((desc.flags & JS_PROP_CONFIGURABLE) && setting_not_configurable)