зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
d69330ead0
Коммит
b2b634e5b6
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче