Bug 1771874 part 3 - Make ToTypedArrayIndex infallible, remove unused cx argument. r=anba

Differential Revision: https://phabricator.services.mozilla.com/D147736
This commit is contained in:
Jan de Mooij 2022-06-03 06:05:42 +00:00
Родитель ec2cbc67fd
Коммит 937265d1ac
4 изменённых файлов: 34 добавлений и 73 удалений

Просмотреть файл

@ -704,15 +704,7 @@ static MOZ_ALWAYS_INLINE bool NativeLookupOwnPropertyInline(
// so that integer properties on the prototype are ignored even for out
// of bounds accesses.
if (obj->template is<TypedArrayObject>()) {
mozilla::Maybe<uint64_t> index;
if (!ToTypedArrayIndex(cx, id, &index)) {
if (!allowGC) {
cx->recoverFromOutOfMemory();
}
return false;
}
if (index.isSome()) {
if (mozilla::Maybe<uint64_t> index = ToTypedArrayIndex(id)) {
uint64_t idx = index.value();
if (idx < obj->template as<TypedArrayObject>().length()) {
propp->setTypedArrayElement(idx);

Просмотреть файл

@ -1443,14 +1443,9 @@ bool js::NativeDefineProperty(JSContext* cx, HandleNativeObject obj,
}
} else if (obj->is<TypedArrayObject>()) {
// 9.4.5.3 step 3. Indexed properties of typed arrays are special.
Rooted<TypedArrayObject*> tobj(cx, &obj->as<TypedArrayObject>());
mozilla::Maybe<uint64_t> index;
if (!ToTypedArrayIndex(cx, id, &index)) {
return false;
}
if (index) {
if (mozilla::Maybe<uint64_t> index = ToTypedArrayIndex(id)) {
MOZ_ASSERT(!cx->isHelperThreadContext());
Rooted<TypedArrayObject*> tobj(cx, &obj->as<TypedArrayObject>());
return DefineTypedArrayElement(cx, tobj, index.value(), desc_, result);
}
} else if (obj->is<ArgumentsObject>()) {
@ -1741,12 +1736,7 @@ static bool DefineNonexistentProperty(JSContext* cx, HandleNativeObject obj,
}
} else if (obj->is<TypedArrayObject>()) {
// 9.4.5.5 step 2. Indexed properties of typed arrays are special.
mozilla::Maybe<uint64_t> index;
if (!ToTypedArrayIndex(cx, id, &index)) {
return false;
}
if (index) {
if (mozilla::Maybe<uint64_t> index = ToTypedArrayIndex(id)) {
// This method is only called for non-existent properties, which
// means any absent indexed property must be out of range.
MOZ_ASSERT(index.value() >= obj->as<TypedArrayObject>().length());

Просмотреть файл

@ -2468,9 +2468,8 @@ static inline bool StringIsNaN(mozilla::Range<const CharT> s) {
}
template <typename CharT>
static bool StringToTypedArrayIndexSlow(JSContext* cx,
mozilla::Range<const CharT> s,
mozilla::Maybe<uint64_t>* indexp) {
static mozilla::Maybe<uint64_t> StringToTypedArrayIndexSlow(
mozilla::Range<const CharT> s) {
const mozilla::RangedPtr<const CharT> start = s.begin();
const mozilla::RangedPtr<const CharT> end = s.end();
@ -2479,8 +2478,7 @@ static bool StringToTypedArrayIndexSlow(JSContext* cx,
// The complete string must have been parsed.
if (actualEnd != end.get()) {
MOZ_ASSERT(indexp->isNothing());
return true;
return mozilla::Nothing();
}
// Now convert it back to a string.
@ -2491,8 +2489,7 @@ static bool StringToTypedArrayIndexSlow(JSContext* cx,
// Both strings must be equal for a canonical numeric index string.
if (s.length() != strlen(cstr) ||
!EqualChars(start.get(), cstr, s.length())) {
MOZ_ASSERT(indexp->isNothing());
return true;
return mozilla::Nothing();
}
// Directly perform IsInteger() check and encode negative and non-integer
@ -2502,25 +2499,22 @@ static bool StringToTypedArrayIndexSlow(JSContext* cx,
// See 9.4.5.8 IntegerIndexedElementGet, steps 5 and 8.
// See 9.4.5.9 IntegerIndexedElementSet, steps 6 and 9.
if (result < 0 || !IsInteger(result)) {
indexp->emplace(UINT64_MAX);
return true;
return mozilla::Some(UINT64_MAX);
}
// Anything equals-or-larger than 2^53 is definitely OOB, encode it
// accordingly so that the cast to uint64_t is well defined.
if (result >= DOUBLE_INTEGRAL_PRECISION_LIMIT) {
indexp->emplace(UINT64_MAX);
return true;
return mozilla::Some(UINT64_MAX);
}
// The string is an actual canonical numeric index.
indexp->emplace(result);
return true;
return mozilla::Some(result);
}
template <typename CharT>
bool js::StringToTypedArrayIndex(JSContext* cx, mozilla::Range<const CharT> s,
mozilla::Maybe<uint64_t>* indexp) {
mozilla::Maybe<uint64_t> js::StringToTypedArrayIndex(
mozilla::Range<const CharT> s) {
mozilla::RangedPtr<const CharT> cp = s.begin();
const mozilla::RangedPtr<const CharT> end = s.end();
@ -2530,8 +2524,7 @@ bool js::StringToTypedArrayIndex(JSContext* cx, mozilla::Range<const CharT> s,
if (*cp == '-') {
negative = true;
if (++cp == end) {
MOZ_ASSERT(indexp->isNothing());
return true;
return mozilla::Nothing();
}
}
@ -2539,11 +2532,9 @@ bool js::StringToTypedArrayIndex(JSContext* cx, mozilla::Range<const CharT> s,
// Check for "NaN", "Infinity", or "-Infinity".
if ((!negative && StringIsNaN<CharT>({cp, end})) ||
StringIsInfinity<CharT>({cp, end})) {
indexp->emplace(UINT64_MAX);
} else {
MOZ_ASSERT(indexp->isNothing());
return mozilla::Some(UINT64_MAX);
}
return true;
return mozilla::Nothing();
}
uint32_t digit = AsciiDigitToNumber(*cp++);
@ -2553,10 +2544,9 @@ bool js::StringToTypedArrayIndex(JSContext* cx, mozilla::Range<const CharT> s,
// The string may be of the form "0.xyz". The exponent form isn't possible
// when the string starts with "0".
if (*cp == '.') {
return StringToTypedArrayIndexSlow(cx, s, indexp);
return StringToTypedArrayIndexSlow(s);
}
MOZ_ASSERT(indexp->isNothing());
return true;
return mozilla::Nothing();
}
uint64_t index = digit;
@ -2565,10 +2555,9 @@ bool js::StringToTypedArrayIndex(JSContext* cx, mozilla::Range<const CharT> s,
if (!IsAsciiDigit(*cp)) {
// Take the slow path when the string has fractional parts or an exponent.
if (*cp == '.' || *cp == 'e') {
return StringToTypedArrayIndexSlow(cx, s, indexp);
return StringToTypedArrayIndexSlow(s);
}
MOZ_ASSERT(indexp->isNothing());
return true;
return mozilla::Nothing();
}
digit = AsciiDigitToNumber(*cp);
@ -2581,25 +2570,21 @@ bool js::StringToTypedArrayIndex(JSContext* cx, mozilla::Range<const CharT> s,
// Also take the slow path when the string is larger-or-equals 2^53.
if (index >= uint64_t(DOUBLE_INTEGRAL_PRECISION_LIMIT)) {
return StringToTypedArrayIndexSlow(cx, s, indexp);
return StringToTypedArrayIndexSlow(s);
}
}
if (negative) {
indexp->emplace(UINT64_MAX);
} else {
indexp->emplace(index);
return mozilla::Some(UINT64_MAX);
}
return true;
return mozilla::Some(index);
}
template bool js::StringToTypedArrayIndex(JSContext* cx,
mozilla::Range<const char16_t> s,
mozilla::Maybe<uint64_t>* indexOut);
template mozilla::Maybe<uint64_t> js::StringToTypedArrayIndex(
mozilla::Range<const char16_t> s);
template bool js::StringToTypedArrayIndex(JSContext* cx,
mozilla::Range<const Latin1Char> s,
mozilla::Maybe<uint64_t>* indexOut);
template mozilla::Maybe<uint64_t> js::StringToTypedArrayIndex(
mozilla::Range<const Latin1Char> s);
bool js::SetTypedArrayElement(JSContext* cx, Handle<TypedArrayObject*> obj,
uint64_t index, HandleValue v,

Просмотреть файл

@ -220,9 +220,7 @@ inline size_t TypedArrayObject::bytesPerElement() const {
// string is a canonical numeric index which is not representable as a uint64_t,
// the returned index is UINT64_MAX.
template <typename CharT>
[[nodiscard]] bool StringToTypedArrayIndex(JSContext* cx,
mozilla::Range<const CharT> s,
mozilla::Maybe<uint64_t>* indexp);
mozilla::Maybe<uint64_t> StringToTypedArrayIndex(mozilla::Range<const CharT> s);
// A string |s| is a TypedArray index (or: canonical numeric index string) iff
// |s| is "-0" or |SameValue(ToString(ToNumber(s)), s)| is true. So check for
@ -233,35 +231,31 @@ inline bool CanStartTypedArrayIndex(CharT ch) {
return mozilla::IsAsciiDigit(ch) || ch == '-' || ch == 'N' || ch == 'I';
}
[[nodiscard]] inline bool ToTypedArrayIndex(JSContext* cx, jsid id,
mozilla::Maybe<uint64_t>* indexp) {
[[nodiscard]] inline mozilla::Maybe<uint64_t> ToTypedArrayIndex(jsid id) {
if (id.isInt()) {
int32_t i = id.toInt();
MOZ_ASSERT(i >= 0);
indexp->emplace(i);
return true;
return mozilla::Some(i);
}
if (MOZ_UNLIKELY(!id.isString())) {
MOZ_ASSERT(indexp->isNothing());
return true;
return mozilla::Nothing();
}
JS::AutoCheckCannotGC nogc;
JSAtom* atom = id.toAtom();
if (atom->empty() || !CanStartTypedArrayIndex(atom->latin1OrTwoByteChar(0))) {
MOZ_ASSERT(indexp->isNothing());
return true;
return mozilla::Nothing();
}
if (atom->hasLatin1Chars()) {
mozilla::Range<const Latin1Char> chars = atom->latin1Range(nogc);
return StringToTypedArrayIndex(cx, chars, indexp);
return StringToTypedArrayIndex(chars);
}
mozilla::Range<const char16_t> chars = atom->twoByteRange(nogc);
return StringToTypedArrayIndex(cx, chars, indexp);
return StringToTypedArrayIndex(chars);
}
bool SetTypedArrayElement(JSContext* cx, Handle<TypedArrayObject*> obj,