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 |