author | Jon Coppeard <jcoppeard@mozilla.com> |
Thu, 29 Sep 2016 10:18:50 +0100 | |
changeset 315810 | d9b67ef4fb0a2f2de2c398034ffe027c07aae8e9 |
parent 315809 | 955340c5cf9eff6f6aa79c88f656fa27428fb12f |
child 315811 | 6a996a75330fb7d4376b4ed6d439126d8b5a50a2 |
push id | 30757 |
push user | cbook@mozilla.com |
push date | Fri, 30 Sep 2016 10:02:43 +0000 |
treeherder | mozilla-central@5ffed033557e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jandem |
bugs | 1269755 |
milestone | 52.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/vm/String.cpp +++ b/js/src/vm/String.cpp @@ -572,16 +572,27 @@ JSRope::flatten(ExclusiveContext* maybec sps.emplace(maybecx->asJSContext()->runtime(), "JSRope::flatten"); if (zone()->needsIncrementalBarrier()) return flattenInternal<WithIncrementalBarrier>(maybecx); return flattenInternal<NoBarrier>(maybecx); } template <AllowGC allowGC> +static JSLinearString* +EnsureLinear(ExclusiveContext* cx, typename MaybeRooted<JSString*, allowGC>::HandleType string) +{ + JSLinearString* linear = string->ensureLinear(cx); + // Don't report an exception if GC is not allowed, just return nullptr. + if (!linear && !allowGC) + cx->recoverFromOutOfMemory(); + return linear; +} + +template <AllowGC allowGC> JSString* js::ConcatStrings(ExclusiveContext* cx, typename MaybeRooted<JSString*, allowGC>::HandleType left, typename MaybeRooted<JSString*, allowGC>::HandleType right) { MOZ_ASSERT_IF(!left->isAtom(), cx->isInsideCurrentZone(left)); MOZ_ASSERT_IF(!right->isAtom(), cx->isInsideCurrentZone(right)); @@ -589,37 +600,41 @@ js::ConcatStrings(ExclusiveContext* cx, if (leftLen == 0) return right; size_t rightLen = right->length(); if (rightLen == 0) return left; size_t wholeLength = leftLen + rightLen; - if (!JSString::validateLength(cx, wholeLength)) + if (MOZ_UNLIKELY(wholeLength > JSString::MAX_LENGTH)) { + // Don't report an exception if GC is not allowed, just return nullptr. + if (allowGC) + js::ReportAllocationOverflow(cx); return nullptr; + } bool isLatin1 = left->hasLatin1Chars() && right->hasLatin1Chars(); bool canUseInline = isLatin1 ? JSInlineString::lengthFits<Latin1Char>(wholeLength) : JSInlineString::lengthFits<char16_t>(wholeLength); if (canUseInline && cx->isJSContext()) { Latin1Char* latin1Buf = nullptr; // initialize to silence GCC warning char16_t* twoByteBuf = nullptr; // initialize to silence GCC warning JSInlineString* str = isLatin1 ? AllocateInlineString<allowGC>(cx, wholeLength, &latin1Buf) : AllocateInlineString<allowGC>(cx, wholeLength, &twoByteBuf); if (!str) return nullptr; AutoCheckCannotGC nogc; - JSLinearString* leftLinear = left->ensureLinear(cx); + JSLinearString* leftLinear = EnsureLinear<allowGC>(cx, left); if (!leftLinear) return nullptr; - JSLinearString* rightLinear = right->ensureLinear(cx); + JSLinearString* rightLinear = EnsureLinear<allowGC>(cx, right); if (!rightLinear) return nullptr; if (isLatin1) { PodCopy(latin1Buf, leftLinear->latin1Chars(nogc), leftLen); PodCopy(latin1Buf + leftLen, rightLinear->latin1Chars(nogc), rightLen); latin1Buf[wholeLength] = 0; } else {