Issue #1240 - Part 6b - Use ToIndex when constructing TypedArray with length argument. https://bugzilla.mozilla.org/show_bug.cgi?id=1317383 Part 2.

This commit is contained in:
Brian Smith 2023-07-19 16:36:58 -05:00 committed by roytam1
commit e004b99054
5 changed files with 51 additions and 43 deletions

View file

@ -1768,6 +1768,35 @@ js::ToIntegerIndex(JSContext* cx, JS::HandleValue v, uint64_t* index)
return true;
}
// ES2017 draft 7.1.17 ToIndex
bool
js::ToIndex(JSContext* cx, JS::HandleValue v, uint64_t* index)
{
// Step 1.
if (v.isUndefined()) {
*index = 0;
return true;
}
// Step 2.a.
double integerIndex;
if (!ToInteger(cx, v, &integerIndex))
return false;
// Inlined version of ToLength.
// 1. Already an integer.
// 2. Step eliminates < 0, +0 == -0 with SameValueZero.
// 3/4. Limit to <= 2^53-1, so everything above should fail.
if (integerIndex < 0 || integerIndex >= DOUBLE_INTEGRAL_PRECISION_LIMIT) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
return false;
}
// Step 3.
*index = uint64_t(integerIndex);
return true;
}
template <typename CharT>
bool
js_strtod(ExclusiveContext* cx, const CharT* begin, const CharT* end, const CharT** dEnd,

View file

@ -308,6 +308,15 @@ MOZ_MUST_USE bool ToLengthClamped(T* cx, HandleValue v, uint32_t* out, bool* ove
*/
MOZ_MUST_USE bool ToIntegerIndex(JSContext* cx, JS::HandleValue v, uint64_t* index);
/* ES2017 draft 7.1.17 ToIndex
*
* Return true and set |*index| to the integer value if |v| is a valid
* integer index value. Otherwise report a RangeError and return false.
*
* The returned index will always be in the range 0 <= *index <= 2^53-1.
*/
MOZ_MUST_USE bool ToIndex(JSContext* cx, JS::HandleValue v, uint64_t* index);
MOZ_MUST_USE inline bool
SafeAdd(int32_t one, int32_t two, int32_t* res)
{

View file

@ -264,27 +264,24 @@ ArrayBufferObject::fun_isView(JSContext* cx, unsigned argc, Value* vp)
return true;
}
/*
* new ArrayBuffer(byteLength)
*/
// ES2017 draft 24.1.2.1
bool
ArrayBufferObject::class_constructor(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
// Step 1.
if (!ThrowIfNotConstructing(cx, args, "ArrayBuffer"))
return false;
int32_t nbytes = 0;
if (argc > 0 && !ToInt32(cx, args[0], &nbytes))
// Step 2.
uint64_t byteLength;
if (!ToIndex(cx, args.get(0), &byteLength))
return false;
if (nbytes < 0) {
/*
* We're just not going to support arrays that are bigger than what will fit
* as an integer value; if someone actually ever complains (validly), then we
* can fix.
*/
// Non-standard: Refuse to allocate buffers larger than ~2 GiB.
if (byteLength > INT32_MAX) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_ARRAY_LENGTH);
return false;
}
@ -294,7 +291,7 @@ ArrayBufferObject::class_constructor(JSContext* cx, unsigned argc, Value* vp)
if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
return false;
JSObject* bufobj = create(cx, uint32_t(nbytes), proto);
JSObject* bufobj = create(cx, uint32_t(byteLength), proto);
if (!bufobj)
return false;
args.rval().setObject(*bufobj);

View file

@ -1898,10 +1898,8 @@ DataViewObject::class_constructor(JSContext* cx, unsigned argc, Value* vp)
template <typename NativeType>
/* static */ uint8_t*
DataViewObject::getDataPointer(JSContext* cx, Handle<DataViewObject*> obj, double offset)
DataViewObject::getDataPointer(JSContext* cx, Handle<DataViewObject*> obj, uint64_t offset)
{
MOZ_ASSERT(offset >= 0);
const size_t TypeSize = sizeof(NativeType);
if (offset > UINT32_MAX - TypeSize || offset + TypeSize > obj->byteLength()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_ARG_INDEX_OUT_OF_RANGE,
@ -1989,31 +1987,6 @@ struct DataViewIO
}
};
static bool
ToIndex(JSContext* cx, HandleValue v, double* index)
{
if (v.isUndefined()) {
*index = 0.0;
return true;
}
double integerIndex;
if (!ToInteger(cx, v, &integerIndex))
return false;
// Inlined version of ToLength.
// 1. Already an integer
// 2. Step eliminates < 0, +0 == -0 with SameValueZero
// 3/4. Limit to <= 2^53-1, so everything above should fail.
if (integerIndex < 0 || integerIndex > 9007199254740991) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
return false;
}
*index = integerIndex;
return true;
}
template<typename NativeType>
/* static */ bool
DataViewObject::read(JSContext* cx, Handle<DataViewObject*> obj,
@ -2023,7 +1996,7 @@ DataViewObject::read(JSContext* cx, Handle<DataViewObject*> obj,
// Step 3. unnecessary assert
// Step 4.
double getIndex;
uint64_t getIndex;
if (!ToIndex(cx, args.get(0), &getIndex))
return false;
@ -2111,7 +2084,7 @@ DataViewObject::write(JSContext* cx, Handle<DataViewObject*> obj,
// Step 3. unnecessary assert
// Step 4.
double getIndex;
uint64_t getIndex;
if (!ToIndex(cx, args.get(0), &getIndex))
return false;

View file

@ -442,7 +442,7 @@ class DataViewObject : public NativeObject
template <typename NativeType>
static uint8_t*
getDataPointer(JSContext* cx, Handle<DataViewObject*> obj, double offset);
getDataPointer(JSContext* cx, Handle<DataViewObject*> obj, uint64_t offset);
template<Value ValueGetter(DataViewObject* view)>
static bool