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