Index: nspr/pr/src/io/prprf.c |
diff --git a/nspr/pr/src/io/prprf.c b/nspr/pr/src/io/prprf.c |
index 1a89141548286b2ca37137ce100c922471593ce8..798ea2a448b091e3854cd3a7f3407236336e31dc 100644 |
--- a/nspr/pr/src/io/prprf.c |
+++ b/nspr/pr/src/io/prprf.c |
@@ -37,7 +37,7 @@ struct SprintfStateStr { |
char *base; |
char *cur; |
- PRUint32 maxlen; |
+ PRUint32 maxlen; /* Must not exceed PR_INT32_MAX. */ |
int (*func)(void *arg, const char *sp, PRUint32 len); |
void *arg; |
@@ -697,7 +697,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) |
char *hexp; |
int rv, i; |
struct NumArg* nas = NULL; |
- struct NumArg* nap; |
+ struct NumArg* nap = NULL; |
struct NumArg nasArray[ NAS_DEFAULT_NUM ]; |
char pattern[20]; |
const char* dolPt = NULL; /* in "%4$.2f", dolPt will point to . */ |
@@ -1060,6 +1060,13 @@ static int FuncStuff(SprintfState *ss, const char *sp, PRUint32 len) |
{ |
int rv; |
+ /* |
+ ** We will add len to ss->maxlen at the end of the function. First check |
+ ** if ss->maxlen + len would overflow or be greater than PR_INT32_MAX. |
+ */ |
+ if (PR_UINT32_MAX - ss->maxlen < len || ss->maxlen + len > PR_INT32_MAX) { |
+ return -1; |
+ } |
rv = (*ss->func)(ss->arg, sp, len); |
if (rv < 0) { |
return rv; |
@@ -1105,9 +1112,21 @@ static int GrowStuff(SprintfState *ss, const char *sp, PRUint32 len) |
PRUint32 newlen; |
off = ss->cur - ss->base; |
+ if (PR_UINT32_MAX - len < off) { |
+ /* off + len would be too big. */ |
+ return -1; |
+ } |
if (off + len >= ss->maxlen) { |
/* Grow the buffer */ |
- newlen = ss->maxlen + ((len > 32) ? len : 32); |
+ PRUint32 increment = (len > 32) ? len : 32; |
+ if (PR_UINT32_MAX - ss->maxlen < increment) { |
+ /* ss->maxlen + increment would overflow. */ |
+ return -1; |
+ } |
+ newlen = ss->maxlen + increment; |
+ if (newlen > PR_INT32_MAX) { |
+ return -1; |
+ } |
if (ss->base) { |
newbase = (char*) PR_REALLOC(ss->base, newlen); |
} else { |
@@ -1210,8 +1229,8 @@ PR_IMPLEMENT(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen,const char *fmt, |
SprintfState ss; |
PRUint32 n; |
- PR_ASSERT((PRInt32)outlen > 0); |
- if ((PRInt32)outlen <= 0) { |
+ PR_ASSERT(outlen != 0 && outlen <= PR_INT32_MAX); |
+ if (outlen == 0 || outlen > PR_INT32_MAX) { |
return 0; |
} |
@@ -1247,7 +1266,10 @@ PR_IMPLEMENT(char *) PR_vsprintf_append(char *last, const char *fmt, va_list ap) |
ss.stuff = GrowStuff; |
if (last) { |
- int lastlen = strlen(last); |
+ size_t lastlen = strlen(last); |
+ if (lastlen > PR_INT32_MAX) { |
+ return 0; |
+ } |
ss.base = last; |
ss.cur = last + lastlen; |
ss.maxlen = lastlen; |