Bug 1379983 - Part 3: Remove goto statements from Unescape function and some other clean-ups. r=jandem

--HG--
extra : rebase_source : ff238fd152fd2c67857f1c255ec49615f4e4bfa1
This commit is contained in:
André Bargull 2017-07-12 07:36:40 -07:00
Родитель 9a3eb95fa0
Коммит a108ef2f00
1 изменённых файлов: 41 добавлений и 53 удалений

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

@ -6,6 +6,7 @@
#include "jsstr.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Attributes.h"
#include "mozilla/Casting.h"
#include "mozilla/CheckedInt.h"
@ -387,39 +388,15 @@ template <typename CharT>
static bool
Unescape(StringBuffer& sb, const mozilla::Range<const CharT> chars)
{
/*
* NB: use signed integers for length/index to allow simple length
* comparisons without unsigned-underflow hazards.
*/
static_assert(JSString::MAX_LENGTH <= INT_MAX, "String length must fit in a signed integer");
int length = AssertedCast<int>(chars.length());
// Step 2.
uint32_t length = chars.length();
/*
* Note that the spec algorithm has been optimized to avoid building
* a string in the case where no escapes are present.
*/
/* Step 4. */
int k = 0;
bool building = false;
/* Step 5. */
while (k < length) {
/* Step 6. */
char16_t c = chars[k];
/* Step 7. */
if (c != '%')
goto step_18;
/* Step 8. */
if (k > length - 6)
goto step_14;
/* Step 9. */
if (chars[k + 1] != 'u')
goto step_14;
#define ENSURE_BUILDING \
do { \
if (!building) { \
@ -430,29 +407,38 @@ Unescape(StringBuffer& sb, const mozilla::Range<const CharT> chars)
} \
} while(false);
/* Step 10-13. */
if (Unhex4(chars.begin() + k + 2, &c)) {
ENSURE_BUILDING;
k += 5;
goto step_18;
// Step 4.
uint32_t k = 0;
// Step 5.
while (k < length) {
// Step 5.a.
char16_t c = chars[k];
// Step 5.b.
if (c == '%') {
static_assert(JSString::MAX_LENGTH < UINT32_MAX - 6,
"String length is not near UINT32_MAX");
// Steps 5.b.i-ii.
if (k + 6 <= length && chars[k + 1] == 'u') {
if (Unhex4(chars.begin() + k + 2, &c)) {
ENSURE_BUILDING
k += 5;
}
} else if (k + 3 <= length) {
if (Unhex2(chars.begin() + k + 1, &c)) {
ENSURE_BUILDING
k += 2;
}
}
}
step_14:
/* Step 14. */
if (k > length - 3)
goto step_18;
/* Step 15-17. */
if (Unhex2(chars.begin() + k + 1, &c)) {
ENSURE_BUILDING;
k += 2;
}
step_18:
// Step 5.c.
if (building && !sb.append(c))
return false;
/* Step 19. */
// Step 5.d.
k += 1;
}
@ -460,22 +446,24 @@ Unescape(StringBuffer& sb, const mozilla::Range<const CharT> chars)
#undef ENSURE_BUILDING
}
/* ES5 B.2.2 */
// ES2018 draft rev f83aa38282c2a60c6916ebc410bfdf105a0f6a54
// B.2.1.2 unescape ( string )
static bool
str_unescape(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
/* Step 1. */
// Step 1.
RootedLinearString str(cx, ArgToRootedString(cx, args, 0));
if (!str)
return false;
/* Step 3. */
// Step 3.
StringBuffer sb(cx);
if (str->hasTwoByteChars() && !sb.ensureTwoByteChars())
return false;
// Steps 2, 4-5.
if (str->hasLatin1Chars()) {
AutoCheckCannotGC nogc;
if (!Unescape(sb, str->latin1Range(nogc)))
@ -486,6 +474,7 @@ str_unescape(JSContext* cx, unsigned argc, Value* vp)
return false;
}
// Step 6.
JSLinearString* result;
if (!sb.empty()) {
result = sb.finishString();
@ -3300,7 +3289,7 @@ CodeUnitToString(JSContext* cx, uint16_t ucode, MutableHandleValue rval)
}
char16_t c = char16_t(ucode);
JSString* str = NewStringCopyN<CanGC>(cx, &c, 1);
JSString* str = NewStringCopyNDontDeflate<CanGC>(cx, &c, 1);
if (!str)
return false;
@ -3330,7 +3319,7 @@ ToCodePoint(JSContext* cx, HandleValue code, uint32_t* codePoint)
// String.fromCodePoint, Steps 5.c-d.
if (JS::ToInteger(nextCP) != nextCP || nextCP < 0 || nextCP > unicode::NonBMPMax) {
ToCStringBuf cbuf;
if (char* numStr = NumberToCString(cx, &cbuf, nextCP))
if (const char* numStr = NumberToCString(cx, &cbuf, nextCP))
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_A_CODEPOINT, numStr);
return false;
}
@ -3415,7 +3404,7 @@ js::str_fromCodePoint(JSContext* cx, unsigned argc, Value* vp)
// Steps 1-2 (omitted).
// Step 3.
static_assert(ARGS_LENGTH_MAX < std::numeric_limits<size_t>::max() / 2,
static_assert(ARGS_LENGTH_MAX < std::numeric_limits<decltype(args.length())>::max() / 2,
"|args.length() * 2 + 1| does not overflow");
char16_t* elements = cx->pod_malloc<char16_t>(args.length() * 2 + 1);
if (!elements)
@ -3649,10 +3638,9 @@ js::ValueToSource(JSContext* cx, HandleValue v)
if (v.isPrimitive()) {
/* Special case to preserve negative zero, _contra_ toString. */
if (v.isDouble() && IsNegativeZero(v.toDouble())) {
/* NB: _ucNstr rather than _ucstr to indicate non-terminated. */
static const char16_t js_negzero_ucNstr[] = {'-', '0'};
static const Latin1Char negativeZero[] = {'-', '0'};
return NewStringCopyN<CanGC>(cx, js_negzero_ucNstr, 2);
return NewStringCopyN<CanGC>(cx, negativeZero, mozilla::ArrayLength(negativeZero));
}
return ToString<CanGC>(cx, v);
}