1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "mozilla/Assertions.h"
8 #include "mozilla/IntegerPrintfMacros.h" // this must pick up <stdint.h>
9 #include "mozilla/Sprintf.h"
10
11 #include <stddef.h>
12 #include <stdio.h>
13 #include <string.h>
14
15 /* Output array and poisoning method shared by all tests. */
16 static char gOutput[32];
17
PoisonOutput()18 static void PoisonOutput() { memset(gOutput, 0xDA, sizeof(gOutput)); }
19
20 /*
21 * The fprintf macros for signed integers are:
22 *
23 * PRIdN PRIdLEASTN PRIdFASTN PRIdMAX PRIdPTR
24 * PRIiN PRIiLEASTN PRIiFASTN PRIiMAX PRIiPTR
25 *
26 * In these names N is the width of the type as described in C99 7.18.1.
27 */
28
TestPrintSigned8()29 static void TestPrintSigned8() {
30 PoisonOutput();
31 SprintfLiteral(gOutput, "%" PRId8, int8_t(-17));
32 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-17"));
33
34 PoisonOutput();
35 SprintfLiteral(gOutput, "%" PRIi8, int8_t(42));
36 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
37 }
38
TestPrintSigned16()39 static void TestPrintSigned16() {
40 PoisonOutput();
41 SprintfLiteral(gOutput, "%" PRId16, int16_t(-289));
42 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-289"));
43
44 PoisonOutput();
45 SprintfLiteral(gOutput, "%" PRIi16, int16_t(728));
46 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "728"));
47 }
48
TestPrintSigned32()49 static void TestPrintSigned32() {
50 PoisonOutput();
51 SprintfLiteral(gOutput, "%" PRId32, int32_t(-342178));
52 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-342178"));
53
54 PoisonOutput();
55 SprintfLiteral(gOutput, "%" PRIi32, int32_t(5719283));
56 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "5719283"));
57 }
58
TestPrintSigned64()59 static void TestPrintSigned64() {
60 PoisonOutput();
61 SprintfLiteral(gOutput, "%" PRId64, int64_t(-INT64_C(432157943248732)));
62 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-432157943248732"));
63
64 PoisonOutput();
65 SprintfLiteral(gOutput, "%" PRIi64, int64_t(INT64_C(325719232983)));
66 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
67 }
68
TestPrintSignedN()69 static void TestPrintSignedN() {
70 TestPrintSigned8();
71 TestPrintSigned16();
72 TestPrintSigned32();
73 TestPrintSigned64();
74 }
75
TestPrintSignedLeast8()76 static void TestPrintSignedLeast8() {
77 PoisonOutput();
78 SprintfLiteral(gOutput, "%" PRIdLEAST8, int_least8_t(-17));
79 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-17"));
80
81 PoisonOutput();
82 SprintfLiteral(gOutput, "%" PRIiLEAST8, int_least8_t(42));
83 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
84 }
85
TestPrintSignedLeast16()86 static void TestPrintSignedLeast16() {
87 PoisonOutput();
88 SprintfLiteral(gOutput, "%" PRIdLEAST16, int_least16_t(-289));
89 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-289"));
90
91 PoisonOutput();
92 SprintfLiteral(gOutput, "%" PRIiLEAST16, int_least16_t(728));
93 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "728"));
94 }
95
TestPrintSignedLeast32()96 static void TestPrintSignedLeast32() {
97 PoisonOutput();
98 SprintfLiteral(gOutput, "%" PRIdLEAST32, int_least32_t(-342178));
99 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-342178"));
100
101 PoisonOutput();
102 SprintfLiteral(gOutput, "%" PRIiLEAST32, int_least32_t(5719283));
103 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "5719283"));
104 }
105
TestPrintSignedLeast64()106 static void TestPrintSignedLeast64() {
107 PoisonOutput();
108 SprintfLiteral(gOutput, "%" PRIdLEAST64,
109 int_least64_t(-INT64_C(432157943248732)));
110 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-432157943248732"));
111
112 PoisonOutput();
113 SprintfLiteral(gOutput, "%" PRIiLEAST64,
114 int_least64_t(INT64_C(325719232983)));
115 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
116 }
117
TestPrintSignedLeastN()118 static void TestPrintSignedLeastN() {
119 TestPrintSignedLeast8();
120 TestPrintSignedLeast16();
121 TestPrintSignedLeast32();
122 TestPrintSignedLeast64();
123 }
124
TestPrintSignedFast8()125 static void TestPrintSignedFast8() {
126 PoisonOutput();
127 SprintfLiteral(gOutput, "%" PRIdFAST8, int_fast8_t(-17));
128 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-17"));
129
130 PoisonOutput();
131 SprintfLiteral(gOutput, "%" PRIiFAST8, int_fast8_t(42));
132 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
133 }
134
TestPrintSignedFast16()135 static void TestPrintSignedFast16() {
136 PoisonOutput();
137 SprintfLiteral(gOutput, "%" PRIdFAST16, int_fast16_t(-289));
138 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-289"));
139
140 PoisonOutput();
141 SprintfLiteral(gOutput, "%" PRIiFAST16, int_fast16_t(728));
142 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "728"));
143 }
144
TestPrintSignedFast32()145 static void TestPrintSignedFast32() {
146 PoisonOutput();
147 SprintfLiteral(gOutput, "%" PRIdFAST32, int_fast32_t(-342178));
148 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-342178"));
149
150 PoisonOutput();
151 SprintfLiteral(gOutput, "%" PRIiFAST32, int_fast32_t(5719283));
152 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "5719283"));
153 }
154
TestPrintSignedFast64()155 static void TestPrintSignedFast64() {
156 PoisonOutput();
157 SprintfLiteral(gOutput, "%" PRIdFAST64,
158 int_fast64_t(-INT64_C(432157943248732)));
159 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-432157943248732"));
160
161 PoisonOutput();
162 SprintfLiteral(gOutput, "%" PRIiFAST64, int_fast64_t(INT64_C(325719232983)));
163 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
164 }
165
TestPrintSignedFastN()166 static void TestPrintSignedFastN() {
167 TestPrintSignedFast8();
168 TestPrintSignedFast16();
169 TestPrintSignedFast32();
170 TestPrintSignedFast64();
171 }
172
TestPrintSignedMax()173 static void TestPrintSignedMax() {
174 PoisonOutput();
175 SprintfLiteral(gOutput, "%" PRIdMAX, intmax_t(-INTMAX_C(432157943248732)));
176 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-432157943248732"));
177
178 PoisonOutput();
179 SprintfLiteral(gOutput, "%" PRIiMAX, intmax_t(INTMAX_C(325719232983)));
180 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
181 }
182
TestPrintSignedPtr()183 static void TestPrintSignedPtr() {
184 PoisonOutput();
185 SprintfLiteral(gOutput, "%" PRIdPTR,
186 intptr_t(reinterpret_cast<void*>(12345678)));
187 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "12345678"));
188
189 PoisonOutput();
190 SprintfLiteral(gOutput, "%" PRIiPTR,
191 intptr_t(reinterpret_cast<void*>(87654321)));
192 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "87654321"));
193 }
194
TestPrintSigned()195 static void TestPrintSigned() {
196 TestPrintSignedN();
197 TestPrintSignedLeastN();
198 TestPrintSignedFastN();
199 TestPrintSignedMax();
200 TestPrintSignedPtr();
201 }
202
203 /*
204 * The fprintf macros for unsigned integers are:
205 *
206 * PRIoN PRIoLEASTN PRIoFASTN PRIoMAX PRIoPTR
207 * PRIuN PRIuLEASTN PRIuFASTN PRIuMAX PRIuPTR
208 * PRIxN PRIxLEASTN PRIxFASTN PRIxMAX PRIxPTR
209 * PRIXN PRIXLEASTN PRIXFASTN PRIXMAX PRIXPTR
210 *
211 * In these names N is the width of the type as described in C99 7.18.1.
212 */
213
TestPrintUnsigned8()214 static void TestPrintUnsigned8() {
215 PoisonOutput();
216 SprintfLiteral(gOutput, "%" PRIo8, uint8_t(042));
217 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
218
219 PoisonOutput();
220 SprintfLiteral(gOutput, "%" PRIu8, uint8_t(17));
221 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17"));
222
223 PoisonOutput();
224 SprintfLiteral(gOutput, "%" PRIx8, uint8_t(0x2a));
225 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a"));
226
227 PoisonOutput();
228 SprintfLiteral(gOutput, "%" PRIX8, uint8_t(0xCD));
229 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CD"));
230 }
231
TestPrintUnsigned16()232 static void TestPrintUnsigned16() {
233 PoisonOutput();
234 SprintfLiteral(gOutput, "%" PRIo16, uint16_t(04242));
235 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4242"));
236
237 PoisonOutput();
238 SprintfLiteral(gOutput, "%" PRIu16, uint16_t(1717));
239 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "1717"));
240
241 PoisonOutput();
242 SprintfLiteral(gOutput, "%" PRIx16, uint16_t(0x2a2a));
243 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a"));
244
245 PoisonOutput();
246 SprintfLiteral(gOutput, "%" PRIX16, uint16_t(0xCDCD));
247 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCD"));
248 }
249
TestPrintUnsigned32()250 static void TestPrintUnsigned32() {
251 PoisonOutput();
252 SprintfLiteral(gOutput, "%" PRIo32, uint32_t(0424242));
253 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242"));
254
255 PoisonOutput();
256 SprintfLiteral(gOutput, "%" PRIu32, uint32_t(171717));
257 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "171717"));
258
259 PoisonOutput();
260 SprintfLiteral(gOutput, "%" PRIx32, uint32_t(0x2a2a2a));
261 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a"));
262
263 PoisonOutput();
264 SprintfLiteral(gOutput, "%" PRIX32, uint32_t(0xCDCDCD));
265 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCD"));
266 }
267
TestPrintUnsigned64()268 static void TestPrintUnsigned64() {
269 PoisonOutput();
270 SprintfLiteral(gOutput, "%" PRIo64, uint64_t(UINT64_C(0424242424242)));
271 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242424242"));
272
273 PoisonOutput();
274 SprintfLiteral(gOutput, "%" PRIu64, uint64_t(UINT64_C(17171717171717171717)));
275 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17171717171717171717"));
276
277 PoisonOutput();
278 SprintfLiteral(gOutput, "%" PRIx64, uint64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
279 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a2a2a2a2a"));
280
281 PoisonOutput();
282 SprintfLiteral(gOutput, "%" PRIX64, uint64_t(UINT64_C(0xCDCDCDCDCDCD)));
283 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCDCDCDCD"));
284 }
285
TestPrintUnsignedN()286 static void TestPrintUnsignedN() {
287 TestPrintUnsigned8();
288 TestPrintUnsigned16();
289 TestPrintUnsigned32();
290 TestPrintUnsigned64();
291 }
292
TestPrintUnsignedLeast8()293 static void TestPrintUnsignedLeast8() {
294 PoisonOutput();
295 SprintfLiteral(gOutput, "%" PRIoLEAST8, uint_least8_t(042));
296 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
297
298 PoisonOutput();
299 SprintfLiteral(gOutput, "%" PRIuLEAST8, uint_least8_t(17));
300 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17"));
301
302 PoisonOutput();
303 SprintfLiteral(gOutput, "%" PRIxLEAST8, uint_least8_t(0x2a));
304 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a"));
305
306 PoisonOutput();
307 SprintfLiteral(gOutput, "%" PRIXLEAST8, uint_least8_t(0xCD));
308 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CD"));
309 }
310
TestPrintUnsignedLeast16()311 static void TestPrintUnsignedLeast16() {
312 PoisonOutput();
313 SprintfLiteral(gOutput, "%" PRIoLEAST16, uint_least16_t(04242));
314 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4242"));
315
316 PoisonOutput();
317 SprintfLiteral(gOutput, "%" PRIuLEAST16, uint_least16_t(1717));
318 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "1717"));
319
320 PoisonOutput();
321 SprintfLiteral(gOutput, "%" PRIxLEAST16, uint_least16_t(0x2a2a));
322 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a"));
323
324 PoisonOutput();
325 SprintfLiteral(gOutput, "%" PRIXLEAST16, uint_least16_t(0xCDCD));
326 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCD"));
327 }
328
TestPrintUnsignedLeast32()329 static void TestPrintUnsignedLeast32() {
330 PoisonOutput();
331 SprintfLiteral(gOutput, "%" PRIoLEAST32, uint_least32_t(0424242));
332 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242"));
333
334 PoisonOutput();
335 SprintfLiteral(gOutput, "%" PRIuLEAST32, uint_least32_t(171717));
336 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "171717"));
337
338 PoisonOutput();
339 SprintfLiteral(gOutput, "%" PRIxLEAST32, uint_least32_t(0x2a2a2a));
340 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a"));
341
342 PoisonOutput();
343 SprintfLiteral(gOutput, "%" PRIXLEAST32, uint_least32_t(0xCDCDCD));
344 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCD"));
345 }
346
TestPrintUnsignedLeast64()347 static void TestPrintUnsignedLeast64() {
348 PoisonOutput();
349 SprintfLiteral(gOutput, "%" PRIoLEAST64,
350 uint_least64_t(UINT64_C(0424242424242)));
351 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242424242"));
352
353 PoisonOutput();
354 SprintfLiteral(gOutput, "%" PRIuLEAST64,
355 uint_least64_t(UINT64_C(17171717171717171717)));
356 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17171717171717171717"));
357
358 PoisonOutput();
359 SprintfLiteral(gOutput, "%" PRIxLEAST64,
360 uint_least64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
361 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a2a2a2a2a"));
362
363 PoisonOutput();
364 SprintfLiteral(gOutput, "%" PRIXLEAST64,
365 uint_least64_t(UINT64_C(0xCDCDCDCDCDCD)));
366 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCDCDCDCD"));
367 }
368
TestPrintUnsignedLeastN()369 static void TestPrintUnsignedLeastN() {
370 TestPrintUnsignedLeast8();
371 TestPrintUnsignedLeast16();
372 TestPrintUnsignedLeast32();
373 TestPrintUnsignedLeast64();
374 }
375
TestPrintUnsignedFast8()376 static void TestPrintUnsignedFast8() {
377 PoisonOutput();
378 SprintfLiteral(gOutput, "%" PRIoFAST8, uint_fast8_t(042));
379 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
380
381 PoisonOutput();
382 SprintfLiteral(gOutput, "%" PRIuFAST8, uint_fast8_t(17));
383 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17"));
384
385 PoisonOutput();
386 SprintfLiteral(gOutput, "%" PRIxFAST8, uint_fast8_t(0x2a));
387 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a"));
388
389 PoisonOutput();
390 SprintfLiteral(gOutput, "%" PRIXFAST8, uint_fast8_t(0xCD));
391 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CD"));
392 }
393
TestPrintUnsignedFast16()394 static void TestPrintUnsignedFast16() {
395 PoisonOutput();
396 SprintfLiteral(gOutput, "%" PRIoFAST16, uint_fast16_t(04242));
397 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4242"));
398
399 PoisonOutput();
400 SprintfLiteral(gOutput, "%" PRIuFAST16, uint_fast16_t(1717));
401 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "1717"));
402
403 PoisonOutput();
404 SprintfLiteral(gOutput, "%" PRIxFAST16, uint_fast16_t(0x2a2a));
405 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a"));
406
407 PoisonOutput();
408 SprintfLiteral(gOutput, "%" PRIXFAST16, uint_fast16_t(0xCDCD));
409 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCD"));
410 }
411
TestPrintUnsignedFast32()412 static void TestPrintUnsignedFast32() {
413 PoisonOutput();
414 SprintfLiteral(gOutput, "%" PRIoFAST32, uint_fast32_t(0424242));
415 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242"));
416
417 PoisonOutput();
418 SprintfLiteral(gOutput, "%" PRIuFAST32, uint_fast32_t(171717));
419 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "171717"));
420
421 PoisonOutput();
422 SprintfLiteral(gOutput, "%" PRIxFAST32, uint_fast32_t(0x2a2a2a));
423 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a"));
424
425 PoisonOutput();
426 SprintfLiteral(gOutput, "%" PRIXFAST32, uint_fast32_t(0xCDCDCD));
427 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCD"));
428 }
429
TestPrintUnsignedFast64()430 static void TestPrintUnsignedFast64() {
431 PoisonOutput();
432 SprintfLiteral(gOutput, "%" PRIoFAST64,
433 uint_fast64_t(UINT64_C(0424242424242)));
434 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242424242"));
435
436 PoisonOutput();
437 SprintfLiteral(gOutput, "%" PRIuFAST64,
438 uint_fast64_t(UINT64_C(17171717171717171717)));
439 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17171717171717171717"));
440
441 PoisonOutput();
442 SprintfLiteral(gOutput, "%" PRIxFAST64,
443 uint_fast64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
444 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a2a2a2a2a"));
445
446 PoisonOutput();
447 SprintfLiteral(gOutput, "%" PRIXFAST64,
448 uint_fast64_t(UINT64_C(0xCDCDCDCDCDCD)));
449 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCDCDCDCD"));
450 }
451
TestPrintUnsignedFastN()452 static void TestPrintUnsignedFastN() {
453 TestPrintUnsignedFast8();
454 TestPrintUnsignedFast16();
455 TestPrintUnsignedFast32();
456 TestPrintUnsignedFast64();
457 }
458
TestPrintUnsignedMax()459 static void TestPrintUnsignedMax() {
460 PoisonOutput();
461 SprintfLiteral(gOutput, "%" PRIoMAX, uintmax_t(UINTMAX_C(432157943248732)));
462 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "14220563454333534"));
463
464 PoisonOutput();
465 SprintfLiteral(gOutput, "%" PRIuMAX, uintmax_t(UINTMAX_C(325719232983)));
466 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
467
468 PoisonOutput();
469 SprintfLiteral(gOutput, "%" PRIxMAX, uintmax_t(UINTMAX_C(327281321873)));
470 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4c337ca791"));
471
472 PoisonOutput();
473 SprintfLiteral(gOutput, "%" PRIXMAX, uintmax_t(UINTMAX_C(912389523743523)));
474 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "33DD03D75A323"));
475 }
476
TestPrintUnsignedPtr()477 static void TestPrintUnsignedPtr() {
478 PoisonOutput();
479 SprintfLiteral(gOutput, "%" PRIoPTR,
480 uintptr_t(reinterpret_cast<void*>(12345678)));
481 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "57060516"));
482
483 PoisonOutput();
484 SprintfLiteral(gOutput, "%" PRIuPTR,
485 uintptr_t(reinterpret_cast<void*>(87654321)));
486 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "87654321"));
487
488 PoisonOutput();
489 SprintfLiteral(gOutput, "%" PRIxPTR,
490 uintptr_t(reinterpret_cast<void*>(0x4c3a791)));
491 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4c3a791"));
492
493 PoisonOutput();
494 SprintfLiteral(gOutput, "%" PRIXPTR,
495 uintptr_t(reinterpret_cast<void*>(0xF328DB)));
496 MOZ_RELEASE_ASSERT(!strcmp(gOutput, "F328DB"));
497 }
498
TestPrintUnsigned()499 static void TestPrintUnsigned() {
500 TestPrintUnsignedN();
501 TestPrintUnsignedLeastN();
502 TestPrintUnsignedFastN();
503 TestPrintUnsignedMax();
504 TestPrintUnsignedPtr();
505 }
506
TestPrint()507 static void TestPrint() {
508 TestPrintSigned();
509 TestPrintUnsigned();
510 }
511
512 /*
513 * The fscanf macros for signed integers are:
514 *
515 * SCNdN SCNdLEASTN SCNdFASTN SCNdMAX SCNdPTR
516 * SCNiN SCNiLEASTN SCNiFASTN SCNiMAX SCNiPTR
517 *
518 * In these names N is the width of the type as described in C99 7.18.1.
519 */
520
521 /*
522 * MSVC's scanf is insufficiently powerful to implement all the SCN* macros.
523 * Rather than support some subset of them, we instead support none of them.
524 * See the comment at the top of IntegerPrintfMacros.h. But in case we ever do
525 * support them, the following tests should adequately test implementation
526 * correctness. (Indeed, these tests *revealed* MSVC's limitations.)
527 *
528 * That said, even if MSVC ever picks up complete support, we still probably
529 * don't want to support these, because of the undefined-behavior issue noted
530 * further down in the comment atop IntegerPrintfMacros.h.
531 */
532 #define SHOULD_TEST_SCANF_MACROS 0
533
534 #if SHOULD_TEST_SCANF_MACROS
535
536 /*
537 * glibc header definitions for SCN{d,i,o,u,x}{,LEAST,FAST}8 use the "hh" length
538 * modifier, which is new in C99 (and C++11, by reference). We compile this
539 * file as C++11, so if "hh" is used in these macros, it's standard. But some
540 * versions of gcc wrongly think it isn't and warn about a "non-standard"
541 * modifier. And since these tests mostly exist to verify format-macro/type
542 * consistency (particularly through compiler warnings about incorrect formats),
543 * these warnings are unacceptable. So for now, compile tests for those macros
544 * only if we aren't compiling with gcc.
545 */
546 # define SHOULD_TEST_8BIT_FORMAT_MACROS (!(MOZ_IS_GCC))
547
548 template <typename T>
549 union Input {
550 T mI;
551 unsigned char mPun[16];
552 };
553
554 template <typename T>
PoisonInput(Input<T> & aInput)555 static void PoisonInput(Input<T>& aInput) {
556 memset(aInput.mPun, 0xDA, sizeof(aInput.mPun));
557 }
558
559 template <typename T>
ExtraBitsUntouched(const Input<T> & aInput)560 static bool ExtraBitsUntouched(const Input<T>& aInput) {
561 for (size_t i = sizeof(aInput.mI); i < sizeof(aInput); i++) {
562 if (aInput.mPun[i] != 0xDA) {
563 return false;
564 }
565 }
566
567 return true;
568 }
569
TestScanSigned8()570 static void TestScanSigned8() {
571 # if SHOULD_TEST_8BIT_FORMAT_MACROS
572 Input<int8_t> u;
573
574 PoisonInput(u);
575 sscanf("-17", "%" SCNd8, &u.mI);
576 MOZ_RELEASE_ASSERT(u.mI == -17);
577 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
578
579 PoisonInput(u);
580 sscanf("042", "%" SCNi8, &u.mI);
581 MOZ_RELEASE_ASSERT(u.mI == 042);
582 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
583 # endif
584 }
585
TestScanSigned16()586 static void TestScanSigned16() {
587 Input<int16_t> u;
588
589 PoisonInput(u);
590 sscanf("-1742", "%" SCNd16, &u.mI);
591 MOZ_RELEASE_ASSERT(u.mI == -1742);
592 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
593
594 PoisonInput(u);
595 sscanf("04217", "%" SCNi16, &u.mI);
596 MOZ_RELEASE_ASSERT(u.mI == 04217);
597 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
598 }
599
TestScanSigned32()600 static void TestScanSigned32() {
601 Input<int32_t> u;
602
603 PoisonInput(u);
604 sscanf("-174257", "%" SCNd32, &u.mI);
605 MOZ_RELEASE_ASSERT(u.mI == -174257);
606 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
607
608 PoisonInput(u);
609 sscanf("0423571", "%" SCNi32, &u.mI);
610 MOZ_RELEASE_ASSERT(u.mI == 0423571);
611 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
612 }
613
TestScanSigned64()614 static void TestScanSigned64() {
615 Input<int64_t> u;
616
617 PoisonInput(u);
618 sscanf("-17425238927232", "%" SCNd64, &u.mI);
619 MOZ_RELEASE_ASSERT(u.mI == -INT64_C(17425238927232));
620 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
621
622 PoisonInput(u);
623 sscanf("042333576571", "%" SCNi64, &u.mI);
624 MOZ_RELEASE_ASSERT(u.mI == INT64_C(042333576571));
625 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
626 }
627
TestScanSignedN()628 static void TestScanSignedN() {
629 TestScanSigned8();
630 TestScanSigned16();
631 TestScanSigned32();
632 TestScanSigned64();
633 }
634
TestScanSignedLeast8()635 static void TestScanSignedLeast8() {
636 # if SHOULD_TEST_8BIT_FORMAT_MACROS
637 Input<int_least8_t> u;
638
639 PoisonInput(u);
640 sscanf("-17", "%" SCNdLEAST8, &u.mI);
641 MOZ_RELEASE_ASSERT(u.mI == -17);
642 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
643
644 PoisonInput(u);
645 sscanf("042", "%" SCNiLEAST8, &u.mI);
646 MOZ_RELEASE_ASSERT(u.mI == 042);
647 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
648 # endif
649 }
650
TestScanSignedLeast16()651 static void TestScanSignedLeast16() {
652 Input<int_least16_t> u;
653
654 PoisonInput(u);
655 sscanf("-1742", "%" SCNdLEAST16, &u.mI);
656 MOZ_RELEASE_ASSERT(u.mI == -1742);
657 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
658
659 PoisonInput(u);
660 sscanf("04217", "%" SCNiLEAST16, &u.mI);
661 MOZ_RELEASE_ASSERT(u.mI == 04217);
662 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
663 }
664
TestScanSignedLeast32()665 static void TestScanSignedLeast32() {
666 Input<int_least32_t> u;
667
668 PoisonInput(u);
669 sscanf("-174257", "%" SCNdLEAST32, &u.mI);
670 MOZ_RELEASE_ASSERT(u.mI == -174257);
671 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
672
673 PoisonInput(u);
674 sscanf("0423571", "%" SCNiLEAST32, &u.mI);
675 MOZ_RELEASE_ASSERT(u.mI == 0423571);
676 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
677 }
678
TestScanSignedLeast64()679 static void TestScanSignedLeast64() {
680 Input<int_least64_t> u;
681
682 PoisonInput(u);
683 sscanf("-17425238927232", "%" SCNdLEAST64, &u.mI);
684 MOZ_RELEASE_ASSERT(u.mI == -INT64_C(17425238927232));
685 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
686
687 PoisonInput(u);
688 sscanf("042333576571", "%" SCNiLEAST64, &u.mI);
689 MOZ_RELEASE_ASSERT(u.mI == INT64_C(042333576571));
690 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
691 }
692
TestScanSignedLeastN()693 static void TestScanSignedLeastN() {
694 TestScanSignedLeast8();
695 TestScanSignedLeast16();
696 TestScanSignedLeast32();
697 TestScanSignedLeast64();
698 }
699
TestScanSignedFast8()700 static void TestScanSignedFast8() {
701 # if SHOULD_TEST_8BIT_FORMAT_MACROS
702 Input<int_fast8_t> u;
703
704 PoisonInput(u);
705 sscanf("-17", "%" SCNdFAST8, &u.mI);
706 MOZ_RELEASE_ASSERT(u.mI == -17);
707 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
708
709 PoisonInput(u);
710 sscanf("042", "%" SCNiFAST8, &u.mI);
711 MOZ_RELEASE_ASSERT(u.mI == 042);
712 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
713 # endif
714 }
715
TestScanSignedFast16()716 static void TestScanSignedFast16() {
717 Input<int_fast16_t> u;
718
719 PoisonInput(u);
720 sscanf("-1742", "%" SCNdFAST16, &u.mI);
721 MOZ_RELEASE_ASSERT(u.mI == -1742);
722 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
723
724 PoisonInput(u);
725 sscanf("04217", "%" SCNiFAST16, &u.mI);
726 MOZ_RELEASE_ASSERT(u.mI == 04217);
727 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
728 }
729
TestScanSignedFast32()730 static void TestScanSignedFast32() {
731 Input<int_fast32_t> u;
732
733 PoisonInput(u);
734 sscanf("-174257", "%" SCNdFAST32, &u.mI);
735 MOZ_RELEASE_ASSERT(u.mI == -174257);
736 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
737
738 PoisonInput(u);
739 sscanf("0423571", "%" SCNiFAST32, &u.mI);
740 MOZ_RELEASE_ASSERT(u.mI == 0423571);
741 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
742 }
743
TestScanSignedFast64()744 static void TestScanSignedFast64() {
745 Input<int_fast64_t> u;
746
747 PoisonInput(u);
748 sscanf("-17425238927232", "%" SCNdFAST64, &u.mI);
749 MOZ_RELEASE_ASSERT(u.mI == -INT64_C(17425238927232));
750 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
751
752 PoisonInput(u);
753 sscanf("042333576571", "%" SCNiFAST64, &u.mI);
754 MOZ_RELEASE_ASSERT(u.mI == INT64_C(042333576571));
755 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
756 }
757
TestScanSignedFastN()758 static void TestScanSignedFastN() {
759 TestScanSignedFast8();
760 TestScanSignedFast16();
761 TestScanSignedFast32();
762 TestScanSignedFast64();
763 }
764
TestScanSignedMax()765 static void TestScanSignedMax() {
766 Input<intmax_t> u;
767
768 PoisonInput(u);
769 sscanf("-432157943248732", "%" SCNdMAX, &u.mI);
770 MOZ_RELEASE_ASSERT(u.mI == -INTMAX_C(432157943248732));
771 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
772
773 PoisonInput(u);
774 sscanf("04233357236571", "%" SCNiMAX, &u.mI);
775 MOZ_RELEASE_ASSERT(u.mI == INTMAX_C(04233357236571));
776 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
777 }
778
TestScanSignedPtr()779 static void TestScanSignedPtr() {
780 Input<intptr_t> u;
781
782 PoisonInput(u);
783 sscanf("12345678", "%" SCNdPTR, &u.mI);
784 MOZ_RELEASE_ASSERT(u.mI == intptr_t(reinterpret_cast<void*>(12345678)));
785 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
786
787 PoisonInput(u);
788 sscanf("04233357236", "%" SCNiPTR, &u.mI);
789 MOZ_RELEASE_ASSERT(u.mI == intptr_t(reinterpret_cast<void*>(04233357236)));
790 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
791 }
792
TestScanSigned()793 static void TestScanSigned() {
794 TestScanSignedN();
795 TestScanSignedLeastN();
796 TestScanSignedFastN();
797 TestScanSignedMax();
798 TestScanSignedPtr();
799 }
800
801 /*
802 * The fscanf macros for unsigned integers are:
803 *
804 * SCNoN SCNoLEASTN SCNoFASTN SCNoMAX SCNoPTR
805 * SCNuN SCNuLEASTN SCNuFASTN SCNuMAX SCNuPTR
806 * SCNxN SCNxLEASTN SCNxFASTN SCNxMAX SCNxPTR
807 *
808 * In these names N is the width of the type as described in C99 7.18.1.
809 */
810
TestScanUnsigned8()811 static void TestScanUnsigned8() {
812 # if SHOULD_TEST_8BIT_FORMAT_MACROS
813 Input<uint8_t> u;
814
815 PoisonInput(u);
816 sscanf("17", "%" SCNo8, &u.mI);
817 MOZ_RELEASE_ASSERT(u.mI == 017);
818 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
819
820 PoisonInput(u);
821 sscanf("42", "%" SCNu8, &u.mI);
822 MOZ_RELEASE_ASSERT(u.mI == 42);
823 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
824
825 PoisonInput(u);
826 sscanf("2A", "%" SCNx8, &u.mI);
827 MOZ_RELEASE_ASSERT(u.mI == 0x2A);
828 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
829 # endif
830 }
831
TestScanUnsigned16()832 static void TestScanUnsigned16() {
833 Input<uint16_t> u;
834
835 PoisonInput(u);
836 sscanf("1742", "%" SCNo16, &u.mI);
837 MOZ_RELEASE_ASSERT(u.mI == 01742);
838 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
839
840 PoisonInput(u);
841 sscanf("4217", "%" SCNu16, &u.mI);
842 MOZ_RELEASE_ASSERT(u.mI == 4217);
843 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
844
845 PoisonInput(u);
846 sscanf("2ABC", "%" SCNx16, &u.mI);
847 MOZ_RELEASE_ASSERT(u.mI == 0x2ABC);
848 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
849 }
850
TestScanUnsigned32()851 static void TestScanUnsigned32() {
852 Input<uint32_t> u;
853
854 PoisonInput(u);
855 sscanf("17421742", "%" SCNo32, &u.mI);
856 MOZ_RELEASE_ASSERT(u.mI == 017421742);
857 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
858
859 PoisonInput(u);
860 sscanf("4217867", "%" SCNu32, &u.mI);
861 MOZ_RELEASE_ASSERT(u.mI == 4217867);
862 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
863
864 PoisonInput(u);
865 sscanf("2ABCBEEF", "%" SCNx32, &u.mI);
866 MOZ_RELEASE_ASSERT(u.mI == 0x2ABCBEEF);
867 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
868 }
869
TestScanUnsigned64()870 static void TestScanUnsigned64() {
871 Input<uint64_t> u;
872
873 PoisonInput(u);
874 sscanf("17421742173", "%" SCNo64, &u.mI);
875 MOZ_RELEASE_ASSERT(u.mI == UINT64_C(017421742173));
876 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
877
878 PoisonInput(u);
879 sscanf("421786713579", "%" SCNu64, &u.mI);
880 MOZ_RELEASE_ASSERT(u.mI == UINT64_C(421786713579));
881 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
882
883 PoisonInput(u);
884 sscanf("DEADBEEF7457E", "%" SCNx64, &u.mI);
885 MOZ_RELEASE_ASSERT(u.mI == UINT64_C(0xDEADBEEF7457E));
886 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
887 }
888
TestScanUnsignedN()889 static void TestScanUnsignedN() {
890 TestScanUnsigned8();
891 TestScanUnsigned16();
892 TestScanUnsigned32();
893 TestScanUnsigned64();
894 }
895
TestScanUnsignedLeast8()896 static void TestScanUnsignedLeast8() {
897 # if SHOULD_TEST_8BIT_FORMAT_MACROS
898 Input<uint_least8_t> u;
899
900 PoisonInput(u);
901 sscanf("17", "%" SCNoLEAST8, &u.mI);
902 MOZ_RELEASE_ASSERT(u.mI == 017);
903 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
904
905 PoisonInput(u);
906 sscanf("42", "%" SCNuLEAST8, &u.mI);
907 MOZ_RELEASE_ASSERT(u.mI == 42);
908 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
909
910 PoisonInput(u);
911 sscanf("2A", "%" SCNxLEAST8, &u.mI);
912 MOZ_RELEASE_ASSERT(u.mI == 0x2A);
913 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
914 # endif
915 }
916
TestScanUnsignedLeast16()917 static void TestScanUnsignedLeast16() {
918 Input<uint_least16_t> u;
919
920 PoisonInput(u);
921 sscanf("1742", "%" SCNoLEAST16, &u.mI);
922 MOZ_RELEASE_ASSERT(u.mI == 01742);
923 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
924
925 PoisonInput(u);
926 sscanf("4217", "%" SCNuLEAST16, &u.mI);
927 MOZ_RELEASE_ASSERT(u.mI == 4217);
928 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
929
930 PoisonInput(u);
931 sscanf("2ABC", "%" SCNxLEAST16, &u.mI);
932 MOZ_RELEASE_ASSERT(u.mI == 0x2ABC);
933 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
934 }
935
TestScanUnsignedLeast32()936 static void TestScanUnsignedLeast32() {
937 Input<uint_least32_t> u;
938
939 PoisonInput(u);
940 sscanf("17421742", "%" SCNoLEAST32, &u.mI);
941 MOZ_RELEASE_ASSERT(u.mI == 017421742);
942 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
943
944 PoisonInput(u);
945 sscanf("4217867", "%" SCNuLEAST32, &u.mI);
946 MOZ_RELEASE_ASSERT(u.mI == 4217867);
947 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
948
949 PoisonInput(u);
950 sscanf("2ABCBEEF", "%" SCNxLEAST32, &u.mI);
951 MOZ_RELEASE_ASSERT(u.mI == 0x2ABCBEEF);
952 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
953 }
954
TestScanUnsignedLeast64()955 static void TestScanUnsignedLeast64() {
956 Input<uint_least64_t> u;
957
958 PoisonInput(u);
959 sscanf("17421742173", "%" SCNoLEAST64, &u.mI);
960 MOZ_RELEASE_ASSERT(u.mI == UINT64_C(017421742173));
961 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
962
963 PoisonInput(u);
964 sscanf("421786713579", "%" SCNuLEAST64, &u.mI);
965 MOZ_RELEASE_ASSERT(u.mI == UINT64_C(421786713579));
966 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
967
968 PoisonInput(u);
969 sscanf("DEADBEEF7457E", "%" SCNxLEAST64, &u.mI);
970 MOZ_RELEASE_ASSERT(u.mI == UINT64_C(0xDEADBEEF7457E));
971 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
972 }
973
TestScanUnsignedLeastN()974 static void TestScanUnsignedLeastN() {
975 TestScanUnsignedLeast8();
976 TestScanUnsignedLeast16();
977 TestScanUnsignedLeast32();
978 TestScanUnsignedLeast64();
979 }
980
TestScanUnsignedFast8()981 static void TestScanUnsignedFast8() {
982 # if SHOULD_TEST_8BIT_FORMAT_MACROS
983 Input<uint_fast8_t> u;
984
985 PoisonInput(u);
986 sscanf("17", "%" SCNoFAST8, &u.mI);
987 MOZ_RELEASE_ASSERT(u.mI == 017);
988 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
989
990 PoisonInput(u);
991 sscanf("42", "%" SCNuFAST8, &u.mI);
992 MOZ_RELEASE_ASSERT(u.mI == 42);
993 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
994
995 PoisonInput(u);
996 sscanf("2A", "%" SCNxFAST8, &u.mI);
997 MOZ_RELEASE_ASSERT(u.mI == 0x2A);
998 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
999 # endif
1000 }
1001
TestScanUnsignedFast16()1002 static void TestScanUnsignedFast16() {
1003 Input<uint_fast16_t> u;
1004
1005 PoisonInput(u);
1006 sscanf("1742", "%" SCNoFAST16, &u.mI);
1007 MOZ_RELEASE_ASSERT(u.mI == 01742);
1008 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1009
1010 PoisonInput(u);
1011 sscanf("4217", "%" SCNuFAST16, &u.mI);
1012 MOZ_RELEASE_ASSERT(u.mI == 4217);
1013 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1014
1015 PoisonInput(u);
1016 sscanf("2ABC", "%" SCNxFAST16, &u.mI);
1017 MOZ_RELEASE_ASSERT(u.mI == 0x2ABC);
1018 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1019 }
1020
TestScanUnsignedFast32()1021 static void TestScanUnsignedFast32() {
1022 Input<uint_fast32_t> u;
1023
1024 PoisonInput(u);
1025 sscanf("17421742", "%" SCNoFAST32, &u.mI);
1026 MOZ_RELEASE_ASSERT(u.mI == 017421742);
1027 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1028
1029 PoisonInput(u);
1030 sscanf("4217867", "%" SCNuFAST32, &u.mI);
1031 MOZ_RELEASE_ASSERT(u.mI == 4217867);
1032 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1033
1034 PoisonInput(u);
1035 sscanf("2ABCBEEF", "%" SCNxFAST32, &u.mI);
1036 MOZ_RELEASE_ASSERT(u.mI == 0x2ABCBEEF);
1037 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1038 }
1039
TestScanUnsignedFast64()1040 static void TestScanUnsignedFast64() {
1041 Input<uint_fast64_t> u;
1042
1043 PoisonInput(u);
1044 sscanf("17421742173", "%" SCNoFAST64, &u.mI);
1045 MOZ_RELEASE_ASSERT(u.mI == UINT64_C(017421742173));
1046 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1047
1048 PoisonInput(u);
1049 sscanf("421786713579", "%" SCNuFAST64, &u.mI);
1050 MOZ_RELEASE_ASSERT(u.mI == UINT64_C(421786713579));
1051 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1052
1053 PoisonInput(u);
1054 sscanf("DEADBEEF7457E", "%" SCNxFAST64, &u.mI);
1055 MOZ_RELEASE_ASSERT(u.mI == UINT64_C(0xDEADBEEF7457E));
1056 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1057 }
1058
TestScanUnsignedFastN()1059 static void TestScanUnsignedFastN() {
1060 TestScanUnsignedFast8();
1061 TestScanUnsignedFast16();
1062 TestScanUnsignedFast32();
1063 TestScanUnsignedFast64();
1064 }
1065
TestScanUnsignedMax()1066 static void TestScanUnsignedMax() {
1067 Input<uintmax_t> u;
1068
1069 PoisonInput(u);
1070 sscanf("14220563454333534", "%" SCNoMAX, &u.mI);
1071 MOZ_RELEASE_ASSERT(u.mI == UINTMAX_C(432157943248732));
1072 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1073
1074 PoisonInput(u);
1075 sscanf("432157943248732", "%" SCNuMAX, &u.mI);
1076 MOZ_RELEASE_ASSERT(u.mI == UINTMAX_C(432157943248732));
1077 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1078
1079 PoisonInput(u);
1080 sscanf("4c337ca791", "%" SCNxMAX, &u.mI);
1081 MOZ_RELEASE_ASSERT(u.mI == UINTMAX_C(327281321873));
1082 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1083 }
1084
TestScanUnsignedPtr()1085 static void TestScanUnsignedPtr() {
1086 Input<uintptr_t> u;
1087
1088 PoisonInput(u);
1089 sscanf("57060516", "%" SCNoPTR, &u.mI);
1090 MOZ_RELEASE_ASSERT(u.mI == uintptr_t(reinterpret_cast<void*>(12345678)));
1091 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1092
1093 PoisonInput(u);
1094 sscanf("87654321", "%" SCNuPTR, &u.mI);
1095 MOZ_RELEASE_ASSERT(u.mI == uintptr_t(reinterpret_cast<void*>(87654321)));
1096 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1097
1098 PoisonInput(u);
1099 sscanf("4c3a791", "%" SCNxPTR, &u.mI);
1100 MOZ_RELEASE_ASSERT(u.mI == uintptr_t(reinterpret_cast<void*>(0x4c3a791)));
1101 MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
1102 }
1103
TestScanUnsigned()1104 static void TestScanUnsigned() {
1105 TestScanUnsignedN();
1106 TestScanUnsignedLeastN();
1107 TestScanUnsignedFastN();
1108 TestScanUnsignedMax();
1109 TestScanUnsignedPtr();
1110 }
1111
TestScan()1112 static void TestScan() {
1113 TestScanSigned();
1114 TestScanUnsigned();
1115 }
1116
1117 #endif /* SHOULD_TEST_SCANF_MACROS */
1118
1119 #if defined(XP_WIN)
wmain()1120 int wmain()
1121 #else
1122 int main()
1123 #endif // defined(XP_WIN)
1124 {
1125 TestPrint();
1126 #if SHOULD_TEST_SCANF_MACROS
1127 TestScan();
1128 #endif
1129 return 0;
1130 }
1131