Bug 1026680 part 4 - Cleanup str_escape. r=njn

This commit is contained in:
Jan de Mooij 2014-06-18 11:33:52 +02:00
parent d47d165554
commit d69237f415

View File

@ -118,17 +118,14 @@ str_escape(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
static const char digits[] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
JSLinearString *str = ArgToRootedString(cx, args, 0);
if (!str)
return false;
size_t length = str->length();
uint32_t length = str->length();
const jschar *chars = str->chars();
static const uint8_t shouldPassThrough[256] = {
static const uint8_t shouldPassThrough[128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1, /* !"#$%&'()*+,-./ */
@ -136,23 +133,11 @@ str_escape(JSContext *cx, unsigned argc, Value *vp)
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* @ABCDEFGHIJKLMNO */
1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, /* PQRSTUVWXYZ[\]^_ */
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* `abcdefghijklmno */
1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, /* pqrstuvwxyz{\}~ DEL */
1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, /* pqrstuvwxyz{\}~ DEL */
};
/* In step 7, exactly 69 characters should pass through unencoded. */
#ifdef DEBUG
size_t count = 0;
for (size_t i = 0; i < sizeof(shouldPassThrough); i++) {
if (shouldPassThrough[i]) {
count++;
}
}
JS_ASSERT(count == 69);
#endif
/* Take a first pass and see how big the result string will need to be. */
size_t newlength = length;
uint32_t newlength = length;
for (size_t i = 0; i < length; i++) {
jschar ch = chars[i];
if (ch < 128 && shouldPassThrough[ch])
@ -162,23 +147,19 @@ str_escape(JSContext *cx, unsigned argc, Value *vp)
newlength += (ch < 256) ? 2 : 5;
/*
* This overflow test works because newlength is incremented by at
* most 5 on each iteration.
* newlength is incremented by at most 5 on each iteration, so worst
* case newlength == length * 6. This can't overflow.
*/
if (newlength < length) {
js_ReportAllocationOverflow(cx);
return false;
}
static_assert(JSString::MAX_LENGTH < UINT32_MAX / 6,
"newlength must not overflow");
}
if (newlength >= ~(size_t)0 / sizeof(jschar)) {
js_ReportAllocationOverflow(cx);
return false;
}
jschar *newchars = cx->pod_malloc<jschar>(newlength + 1);
ScopedJSFreePtr<jschar> newchars(cx->pod_malloc<jschar>(newlength + 1));
if (!newchars)
return false;
static const char digits[] = "0123456789ABCDEF";
size_t i, ni;
for (i = 0, ni = 0; i < length; i++) {
jschar ch = chars[i];
@ -200,12 +181,11 @@ str_escape(JSContext *cx, unsigned argc, Value *vp)
JS_ASSERT(ni == newlength);
newchars[newlength] = 0;
JSString *retstr = js_NewString<CanGC>(cx, newchars, newlength);
if (!retstr) {
js_free(newchars);
JSString *retstr = js_NewString<CanGC>(cx, newchars.get(), newlength);
if (!retstr)
return false;
}
newchars.forget();
args.rval().setString(retstr);
return true;
}