Bug 1019838 - Fix various leaks in dosprintf (in jsprf.cpp and nsTextFormatter.cpp). r=jwalden

--HG--
extra : rebase_source : d0dff2bfa1590db460729f412e92c9ce9dfe1869
This commit is contained in:
Gokcehan Kara 2014-09-08 17:26:49 -07:00
parent 39f1e17105
commit 2aa0f35e50

View File

@ -12,6 +12,8 @@
#include "jsprf.h"
#include "mozilla/Vector.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@ -56,7 +58,7 @@ struct NumArgState
va_list ap; // point to the corresponding position on ap
};
const size_t NAS_DEFAULT_NUM = 20; // default number of NumberedArgumentState array
typedef Vector<NumArgState, 20, SystemAllocPolicy> NumArgStateVector;
#define TYPE_INT16 0
@ -375,20 +377,18 @@ cvt_s(SprintfState *ss, const Char *s, int width, int prec, int flags)
* fmp = "%4$i, %2$d, %3s, %1d";
* the number must start from 1, and no gap among them
*/
static NumArgState *
BuildArgArray(const char *fmt, va_list ap, int *rv, NumArgState *nasArray)
static bool
BuildArgArray(const char *fmt, va_list ap, NumArgStateVector& nas)
{
size_t number = 0, cn = 0, i;
const char *p;
char c;
NumArgState *nas;
// First pass:
// Detemine how many legal % I have got, then allocate space.
p = fmt;
*rv = 0;
i = 0;
while ((c = *p++) != 0) {
if (c != '%')
@ -399,16 +399,12 @@ BuildArgArray(const char *fmt, va_list ap, int *rv, NumArgState *nasArray)
while (c != 0) {
if (c > '9' || c < '0') {
if (c == '$') { // numbered argument case
if (i > 0) {
*rv = -1;
return nullptr;
}
if (i > 0)
return false;
number++;
} else { // non-numbered argument case
if (number > 0) {
*rv = -1;
return nullptr;
}
if (number > 0)
return false;
i = 1;
}
break;
@ -419,17 +415,10 @@ BuildArgArray(const char *fmt, va_list ap, int *rv, NumArgState *nasArray)
}
if (number == 0)
return nullptr;
return true;
if (number > NAS_DEFAULT_NUM) {
nas = (NumArgState *) js_malloc(number * sizeof(NumArgState));
if (!nas) {
*rv = -1;
return nullptr;
}
} else {
nas = nasArray;
}
if (!nas.growByUninitialized(number))
return false;
for (i = 0; i < number; i++)
nas[i].type = TYPE_UNKNOWN;
@ -452,10 +441,8 @@ BuildArgArray(const char *fmt, va_list ap, int *rv, NumArgState *nasArray)
c = *p++;
}
if (!c || cn < 1 || cn > number) {
*rv = -1;
break;
}
if (!c || cn < 1 || cn > number)
return false;
// nas[cn] starts from 0, and make sure nas[cn].type is not assigned.
cn--;
@ -467,8 +454,7 @@ BuildArgArray(const char *fmt, va_list ap, int *rv, NumArgState *nasArray)
// width
if (c == '*') {
// not supported feature, for the argument is not numbered
*rv = -1;
break;
return false;
}
while ((c >= '0') && (c <= '9')) {
@ -480,8 +466,7 @@ BuildArgArray(const char *fmt, va_list ap, int *rv, NumArgState *nasArray)
c = *p++;
if (c == '*') {
// not supported feature, for the argument is not numbered
*rv = -1;
break;
return false;
}
while ((c >= '0') && (c <= '9')) {
@ -561,22 +546,14 @@ BuildArgArray(const char *fmt, va_list ap, int *rv, NumArgState *nasArray)
}
// get a legal para.
if (nas[cn].type == TYPE_UNKNOWN) {
*rv = -1;
break;
}
if (nas[cn].type == TYPE_UNKNOWN)
return false;
}
// Third pass:
// Fill nas[].ap.
if (*rv < 0) {
if (nas != nasArray)
js_free(nas);
return nullptr;
}
cn = 0;
while (cn < number) {
if (nas[cn].type == TYPE_UNKNOWN) {
@ -600,18 +577,13 @@ BuildArgArray(const char *fmt, va_list ap, int *rv, NumArgState *nasArray)
case TYPE_INTSTR: (void) va_arg(ap, int*); break;
case TYPE_DOUBLE: (void) va_arg(ap, double); break;
default:
if (nas != nasArray)
js_free(nas);
*rv = -1;
return nullptr;
default: return false;
}
cn++;
}
return nas;
return true;
}
/*
@ -638,16 +610,14 @@ dosprintf(SprintfState *ss, const char *fmt, va_list ap)
static const char HEX[] = "0123456789ABCDEF";
const char *hexp;
int rv, i;
NumArgState *nas = nullptr;
NumArgState nasArray[NAS_DEFAULT_NUM];
char pattern[20];
const char *dolPt = nullptr; // in "%4$.2f", dolPt will point to '.'
// Build an argument array, IF the fmt is numbered argument
// list style, to contain the Numbered Argument list pointers.
nas = BuildArgArray(fmt, ap, &rv, nasArray);
if (rv < 0) {
NumArgStateVector nas;
if (!BuildArgArray(fmt, ap, nas)) {
// the fmt contains error Numbered Argument format, jliu@netscape.com
JS_ASSERT(0);
return rv;
@ -676,7 +646,7 @@ dosprintf(SprintfState *ss, const char *fmt, va_list ap)
continue;
}
if (nas != nullptr) {
if (!nas.empty()) {
// the fmt contains the Numbered Arguments feature
i = 0;
while (c && c != '$') { // should improve error check later
@ -684,13 +654,10 @@ dosprintf(SprintfState *ss, const char *fmt, va_list ap)
c = *fmt++;
}
if (nas[i-1].type == TYPE_UNKNOWN) {
if (nas && nas != nasArray)
js_free(nas);
if (nas[i - 1].type == TYPE_UNKNOWN)
return -1;
}
ap = nas[i-1].ap;
ap = nas[i - 1].ap;
dolPt = fmt;
c = *fmt++;
}
@ -846,7 +813,7 @@ dosprintf(SprintfState *ss, const char *fmt, va_list ap)
case 'f':
case 'g':
u.d = va_arg(ap, double);
if (nas != nullptr) {
if (!nas.empty()) {
i = fmt - dolPt;
if (i < int(sizeof(pattern))) {
pattern[0] = '%';
@ -953,9 +920,6 @@ dosprintf(SprintfState *ss, const char *fmt, va_list ap)
// Stuff trailing NUL
rv = (*ss->stuff)(ss, "\0", 1);
if (nas && nas != nasArray)
js_free(nas);
return rv;
}