mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:52:45 +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 {}; | ||||
|         if (value.is_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(); | ||||
|         auto string = value.to_string(global_object); | ||||
|         if (string.is_null()) | ||||
|  | @ -49,8 +49,8 @@ public: | |||
|         // FIXME: Replace this with requires(IsUnsigned<T>)?
 | ||||
|         //        Needs changes in various places using `int` (but not actually being in the negative range)
 | ||||
|         VERIFY(index >= 0); | ||||
|         if constexpr (NumericLimits<T>::max() > NumericLimits<u32>::max()) | ||||
|             VERIFY(index <= NumericLimits<u32>::max()); | ||||
|         if constexpr (NumericLimits<T>::max() >= NumericLimits<u32>::max()) | ||||
|             VERIFY(index < NumericLimits<u32>::max()); | ||||
|     } | ||||
| 
 | ||||
|     PropertyName(char const* chars) | ||||
|  | @ -131,7 +131,7 @@ public: | |||
|         } | ||||
| 
 | ||||
|         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; | ||||
|             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
	
	 Linus Groh
						Linus Groh