Bug 622060 - Fix off-by-one error in num_toLocaleString (r=bz)
authorBill McCloskey <wmccloskey@mozilla.com>
Fri, 31 Dec 2010 11:30:24 -0800
changeset 59978 e0fc487c23f492e8f9a530ca1188627575063c02
parent 59977 96482f2ef48e691e1ab8cf082dbdb7b0030b0b9f
child 59979 673ae0e2f656e20dd858a59a14be50f68201d64c
push id17820
push usercleary@mozilla.com
push dateTue, 04 Jan 2011 21:40:57 +0000
treeherdermozilla-central@969691cfe40e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs622060
milestone2.0b9pre
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
Bug 622060 - Fix off-by-one error in num_toLocaleString (r=bz)
js/src/jsnum.cpp
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -764,19 +764,19 @@ num_toLocaleString(JSContext *cx, uintN 
     if (!digits)
         return JS_TRUE;
 
     rt = cx->runtime;
     thousandsLength = strlen(rt->thousandsSeparator);
     decimalLength = strlen(rt->decimalSeparator);
 
     /* Figure out how long resulting string will be. */
-    buflen = digits + (*nint ? strlen(nint + 1) : 0);
+    buflen = strlen(num);
     if (*nint == '.')
-        buflen += decimalLength;
+        buflen += decimalLength - 1; /* -1 to account for existing '.' */
 
     numGrouping = tmpGroup = rt->numGrouping;
     remainder = digits;
     if (*num == '-')
         remainder--;
 
     while (*tmpGroup != CHAR_MAX && *tmpGroup != '\0') {
         if (*tmpGroup >= remainder)
@@ -796,33 +796,40 @@ num_toLocaleString(JSContext *cx, uintN 
 
     buf = (char *)cx->malloc(buflen + 1);
     if (!buf)
         return JS_FALSE;
 
     tmpDest = buf;
     tmpSrc = num;
 
-    while (*tmpSrc == '-' || remainder--)
+    while (*tmpSrc == '-' || remainder--) {
+        JS_ASSERT(tmpDest - buf < buflen);
         *tmpDest++ = *tmpSrc++;
+    }
     while (tmpSrc < end) {
+        JS_ASSERT(tmpDest - buf + ptrdiff_t(thousandsLength) <= buflen);
         strcpy(tmpDest, rt->thousandsSeparator);
         tmpDest += thousandsLength;
+        JS_ASSERT(tmpDest - buf + *tmpGroup <= buflen);
         memcpy(tmpDest, tmpSrc, *tmpGroup);
         tmpDest += *tmpGroup;
         tmpSrc += *tmpGroup;
         if (--nrepeat < 0)
             tmpGroup--;
     }
 
     if (*nint == '.') {
+        JS_ASSERT(tmpDest - buf + ptrdiff_t(decimalLength) <= buflen);
         strcpy(tmpDest, rt->decimalSeparator);
         tmpDest += decimalLength;
+        JS_ASSERT(tmpDest - buf + ptrdiff_t(strlen(nint + 1)) <= buflen);
         strcpy(tmpDest, nint + 1);
     } else {
+        JS_ASSERT(tmpDest - buf + ptrdiff_t(strlen(nint)) <= buflen);
         strcpy(tmpDest, nint);
     }
 
     if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode) {
         JSBool ok = cx->localeCallbacks->localeToUnicode(cx, buf, Jsvalify(vp));
         cx->free(buf);
         return ok;
     }