| 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 */ |
| 11 #include <stdarg.h> | 11 #include <stdarg.h> |
| 12 #include <stddef.h> | 12 #include <stddef.h> |
| 13 #include <stdio.h> | 13 #include <stdio.h> |
| 14 #include <string.h> | 14 #include <string.h> |
| 15 #include "primpl.h" | 15 #include "primpl.h" |
| 16 #include "prprf.h" | 16 #include "prprf.h" |
| 17 #include "prlong.h" | 17 #include "prlong.h" |
| 18 #include "prlog.h" | 18 #include "prlog.h" |
| 19 #include "prmem.h" | 19 #include "prmem.h" |
| 20 | 20 |
| 21 #ifdef _MSC_VER |
| 22 #define snprintf _snprintf |
| 23 #endif |
| 24 |
| 21 /* | 25 /* |
| 22 ** WARNING: This code may *NOT* call PR_LOG (because PR_LOG calls it) | 26 ** WARNING: This code may *NOT* call PR_LOG (because PR_LOG calls it) |
| 23 */ | 27 */ |
| 24 | 28 |
| 25 /* | 29 /* |
| 26 ** XXX This needs to be internationalized! | 30 ** XXX This needs to be internationalized! |
| 27 */ | 31 */ |
| 28 | 32 |
| 29 typedef struct SprintfStateStr SprintfState; | 33 typedef struct SprintfStateStr SprintfState; |
| 30 | 34 |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 ** Now that we have the number converted without its sign, deal with | 301 ** Now that we have the number converted without its sign, deal with |
| 298 ** the sign and zero padding. | 302 ** the sign and zero padding. |
| 299 */ | 303 */ |
| 300 return fill_n(ss, cvt, digits, width, prec, type, flags); | 304 return fill_n(ss, cvt, digits, width, prec, type, flags); |
| 301 } | 305 } |
| 302 | 306 |
| 303 /* | 307 /* |
| 304 ** Convert a double precision floating point number into its printable | 308 ** Convert a double precision floating point number into its printable |
| 305 ** form. | 309 ** form. |
| 306 ** | 310 ** |
| 307 ** XXX stop using sprintf to convert floating point | 311 ** XXX stop using snprintf to convert floating point |
| 308 */ | 312 */ |
| 309 static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1) | 313 static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1) |
| 310 { | 314 { |
| 311 char fin[20]; | 315 char fin[20]; |
| 312 char fout[300]; | 316 char fout[300]; |
| 313 int amount = fmt1 - fmt0; | 317 int amount = fmt1 - fmt0; |
| 314 | 318 |
| 315 PR_ASSERT((amount > 0) && (amount < sizeof(fin))); | 319 if (amount <= 0 || amount >= sizeof(fin)) { |
| 316 if (amount >= sizeof(fin)) { | 320 » /* Totally bogus % command to snprintf. Just ignore it */ |
| 317 » /* Totally bogus % command to sprintf. Just ignore it */ | |
| 318 return 0; | 321 return 0; |
| 319 } | 322 } |
| 320 memcpy(fin, fmt0, amount); | 323 memcpy(fin, fmt0, amount); |
| 321 fin[amount] = 0; | 324 fin[amount] = 0; |
| 322 | 325 |
| 323 /* Convert floating point using the native sprintf code */ | 326 /* Convert floating point using the native snprintf code */ |
| 324 #ifdef DEBUG | 327 #ifdef DEBUG |
| 325 { | 328 { |
| 326 const char *p = fin; | 329 const char *p = fin; |
| 327 while (*p) { | 330 while (*p) { |
| 328 PR_ASSERT(*p != 'L'); | 331 PR_ASSERT(*p != 'L'); |
| 329 p++; | 332 p++; |
| 330 } | 333 } |
| 331 } | 334 } |
| 332 #endif | 335 #endif |
| 333 sprintf(fout, fin, d); | 336 memset(fout, 0, sizeof(fout)); |
| 334 | 337 snprintf(fout, sizeof(fout), fin, d); |
| 335 /* | 338 /* Explicitly null-terminate fout because on Windows snprintf doesn't |
| 336 ** This assert will catch overflow's of fout, when building with | 339 * append a null-terminator if the buffer is too small. */ |
| 337 ** debugging on. At least this way we can track down the evil piece | 340 fout[sizeof(fout) - 1] = '\0'; |
| 338 ** of calling code and fix it! | |
| 339 */ | |
| 340 PR_ASSERT(strlen(fout) < sizeof(fout)); | |
| 341 | 341 |
| 342 return (*ss->stuff)(ss, fout, strlen(fout)); | 342 return (*ss->stuff)(ss, fout, strlen(fout)); |
| 343 } | 343 } |
| 344 | 344 |
| 345 /* | 345 /* |
| 346 ** Convert a string into its printable form. "width" is the output | 346 ** Convert a string into its printable form. "width" is the output |
| 347 ** width. "prec" is the maximum number of characters of "s" to output, | 347 ** width. "prec" is the maximum number of characters of "s" to output, |
| 348 ** where -1 means until NUL. | 348 ** where -1 means until NUL. |
| 349 */ | 349 */ |
| 350 static int cvt_s(SprintfState *ss, const char *str, int width, int prec, | 350 static int cvt_s(SprintfState *ss, const char *str, int width, int prec, |
| (...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 rv = dosprintf(&ss, fmt, ap); | 1239 rv = dosprintf(&ss, fmt, ap); |
| 1240 if (rv < 0) { | 1240 if (rv < 0) { |
| 1241 if (ss.base) { | 1241 if (ss.base) { |
| 1242 PR_DELETE(ss.base); | 1242 PR_DELETE(ss.base); |
| 1243 } | 1243 } |
| 1244 return 0; | 1244 return 0; |
| 1245 } | 1245 } |
| 1246 return ss.base; | 1246 return ss.base; |
| 1247 } | 1247 } |
| 1248 | 1248 |
| OLD | NEW |