mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1026680 part 4 - Cleanup str_escape. r=njn
This commit is contained in:
parent
f942104e7b
commit
7de72232c9
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user