[js] Use isElement in UnmappedArgSetter to check if the argument was marked as deleted.

This is more consistent with `UnmappedArgGetter` and better handles the
case where the property was marked deleted in `RareArgumentsData` but not
actually deleted from the object due to OOM. Unfortunately this scenario
is hard to prevent because the property is marked as deleted in the
`ArgumentsObject::obj_delProperty` class hook and after that
`NativeDeleteProperty` tries to remove the property and this can fail.
This commit is contained in:
Moonchild
2026-04-26 10:49:29 +02:00
committed by roytam1
parent 0329082cf0
commit 8a3427845f
2 changed files with 15 additions and 1 deletions
+1 -1
View File
@@ -690,7 +690,7 @@ UnmappedArgSetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleVal
if (JSID_IS_INT(id)) {
unsigned arg = unsigned(JSID_TO_INT(id));
if (arg < argsobj->initialLength()) {
if (argsobj->isElement(arg)) {
argsobj->setElement(cx, arg, vp);
return result.succeed();
}
+14
View File
@@ -283,6 +283,20 @@ class ArgumentsObject : public NativeObject
bool markElementDeleted(JSContext* cx, uint32_t i);
/*
* Return true if the index is a valid element index for this arguments
* object.
*
* Returning true here doesn't imply that the element value can be read
* through |ArgumentsObject::element()|. For example, unmapped arguments
* objects can have an element index property redefined without having marked
* the element as deleted. Instead, use |maybeGetElement()| or manually check
* for |hasOverriddenElement()|.
*/
bool isElement(uint32_t i) const {
return i < initialLength() && !isElementDeleted(i);
}
/*
* An ArgumentsObject serves two roles:
* - a real object, accessed through regular object operations, e.g..,