return null in bad retrieval, throw on bad insert

This commit is contained in:
2026-01-06 09:16:15 -06:00
parent eba0727247
commit df07069c38
2 changed files with 96 additions and 15 deletions

View File

@@ -7572,10 +7572,10 @@ static JSValue JS_GetPropertyValue(JSContext *ctx, JSValueConst this_obj,
signed_idx = JS_VALUE_GET_INT(prop);
switch(p->class_id) {
case JS_CLASS_ARRAY:
/* arrays require non-negative numeric index */
/* arrays require non-negative numeric index - return null for invalid */
if (signed_idx < 0) {
JS_FreeValue(ctx, prop);
return JS_ThrowTypeError(ctx, "array index must be non-negative");
return JS_NULL;
}
idx = (uint32_t)signed_idx;
if (unlikely(idx >= p->u.array.count)) goto slow_path;
@@ -7585,34 +7585,41 @@ static JSValue JS_GetPropertyValue(JSContext *ctx, JSValueConst this_obj,
}
} else {
slow_path:
/* Type checking for array vs object indexing */
/* Type checking for array vs object indexing - return null for invalid retrieval */
if (JS_VALUE_GET_TAG(this_obj) == JS_TAG_OBJECT) {
JSObject *p = JS_VALUE_GET_OBJ(this_obj);
if (p->class_id == JS_CLASS_ARRAY) {
/* Arrays require numeric index */
/* Arrays require numeric index - return null for non-numeric */
if (prop_tag != JS_TAG_INT && !JS_TAG_IS_FLOAT64(prop_tag)) {
JS_FreeValue(ctx, prop);
return JS_ThrowTypeError(ctx, "array index must be a number");
return JS_NULL;
}
/* Check for negative index */
/* Return null for negative index */
if (prop_tag == JS_TAG_INT) {
if (JS_VALUE_GET_INT(prop) < 0) {
JS_FreeValue(ctx, prop);
return JS_ThrowTypeError(ctx, "array index must be non-negative");
return JS_NULL;
}
} else {
double d = JS_VALUE_GET_FLOAT64(prop);
if (d < 0) {
JS_FreeValue(ctx, prop);
return JS_ThrowTypeError(ctx, "array index must be non-negative");
return JS_NULL;
}
}
} else {
/* Objects require text or object (symbol) key - NOT numbers */
if (prop_tag != JS_TAG_STRING && prop_tag != JS_TAG_STRING_ROPE &&
prop_tag != JS_TAG_SYMBOL && prop_tag != JS_TAG_OBJECT) {
/* Objects require text or non-array object (symbol) key - return null for invalid */
if (prop_tag == JS_TAG_OBJECT) {
/* Check if it's an array - arrays not allowed as object keys */
JSObject *key_obj = JS_VALUE_GET_OBJ(prop);
if (key_obj->class_id == JS_CLASS_ARRAY) {
JS_FreeValue(ctx, prop);
return JS_NULL;
}
} else if (prop_tag != JS_TAG_STRING && prop_tag != JS_TAG_STRING_ROPE &&
prop_tag != JS_TAG_SYMBOL) {
JS_FreeValue(ctx, prop);
return JS_ThrowTypeError(ctx, "object key must be text or object");
return JS_NULL;
}
}
}
@@ -8388,9 +8395,18 @@ static int JS_SetPropertyValue(JSContext *ctx, JSValueConst this_obj,
}
}
} else {
/* Objects require text or object (symbol) key - NOT numbers */
if (prop_tag != JS_TAG_STRING && prop_tag != JS_TAG_STRING_ROPE &&
prop_tag != JS_TAG_SYMBOL && prop_tag != JS_TAG_OBJECT) {
/* Objects require text or non-array object (symbol) key - NOT numbers */
if (prop_tag == JS_TAG_OBJECT) {
/* Check if it's an array - arrays not allowed as object keys */
JSObject *key_obj = JS_VALUE_GET_OBJ(prop);
if (key_obj->class_id == JS_CLASS_ARRAY) {
JS_FreeValue(ctx, prop);
JS_FreeValue(ctx, val);
JS_ThrowTypeError(ctx, "object key must be text or object, not array");
return -1;
}
} else if (prop_tag != JS_TAG_STRING && prop_tag != JS_TAG_STRING_ROPE &&
prop_tag != JS_TAG_SYMBOL) {
JS_FreeValue(ctx, prop);
JS_FreeValue(ctx, val);
JS_ThrowTypeError(ctx, "object key must be text or object");