mirror of
https://github.com/RGBCube/serenity
synced 2025-05-23 12:35:07 +00:00
LibJS: Don't treat 2^32 - 1 as numeric PropertyName
10.4.2 Array Exotic Objects https://tc39.es/ecma262/#sec-array-exotic-objects A String property name P is an array index if and only if ToString(ToUint32(P)) equals P and ToUint32(P) is not the same value as 𝔽(2^32 - 1).
This commit is contained in:
parent
47bd25a2f1
commit
83f61748a5
2 changed files with 34 additions and 4 deletions
|
@ -31,7 +31,7 @@ public:
|
||||||
return {};
|
return {};
|
||||||
if (value.is_symbol())
|
if (value.is_symbol())
|
||||||
return value.as_symbol();
|
return value.as_symbol();
|
||||||
if (value.is_integral_number() && value.as_double() >= 0 && value.as_double() <= NumericLimits<u32>::max())
|
if (value.is_integral_number() && value.as_double() >= 0 && value.as_double() < NumericLimits<u32>::max())
|
||||||
return value.as_u32();
|
return value.as_u32();
|
||||||
auto string = value.to_string(global_object);
|
auto string = value.to_string(global_object);
|
||||||
if (string.is_null())
|
if (string.is_null())
|
||||||
|
@ -49,8 +49,8 @@ public:
|
||||||
// FIXME: Replace this with requires(IsUnsigned<T>)?
|
// FIXME: Replace this with requires(IsUnsigned<T>)?
|
||||||
// Needs changes in various places using `int` (but not actually being in the negative range)
|
// Needs changes in various places using `int` (but not actually being in the negative range)
|
||||||
VERIFY(index >= 0);
|
VERIFY(index >= 0);
|
||||||
if constexpr (NumericLimits<T>::max() > NumericLimits<u32>::max())
|
if constexpr (NumericLimits<T>::max() >= NumericLimits<u32>::max())
|
||||||
VERIFY(index <= NumericLimits<u32>::max());
|
VERIFY(index < NumericLimits<u32>::max());
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyName(char const* chars)
|
PropertyName(char const* chars)
|
||||||
|
@ -131,7 +131,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
auto property_index = m_string.to_uint(TrimWhitespace::No);
|
auto property_index = m_string.to_uint(TrimWhitespace::No);
|
||||||
if (!property_index.has_value()) {
|
if (!property_index.has_value() || property_index.value() == NumericLimits<u32>::max()) {
|
||||||
m_string_may_be_number = false;
|
m_string_may_be_number = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
test("numeric properties", () => {
|
||||||
|
const i32Max = 2 ** 31 - 1;
|
||||||
|
const u32Max = 2 ** 32 - 1;
|
||||||
|
const o = {
|
||||||
|
[-1]: "foo",
|
||||||
|
0: "foo",
|
||||||
|
1: "foo",
|
||||||
|
[i32Max - 1]: "foo",
|
||||||
|
[i32Max]: "foo",
|
||||||
|
[i32Max + 1]: "foo",
|
||||||
|
[u32Max - 1]: "foo",
|
||||||
|
[u32Max]: "foo",
|
||||||
|
[u32Max + 1]: "foo",
|
||||||
|
};
|
||||||
|
// Numeric properties come first in Object.getOwnPropertyNames()'s output,
|
||||||
|
// which means we can test what each is treated as internally.
|
||||||
|
expect(Object.getOwnPropertyNames(o)).toEqual([
|
||||||
|
// Numeric properties
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"2147483646",
|
||||||
|
"2147483647",
|
||||||
|
"2147483648",
|
||||||
|
"4294967294",
|
||||||
|
// Non-numeric properties
|
||||||
|
"-1",
|
||||||
|
"4294967295", // >= 2^32 - 1
|
||||||
|
"4294967296", // >= 2^32 - 1
|
||||||
|
]);
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue