| OLD | NEW | 
|     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | 
|     2 /* This Source Code Form is subject to the terms of the Mozilla Public |     2 /* This Source Code Form is subject to the terms of the Mozilla Public | 
|     3  * License, v. 2.0. If a copy of the MPL was not distributed with this |     3  * License, v. 2.0. If a copy of the MPL was not distributed with this | 
|     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 
|     5  |     5  | 
|     6 /* |     6 /* | 
|     7 ** Portable safe sprintf code. |     7 ** Portable safe sprintf code. | 
|     8 ** |     8 ** | 
|     9 ** Author: Kipp E.B. Hickman |     9 ** Author: Kipp E.B. Hickman | 
|    10 */ |    10 */ | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|    30 ** XXX This needs to be internationalized! |    30 ** XXX This needs to be internationalized! | 
|    31 */ |    31 */ | 
|    32  |    32  | 
|    33 typedef struct SprintfStateStr SprintfState; |    33 typedef struct SprintfStateStr SprintfState; | 
|    34  |    34  | 
|    35 struct SprintfStateStr { |    35 struct SprintfStateStr { | 
|    36     int (*stuff)(SprintfState *ss, const char *sp, PRUint32 len); |    36     int (*stuff)(SprintfState *ss, const char *sp, PRUint32 len); | 
|    37  |    37  | 
|    38     char *base; |    38     char *base; | 
|    39     char *cur; |    39     char *cur; | 
|    40     PRUint32 maxlen; |    40     PRUint32 maxlen;  /* Must not exceed PR_INT32_MAX. */ | 
|    41  |    41  | 
|    42     int (*func)(void *arg, const char *sp, PRUint32 len); |    42     int (*func)(void *arg, const char *sp, PRUint32 len); | 
|    43     void *arg; |    43     void *arg; | 
|    44 }; |    44 }; | 
|    45  |    45  | 
|    46 /* |    46 /* | 
|    47 ** Numbered Argument |    47 ** Numbered Argument | 
|    48 */ |    48 */ | 
|    49 struct NumArg { |    49 struct NumArg { | 
|    50     int type;           /* type of the numbered argument    */ |    50     int type;           /* type of the numbered argument    */ | 
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   690 #ifdef WIN32 |   690 #ifdef WIN32 | 
|   691         const WCHAR *ws; |   691         const WCHAR *ws; | 
|   692 #endif |   692 #endif | 
|   693     } u; |   693     } u; | 
|   694     const char *fmt0; |   694     const char *fmt0; | 
|   695     static char *hex = "0123456789abcdef"; |   695     static char *hex = "0123456789abcdef"; | 
|   696     static char *HEX = "0123456789ABCDEF"; |   696     static char *HEX = "0123456789ABCDEF"; | 
|   697     char *hexp; |   697     char *hexp; | 
|   698     int rv, i; |   698     int rv, i; | 
|   699     struct NumArg* nas = NULL; |   699     struct NumArg* nas = NULL; | 
|   700     struct NumArg* nap; |   700     struct NumArg* nap = NULL; | 
|   701     struct NumArg  nasArray[ NAS_DEFAULT_NUM ]; |   701     struct NumArg  nasArray[ NAS_DEFAULT_NUM ]; | 
|   702     char  pattern[20]; |   702     char  pattern[20]; | 
|   703     const char* dolPt = NULL;  /* in "%4$.2f", dolPt will point to . */ |   703     const char* dolPt = NULL;  /* in "%4$.2f", dolPt will point to . */ | 
|   704 #ifdef WIN32 |   704 #ifdef WIN32 | 
|   705     char *pBuf = NULL; |   705     char *pBuf = NULL; | 
|   706 #endif |   706 #endif | 
|   707  |   707  | 
|   708     /* |   708     /* | 
|   709     ** build an argument array, IF the fmt is numbered argument |   709     ** build an argument array, IF the fmt is numbered argument | 
|   710     ** list style, to contain the Numbered Argument list pointers |   710     ** list style, to contain the Numbered Argument list pointers | 
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1053  |  1053  | 
|  1054     return rv; |  1054     return rv; | 
|  1055 } |  1055 } | 
|  1056  |  1056  | 
|  1057 /************************************************************************/ |  1057 /************************************************************************/ | 
|  1058  |  1058  | 
|  1059 static int FuncStuff(SprintfState *ss, const char *sp, PRUint32 len) |  1059 static int FuncStuff(SprintfState *ss, const char *sp, PRUint32 len) | 
|  1060 { |  1060 { | 
|  1061     int rv; |  1061     int rv; | 
|  1062  |  1062  | 
 |  1063     /* | 
 |  1064     ** We will add len to ss->maxlen at the end of the function. First check | 
 |  1065     ** if ss->maxlen + len would overflow or be greater than PR_INT32_MAX. | 
 |  1066     */ | 
 |  1067     if (PR_UINT32_MAX - ss->maxlen < len || ss->maxlen + len > PR_INT32_MAX) { | 
 |  1068         return -1; | 
 |  1069     } | 
|  1063     rv = (*ss->func)(ss->arg, sp, len); |  1070     rv = (*ss->func)(ss->arg, sp, len); | 
|  1064     if (rv < 0) { |  1071     if (rv < 0) { | 
|  1065         return rv; |  1072         return rv; | 
|  1066     } |  1073     } | 
|  1067     ss->maxlen += len; |  1074     ss->maxlen += len; | 
|  1068     return 0; |  1075     return 0; | 
|  1069 } |  1076 } | 
|  1070  |  1077  | 
|  1071 PR_IMPLEMENT(PRUint32) PR_sxprintf(PRStuffFunc func, void *arg,  |  1078 PR_IMPLEMENT(PRUint32) PR_sxprintf(PRStuffFunc func, void *arg,  | 
|  1072                                  const char *fmt, ...) |  1079                                  const char *fmt, ...) | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|  1098 ** Stuff routine that automatically grows the malloc'd output buffer |  1105 ** Stuff routine that automatically grows the malloc'd output buffer | 
|  1099 ** before it overflows. |  1106 ** before it overflows. | 
|  1100 */ |  1107 */ | 
|  1101 static int GrowStuff(SprintfState *ss, const char *sp, PRUint32 len) |  1108 static int GrowStuff(SprintfState *ss, const char *sp, PRUint32 len) | 
|  1102 { |  1109 { | 
|  1103     ptrdiff_t off; |  1110     ptrdiff_t off; | 
|  1104     char *newbase; |  1111     char *newbase; | 
|  1105     PRUint32 newlen; |  1112     PRUint32 newlen; | 
|  1106  |  1113  | 
|  1107     off = ss->cur - ss->base; |  1114     off = ss->cur - ss->base; | 
 |  1115     if (PR_UINT32_MAX - len < off) { | 
 |  1116         /* off + len would be too big. */ | 
 |  1117         return -1; | 
 |  1118     } | 
|  1108     if (off + len >= ss->maxlen) { |  1119     if (off + len >= ss->maxlen) { | 
|  1109         /* Grow the buffer */ |  1120         /* Grow the buffer */ | 
|  1110 »       newlen = ss->maxlen + ((len > 32) ? len : 32); |  1121 »       PRUint32 increment = (len > 32) ? len : 32; | 
 |  1122 »       if (PR_UINT32_MAX - ss->maxlen < increment) { | 
 |  1123 »           /* ss->maxlen + increment would overflow. */ | 
 |  1124 »           return -1; | 
 |  1125 »       } | 
 |  1126 »       newlen = ss->maxlen + increment; | 
 |  1127 »       if (newlen > PR_INT32_MAX) { | 
 |  1128 »           return -1; | 
 |  1129 »       } | 
|  1111         if (ss->base) { |  1130         if (ss->base) { | 
|  1112             newbase = (char*) PR_REALLOC(ss->base, newlen); |  1131             newbase = (char*) PR_REALLOC(ss->base, newlen); | 
|  1113         } else { |  1132         } else { | 
|  1114             newbase = (char*) PR_MALLOC(newlen); |  1133             newbase = (char*) PR_MALLOC(newlen); | 
|  1115         } |  1134         } | 
|  1116         if (!newbase) { |  1135         if (!newbase) { | 
|  1117             /* Ran out of memory */ |  1136             /* Ran out of memory */ | 
|  1118             return -1; |  1137             return -1; | 
|  1119         } |  1138         } | 
|  1120         ss->base = newbase; |  1139         ss->base = newbase; | 
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1203     va_end(ap); |  1222     va_end(ap); | 
|  1204     return rv; |  1223     return rv; | 
|  1205 } |  1224 } | 
|  1206  |  1225  | 
|  1207 PR_IMPLEMENT(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen,const char *fmt, |  1226 PR_IMPLEMENT(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen,const char *fmt, | 
|  1208                                   va_list ap) |  1227                                   va_list ap) | 
|  1209 { |  1228 { | 
|  1210     SprintfState ss; |  1229     SprintfState ss; | 
|  1211     PRUint32 n; |  1230     PRUint32 n; | 
|  1212  |  1231  | 
|  1213     PR_ASSERT((PRInt32)outlen > 0); |  1232     PR_ASSERT(outlen != 0 && outlen <= PR_INT32_MAX); | 
|  1214     if ((PRInt32)outlen <= 0) { |  1233     if (outlen == 0 || outlen > PR_INT32_MAX) { | 
|  1215         return 0; |  1234         return 0; | 
|  1216     } |  1235     } | 
|  1217  |  1236  | 
|  1218     ss.stuff = LimitStuff; |  1237     ss.stuff = LimitStuff; | 
|  1219     ss.base = out; |  1238     ss.base = out; | 
|  1220     ss.cur = out; |  1239     ss.cur = out; | 
|  1221     ss.maxlen = outlen; |  1240     ss.maxlen = outlen; | 
|  1222     (void) dosprintf(&ss, fmt, ap); |  1241     (void) dosprintf(&ss, fmt, ap); | 
|  1223  |  1242  | 
|  1224     /* If we added chars, and we didn't append a null, do it now. */ |  1243     /* If we added chars, and we didn't append a null, do it now. */ | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  1240     return rv; |  1259     return rv; | 
|  1241 } |  1260 } | 
|  1242  |  1261  | 
|  1243 PR_IMPLEMENT(char *) PR_vsprintf_append(char *last, const char *fmt, va_list ap) |  1262 PR_IMPLEMENT(char *) PR_vsprintf_append(char *last, const char *fmt, va_list ap) | 
|  1244 { |  1263 { | 
|  1245     SprintfState ss; |  1264     SprintfState ss; | 
|  1246     int rv; |  1265     int rv; | 
|  1247  |  1266  | 
|  1248     ss.stuff = GrowStuff; |  1267     ss.stuff = GrowStuff; | 
|  1249     if (last) { |  1268     if (last) { | 
|  1250 »       int lastlen = strlen(last); |  1269 »       size_t lastlen = strlen(last); | 
 |  1270 »       if (lastlen > PR_INT32_MAX) { | 
 |  1271 »           return 0; | 
 |  1272 »       } | 
|  1251         ss.base = last; |  1273         ss.base = last; | 
|  1252         ss.cur = last + lastlen; |  1274         ss.cur = last + lastlen; | 
|  1253         ss.maxlen = lastlen; |  1275         ss.maxlen = lastlen; | 
|  1254     } else { |  1276     } else { | 
|  1255         ss.base = 0; |  1277         ss.base = 0; | 
|  1256         ss.cur = 0; |  1278         ss.cur = 0; | 
|  1257         ss.maxlen = 0; |  1279         ss.maxlen = 0; | 
|  1258     } |  1280     } | 
|  1259     rv = dosprintf(&ss, fmt, ap); |  1281     rv = dosprintf(&ss, fmt, ap); | 
|  1260     if (rv < 0) { |  1282     if (rv < 0) { | 
|  1261         if (ss.base) { |  1283         if (ss.base) { | 
|  1262             PR_DELETE(ss.base); |  1284             PR_DELETE(ss.base); | 
|  1263         } |  1285         } | 
|  1264         return 0; |  1286         return 0; | 
|  1265     } |  1287     } | 
|  1266     return ss.base; |  1288     return ss.base; | 
|  1267 } |  1289 } | 
|  1268  |  1290  | 
| OLD | NEW |