xref: /qemu/tests/unit/test-cutils.c (revision 42cc08d1)
1 /*
2  * cutils.c unit-tests
3  *
4  * Copyright Red Hat
5  *
6  * Authors:
7  *  Eduardo Habkost <ehabkost@redhat.com>
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in
17  * all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25  * THE SOFTWARE.
26  */
27 
28 #include <math.h>
29 
30 #include "qemu/osdep.h"
31 #include "qemu/cutils.h"
32 #include "qemu/units.h"
33 
test_parse_uint_null(void)34 static void test_parse_uint_null(void)
35 {
36     uint64_t i = 999;
37     const char *endptr = "somewhere";
38     int r;
39 
40     r = parse_uint(NULL, &endptr, 0, &i);
41 
42     g_assert_cmpint(r, ==, -EINVAL);
43     g_assert_cmpuint(i, ==, 0);
44     g_assert_null(endptr);
45 }
46 
test_parse_uint_empty(void)47 static void test_parse_uint_empty(void)
48 {
49     uint64_t i = 999;
50     const char *endptr = "somewhere";
51     const char *str = "";
52     int r;
53 
54     r = parse_uint(str, &endptr, 0, &i);
55 
56     g_assert_cmpint(r, ==, -EINVAL);
57     g_assert_cmpuint(i, ==, 0);
58     g_assert_true(endptr == str);
59 }
60 
test_parse_uint_whitespace(void)61 static void test_parse_uint_whitespace(void)
62 {
63     uint64_t i = 999;
64     const char *endptr = "somewhere";
65     const char *str = "   \t   ";
66     int r;
67 
68     r = parse_uint(str, &endptr, 0, &i);
69 
70     g_assert_cmpint(r, ==, -EINVAL);
71     g_assert_cmpuint(i, ==, 0);
72     g_assert_true(endptr == str);
73 }
74 
75 
test_parse_uint_invalid(void)76 static void test_parse_uint_invalid(void)
77 {
78     uint64_t i = 999;
79     const char *endptr = "somewhere";
80     const char *str = " \t xxx";
81     int r;
82 
83     r = parse_uint(str, &endptr, 0, &i);
84 
85     g_assert_cmpint(r, ==, -EINVAL);
86     g_assert_cmpuint(i, ==, 0);
87     g_assert_true(endptr == str);
88 }
89 
90 
test_parse_uint_trailing(void)91 static void test_parse_uint_trailing(void)
92 {
93     uint64_t i = 999;
94     const char *endptr = "somewhere";
95     const char *str = "123xxx";
96     int r;
97 
98     r = parse_uint(str, &endptr, 0, &i);
99 
100     g_assert_cmpint(r, ==, 0);
101     g_assert_cmpuint(i, ==, 123);
102     g_assert_true(endptr == str + 3);
103 }
104 
test_parse_uint_correct(void)105 static void test_parse_uint_correct(void)
106 {
107     uint64_t i = 999;
108     const char *endptr = "somewhere";
109     const char *str = "123";
110     int r;
111 
112     r = parse_uint(str, &endptr, 0, &i);
113 
114     g_assert_cmpint(r, ==, 0);
115     g_assert_cmpuint(i, ==, 123);
116     g_assert_true(endptr == str + strlen(str));
117 }
118 
test_parse_uint_octal(void)119 static void test_parse_uint_octal(void)
120 {
121     uint64_t i = 999;
122     const char *endptr = "somewhere";
123     const char *str = "0123";
124     int r;
125 
126     r = parse_uint(str, &endptr, 0, &i);
127 
128     g_assert_cmpint(r, ==, 0);
129     g_assert_cmpuint(i, ==, 0123);
130     g_assert_true(endptr == str + strlen(str));
131 }
132 
test_parse_uint_decimal(void)133 static void test_parse_uint_decimal(void)
134 {
135     uint64_t i = 999;
136     const char *endptr = "somewhere";
137     const char *str = "0123";
138     int r;
139 
140     r = parse_uint(str, &endptr, 10, &i);
141 
142     g_assert_cmpint(r, ==, 0);
143     g_assert_cmpuint(i, ==, 123);
144     g_assert_true(endptr == str + strlen(str));
145 }
146 
test_parse_uint_llong_max(void)147 static void test_parse_uint_llong_max(void)
148 {
149     uint64_t i = 999;
150     const char *endptr = "somewhere";
151     char *str = g_strdup_printf("%llu", (unsigned long long)LLONG_MAX + 1);
152     int r;
153 
154     r = parse_uint(str, &endptr, 0, &i);
155 
156     g_assert_cmpint(r, ==, 0);
157     g_assert_cmpuint(i, ==, (unsigned long long)LLONG_MAX + 1);
158     g_assert_true(endptr == str + strlen(str));
159 
160     g_free(str);
161 }
162 
test_parse_uint_max(void)163 static void test_parse_uint_max(void)
164 {
165     uint64_t i = 999;
166     const char *endptr = "somewhere";
167     char *str = g_strdup_printf("%llu", ULLONG_MAX);
168     int r;
169 
170     r = parse_uint(str, &endptr, 0, &i);
171 
172     g_assert_cmpint(r, ==, 0);
173     g_assert_cmpuint(i, ==, ULLONG_MAX);
174     g_assert_true(endptr == str + strlen(str));
175 
176     g_free(str);
177 }
178 
test_parse_uint_overflow(void)179 static void test_parse_uint_overflow(void)
180 {
181     uint64_t i;
182     const char *endptr;
183     const char *str;
184     int r;
185 
186     i = 999;
187     endptr = "somewhere";
188     str = "99999999999999999999999999999999999999";
189     r = parse_uint(str, &endptr, 0, &i);
190     g_assert_cmpint(r, ==, -ERANGE);
191     g_assert_cmpuint(i, ==, ULLONG_MAX);
192     g_assert_true(endptr == str + strlen(str));
193 
194     i = 999;
195     endptr = "somewhere";
196     str = "0x10000000000000000"; /* 65 bits, 64-bit sign bit clear */
197     r = parse_uint(str, &endptr, 0, &i);
198     g_assert_cmpint(r, ==, -ERANGE);
199     g_assert_cmpuint(i, ==, ULLONG_MAX);
200     g_assert_true(endptr == str + strlen(str));
201 
202     i = 999;
203     endptr = "somewhere";
204     str = "0x18000000080000000"; /* 65 bits, 64-bit sign bit set */
205     r = parse_uint(str, &endptr, 0, &i);
206     g_assert_cmpint(r, ==, -ERANGE);
207     g_assert_cmpuint(i, ==, ULLONG_MAX);
208     g_assert_true(endptr == str + strlen(str));
209 }
210 
test_parse_uint_negative(void)211 static void test_parse_uint_negative(void)
212 {
213     uint64_t i;
214     const char *endptr;
215     const char *str;
216     int r;
217 
218     i = 999;
219     endptr = "somewhere";
220     str = " \t -321";
221     r = parse_uint(str, &endptr, 0, &i);
222     g_assert_cmpint(r, ==, -ERANGE);
223     g_assert_cmpuint(i, ==, 0);
224     g_assert_true(endptr == str + strlen(str));
225 
226     i = 999;
227     endptr = "somewhere";
228     str = "-0xffffffff00000001";
229     r = parse_uint(str, &endptr, 0, &i);
230     g_assert_cmpint(r, ==, -ERANGE);
231     g_assert_cmpuint(i, ==, 0);
232     g_assert_true(endptr == str + strlen(str));
233 }
234 
test_parse_uint_negzero(void)235 static void test_parse_uint_negzero(void)
236 {
237     uint64_t i = 999;
238     const char *endptr = "somewhere";
239     const char *str = " -0";
240     int r;
241 
242     r = parse_uint(str, &endptr, 0, &i);
243 
244     g_assert_cmpint(r, ==, -ERANGE);
245     g_assert_cmpuint(i, ==, 0);
246     g_assert_true(endptr == str + strlen(str));
247 }
248 
test_parse_uint_full_trailing(void)249 static void test_parse_uint_full_trailing(void)
250 {
251     uint64_t i = 999;
252     const char *str = "123xxx";
253     int r;
254 
255     r = parse_uint_full(str, 0, &i);
256 
257     g_assert_cmpint(r, ==, -EINVAL);
258     g_assert_cmpuint(i, ==, 0);
259 }
260 
test_parse_uint_full_correct(void)261 static void test_parse_uint_full_correct(void)
262 {
263     uint64_t i = 999;
264     const char *str = "123";
265     int r;
266 
267     r = parse_uint_full(str, 0, &i);
268 
269     g_assert_cmpint(r, ==, 0);
270     g_assert_cmpuint(i, ==, 123);
271 }
272 
test_parse_uint_full_erange_junk(void)273 static void test_parse_uint_full_erange_junk(void)
274 {
275     /* EINVAL has priority over ERANGE */
276     uint64_t i = 999;
277     const char *str = "-2junk";
278     int r;
279 
280     r = parse_uint_full(str, 0, &i);
281 
282     g_assert_cmpint(r, ==, -EINVAL);
283     g_assert_cmpuint(i, ==, 0);
284 }
285 
test_parse_uint_full_null(void)286 static void test_parse_uint_full_null(void)
287 {
288     uint64_t i = 999;
289     const char *str = NULL;
290     int r;
291 
292     r = parse_uint_full(str, 0, &i);
293 
294     g_assert_cmpint(r, ==, -EINVAL);
295     g_assert_cmpuint(i, ==, 0);
296 }
297 
test_qemu_strtoi_correct(void)298 static void test_qemu_strtoi_correct(void)
299 {
300     const char *str = "12345 foo";
301     char f = 'X';
302     const char *endptr = &f;
303     int res = 999;
304     int err;
305 
306     err = qemu_strtoi(str, &endptr, 0, &res);
307 
308     g_assert_cmpint(err, ==, 0);
309     g_assert_cmpint(res, ==, 12345);
310     g_assert_true(endptr == str + 5);
311 }
312 
test_qemu_strtoi_null(void)313 static void test_qemu_strtoi_null(void)
314 {
315     char f = 'X';
316     const char *endptr = &f;
317     int res = 999;
318     int err;
319 
320     err = qemu_strtoi(NULL, &endptr, 0, &res);
321 
322     g_assert_cmpint(err, ==, -EINVAL);
323     g_assert_cmpint(res, ==, 0);
324     g_assert_null(endptr);
325 }
326 
test_qemu_strtoi_empty(void)327 static void test_qemu_strtoi_empty(void)
328 {
329     const char *str = "";
330     char f = 'X';
331     const char *endptr = &f;
332     int res = 999;
333     int err;
334 
335     err = qemu_strtoi(str, &endptr, 0, &res);
336 
337     g_assert_cmpint(err, ==, -EINVAL);
338     g_assert_cmpint(res, ==, 0);
339     g_assert_true(endptr == str);
340 }
341 
test_qemu_strtoi_whitespace(void)342 static void test_qemu_strtoi_whitespace(void)
343 {
344     const char *str = "  \t  ";
345     char f = 'X';
346     const char *endptr = &f;
347     int res = 999;
348     int err;
349 
350     err = qemu_strtoi(str, &endptr, 0, &res);
351 
352     g_assert_cmpint(err, ==, -EINVAL);
353     g_assert_cmpint(res, ==, 0);
354     g_assert_true(endptr == str);
355 }
356 
test_qemu_strtoi_invalid(void)357 static void test_qemu_strtoi_invalid(void)
358 {
359     const char *str = "   xxxx  \t abc";
360     char f = 'X';
361     const char *endptr = &f;
362     int res = 999;
363     int err;
364 
365     err = qemu_strtoi(str, &endptr, 0, &res);
366 
367     g_assert_cmpint(err, ==, -EINVAL);
368     g_assert_cmpint(res, ==, 0);
369     g_assert_true(endptr == str);
370 }
371 
test_qemu_strtoi_trailing(void)372 static void test_qemu_strtoi_trailing(void)
373 {
374     const char *str = "123xxx";
375     char f = 'X';
376     const char *endptr = &f;
377     int res = 999;
378     int err;
379 
380     err = qemu_strtoi(str, &endptr, 0, &res);
381 
382     g_assert_cmpint(err, ==, 0);
383     g_assert_cmpint(res, ==, 123);
384     g_assert_true(endptr == str + 3);
385 }
386 
test_qemu_strtoi_octal(void)387 static void test_qemu_strtoi_octal(void)
388 {
389     const char *str = "0123";
390     char f = 'X';
391     const char *endptr = &f;
392     int res = 999;
393     int err;
394 
395     err = qemu_strtoi(str, &endptr, 8, &res);
396 
397     g_assert_cmpint(err, ==, 0);
398     g_assert_cmpint(res, ==, 0123);
399     g_assert_true(endptr == str + strlen(str));
400 
401     res = 999;
402     endptr = &f;
403     err = qemu_strtoi(str, &endptr, 0, &res);
404 
405     g_assert_cmpint(err, ==, 0);
406     g_assert_cmpint(res, ==, 0123);
407     g_assert_true(endptr == str + strlen(str));
408 }
409 
test_qemu_strtoi_decimal(void)410 static void test_qemu_strtoi_decimal(void)
411 {
412     const char *str = "0123";
413     char f = 'X';
414     const char *endptr = &f;
415     int res = 999;
416     int err;
417 
418     err = qemu_strtoi(str, &endptr, 10, &res);
419 
420     g_assert_cmpint(err, ==, 0);
421     g_assert_cmpint(res, ==, 123);
422     g_assert_true(endptr == str + strlen(str));
423 
424     str = "123";
425     res = 999;
426     endptr = &f;
427     err = qemu_strtoi(str, &endptr, 0, &res);
428 
429     g_assert_cmpint(err, ==, 0);
430     g_assert_cmpint(res, ==, 123);
431     g_assert_true(endptr == str + strlen(str));
432 }
433 
test_qemu_strtoi_hex(void)434 static void test_qemu_strtoi_hex(void)
435 {
436     const char *str = "0123";
437     char f = 'X';
438     const char *endptr = &f;
439     int res = 999;
440     int err;
441 
442     err = qemu_strtoi(str, &endptr, 16, &res);
443 
444     g_assert_cmpint(err, ==, 0);
445     g_assert_cmpint(res, ==, 0x123);
446     g_assert_true(endptr == str + strlen(str));
447 
448     str = "0x123";
449     res = 999;
450     endptr = &f;
451     err = qemu_strtoi(str, &endptr, 0, &res);
452 
453     g_assert_cmpint(err, ==, 0);
454     g_assert_cmpint(res, ==, 0x123);
455     g_assert_true(endptr == str + strlen(str));
456 
457     str = "0x";
458     res = 999;
459     endptr = &f;
460     err = qemu_strtoi(str, &endptr, 16, &res);
461 
462     g_assert_cmpint(err, ==, 0);
463     g_assert_cmpint(res, ==, 0);
464     g_assert_true(endptr == str + 1);
465 }
466 
test_qemu_strtoi_max(void)467 static void test_qemu_strtoi_max(void)
468 {
469     char *str = g_strdup_printf("%d", INT_MAX);
470     char f = 'X';
471     const char *endptr = &f;
472     int res = 999;
473     int err;
474 
475     err = qemu_strtoi(str, &endptr, 0, &res);
476 
477     g_assert_cmpint(err, ==, 0);
478     g_assert_cmpint(res, ==, INT_MAX);
479     g_assert_true(endptr == str + strlen(str));
480     g_free(str);
481 }
482 
test_qemu_strtoi_overflow(void)483 static void test_qemu_strtoi_overflow(void)
484 {
485     const char *str;
486     const char *endptr;
487     int res;
488     int err;
489 
490     str = "2147483648"; /* INT_MAX + 1ll */
491     endptr = "somewhere";
492     res = 999;
493     err = qemu_strtoi(str, &endptr, 0, &res);
494     g_assert_cmpint(err, ==, -ERANGE);
495     g_assert_cmpint(res, ==, INT_MAX);
496     g_assert_true(endptr == str + strlen(str));
497 
498     str = "0x7fffffffffffffff"; /* LLONG_MAX */
499     endptr = "somewhere";
500     res = 999;
501     err = qemu_strtoi(str, &endptr, 0, &res);
502     g_assert_cmpint(err, ==, -ERANGE);
503     g_assert_cmpint(res, ==, INT_MAX);
504     g_assert_true(endptr == str + strlen(str));
505 
506     str = "0x8000000000000000"; /* (uint64_t)LLONG_MIN */
507     endptr = "somewhere";
508     res = 999;
509     err = qemu_strtoi(str, &endptr, 0, &res);
510     g_assert_cmpint(err, ==, -ERANGE);
511     g_assert_cmpint(res, ==, INT_MAX);
512     g_assert_true(endptr == str + strlen(str));
513 
514     str = "0x10000000000000000"; /* 65 bits, 32-bit sign bit clear */
515     endptr = "somewhere";
516     res = 999;
517     err = qemu_strtoi(str, &endptr, 0, &res);
518     g_assert_cmpint(err, ==, -ERANGE);
519     g_assert_cmpint(res, ==, INT_MAX);
520     g_assert_true(endptr == str + strlen(str));
521 
522     str = "0x18000000080000000"; /* 65 bits, 32-bit sign bit set */
523     endptr = "somewhere";
524     res = 999;
525     err = qemu_strtoi(str, &endptr, 0, &res);
526     g_assert_cmpint(err, ==, -ERANGE);
527     g_assert_cmpint(res, ==, INT_MAX);
528     g_assert_true(endptr == str + strlen(str));
529 }
530 
test_qemu_strtoi_min(void)531 static void test_qemu_strtoi_min(void)
532 {
533     char *str = g_strdup_printf("%d", INT_MIN);
534     char f = 'X';
535     const char *endptr = &f;
536     int res = 999;
537     int err;
538 
539     err = qemu_strtoi(str, &endptr, 0, &res);
540 
541     g_assert_cmpint(err, ==, 0);
542     g_assert_cmpint(res, ==, INT_MIN);
543     g_assert_true(endptr == str + strlen(str));
544     g_free(str);
545 }
546 
test_qemu_strtoi_underflow(void)547 static void test_qemu_strtoi_underflow(void)
548 {
549     const char *str;
550     const char *endptr;
551     int res;
552     int err;
553 
554     str = "-2147483649"; /* INT_MIN - 1ll */
555     endptr = "somewhere";
556     res = 999;
557     err = qemu_strtoi(str, &endptr, 0, &res);
558     g_assert_cmpint(err, ==, -ERANGE);
559     g_assert_cmpint(res, ==, INT_MIN);
560     g_assert_true(endptr == str + strlen(str));
561 
562     str = "-0x7fffffffffffffff"; /* -LLONG_MAX */
563     endptr = "somewhere";
564     res = 999;
565     err = qemu_strtoi(str, &endptr, 0, &res);
566     g_assert_cmpint(err, ==, -ERANGE);
567     g_assert_cmpint(res, ==, INT_MIN);
568     g_assert_true(endptr == str + strlen(str));
569 
570     str = "-0x8000000000000000"; /* (uint64_t)LLONG_MIN */
571     endptr = "somewhere";
572     res = 999;
573     err = qemu_strtoi(str, &endptr, 0, &res);
574     g_assert_cmpint(err, ==, -ERANGE);
575     g_assert_cmpint(res, ==, INT_MIN);
576     g_assert_true(endptr == str + strlen(str));
577 
578     str = "-18446744073709551615"; /* -UINT64_MAX (not 1) */
579     endptr = "somewhere";
580     res = 999;
581     err = qemu_strtoi(str, &endptr, 0, &res);
582     g_assert_cmpint(err, ==, -ERANGE);
583     g_assert_cmpint(res, ==, INT_MIN);
584     g_assert_true(endptr == str + strlen(str));
585 
586     str = "-0x10000000000000000"; /* 65 bits, 32-bit sign bit clear */
587     endptr = "somewhere";
588     res = 999;
589     err = qemu_strtoi(str, &endptr, 0, &res);
590     g_assert_cmpint(err, ==, -ERANGE);
591     g_assert_cmpint(res, ==, INT_MIN);
592     g_assert_true(endptr == str + strlen(str));
593 
594     str = "-0x18000000080000000"; /* 65 bits, 32-bit sign bit set */
595     endptr = "somewhere";
596     res = 999;
597     err = qemu_strtoi(str, &endptr, 0, &res);
598     g_assert_cmpint(err, ==, -ERANGE);
599     g_assert_cmpint(res, ==, INT_MIN);
600     g_assert_true(endptr == str + strlen(str));
601 }
602 
test_qemu_strtoi_negative(void)603 static void test_qemu_strtoi_negative(void)
604 {
605     const char *str;
606     const char *endptr;
607     int res;
608     int err;
609 
610     str = "  \t -321";
611     endptr = "somewhere";
612     res = 999;
613     err = qemu_strtoi(str, &endptr, 0, &res);
614     g_assert_cmpint(err, ==, 0);
615     g_assert_cmpint(res, ==, -321);
616     g_assert_true(endptr == str + strlen(str));
617 
618     str = "-2147483648"; /* INT_MIN */
619     endptr = "somewhere";
620     res = 999;
621     err = qemu_strtoi(str, &endptr, 0, &res);
622     g_assert_cmpint(err, ==, 0);
623     g_assert_cmpint(res, ==, INT_MIN);
624     g_assert_true(endptr == str + strlen(str));
625 }
626 
test_qemu_strtoi_negzero(void)627 static void test_qemu_strtoi_negzero(void)
628 {
629     const char *str = " -0";
630     char f = 'X';
631     const char *endptr = &f;
632     int res = 999;
633     int err;
634 
635     err = qemu_strtoi(str, &endptr, 0, &res);
636 
637     g_assert_cmpint(err, ==, 0);
638     g_assert_cmpint(res, ==, 0);
639     g_assert_true(endptr == str + strlen(str));
640 }
641 
test_qemu_strtoi_full_correct(void)642 static void test_qemu_strtoi_full_correct(void)
643 {
644     const char *str = "123";
645     int res = 999;
646     int err;
647 
648     err = qemu_strtoi(str, NULL, 0, &res);
649 
650     g_assert_cmpint(err, ==, 0);
651     g_assert_cmpint(res, ==, 123);
652 }
653 
test_qemu_strtoi_full_null(void)654 static void test_qemu_strtoi_full_null(void)
655 {
656     char f = 'X';
657     const char *endptr = &f;
658     int res = 999;
659     int err;
660 
661     err = qemu_strtoi(NULL, &endptr, 0, &res);
662 
663     g_assert_cmpint(err, ==, -EINVAL);
664     g_assert_cmpint(res, ==, 0);
665     g_assert_null(endptr);
666 }
667 
test_qemu_strtoi_full_empty(void)668 static void test_qemu_strtoi_full_empty(void)
669 {
670     const char *str = "";
671     int res = 999;
672     int err;
673 
674     err = qemu_strtoi(str, NULL, 0, &res);
675 
676     g_assert_cmpint(err, ==, -EINVAL);
677     g_assert_cmpint(res, ==, 0);
678 }
679 
test_qemu_strtoi_full_negative(void)680 static void test_qemu_strtoi_full_negative(void)
681 {
682     const char *str = " \t -321";
683     int res = 999;
684     int err;
685 
686     err = qemu_strtoi(str, NULL, 0, &res);
687 
688     g_assert_cmpint(err, ==, 0);
689     g_assert_cmpint(res, ==, -321);
690 }
691 
test_qemu_strtoi_full_negzero(void)692 static void test_qemu_strtoi_full_negzero(void)
693 {
694     const char *str = " -0";
695     int res = 999;
696     int err;
697 
698     err = qemu_strtoi(str, NULL, 0, &res);
699 
700     g_assert_cmpint(err, ==, 0);
701     g_assert_cmpint(res, ==, 0);
702 }
703 
test_qemu_strtoi_full_trailing(void)704 static void test_qemu_strtoi_full_trailing(void)
705 {
706     const char *str = "123xxx";
707     int res = 999;
708     int err;
709 
710     err = qemu_strtoi(str, NULL, 0, &res);
711 
712     g_assert_cmpint(err, ==, -EINVAL);
713     g_assert_cmpint(res, ==, 123);
714 }
715 
test_qemu_strtoi_full_max(void)716 static void test_qemu_strtoi_full_max(void)
717 {
718     char *str = g_strdup_printf("%d", INT_MAX);
719     int res = 999;
720     int err;
721 
722     err = qemu_strtoi(str, NULL, 0, &res);
723 
724     g_assert_cmpint(err, ==, 0);
725     g_assert_cmpint(res, ==, INT_MAX);
726     g_free(str);
727 }
728 
test_qemu_strtoi_full_erange_junk(void)729 static void test_qemu_strtoi_full_erange_junk(void)
730 {
731     /* EINVAL has priority over ERANGE */
732     const char *str = "-9999999999junk";
733     int res = 999;
734     int err;
735 
736     err = qemu_strtoi(str, NULL, 0, &res);
737 
738     g_assert_cmpint(err, ==, -EINVAL);
739     g_assert_cmpint(res, ==, INT_MIN);
740 }
741 
test_qemu_strtoui_correct(void)742 static void test_qemu_strtoui_correct(void)
743 {
744     const char *str = "12345 foo";
745     char f = 'X';
746     const char *endptr = &f;
747     unsigned int res = 999;
748     int err;
749 
750     err = qemu_strtoui(str, &endptr, 0, &res);
751 
752     g_assert_cmpint(err, ==, 0);
753     g_assert_cmpuint(res, ==, 12345);
754     g_assert_true(endptr == str + 5);
755 }
756 
test_qemu_strtoui_null(void)757 static void test_qemu_strtoui_null(void)
758 {
759     char f = 'X';
760     const char *endptr = &f;
761     unsigned int res = 999;
762     int err;
763 
764     err = qemu_strtoui(NULL, &endptr, 0, &res);
765 
766     g_assert_cmpint(err, ==, -EINVAL);
767     g_assert_cmpuint(res, ==, 0);
768     g_assert_null(endptr);
769 }
770 
test_qemu_strtoui_empty(void)771 static void test_qemu_strtoui_empty(void)
772 {
773     const char *str = "";
774     char f = 'X';
775     const char *endptr = &f;
776     unsigned int res = 999;
777     int err;
778 
779     err = qemu_strtoui(str, &endptr, 0, &res);
780 
781     g_assert_cmpint(err, ==, -EINVAL);
782     g_assert_cmpuint(res, ==, 0);
783     g_assert_true(endptr == str);
784 }
785 
test_qemu_strtoui_whitespace(void)786 static void test_qemu_strtoui_whitespace(void)
787 {
788     const char *str = "  \t  ";
789     char f = 'X';
790     const char *endptr = &f;
791     unsigned int res = 999;
792     int err;
793 
794     err = qemu_strtoui(str, &endptr, 0, &res);
795 
796     g_assert_cmpint(err, ==, -EINVAL);
797     g_assert_cmpuint(res, ==, 0);
798     g_assert_true(endptr == str);
799 }
800 
test_qemu_strtoui_invalid(void)801 static void test_qemu_strtoui_invalid(void)
802 {
803     const char *str = "   xxxx  \t abc";
804     char f = 'X';
805     const char *endptr = &f;
806     unsigned int res = 999;
807     int err;
808 
809     err = qemu_strtoui(str, &endptr, 0, &res);
810 
811     g_assert_cmpint(err, ==, -EINVAL);
812     g_assert_cmpuint(res, ==, 0);
813     g_assert_true(endptr == str);
814 }
815 
test_qemu_strtoui_trailing(void)816 static void test_qemu_strtoui_trailing(void)
817 {
818     const char *str = "123xxx";
819     char f = 'X';
820     const char *endptr = &f;
821     unsigned int res = 999;
822     int err;
823 
824     err = qemu_strtoui(str, &endptr, 0, &res);
825 
826     g_assert_cmpint(err, ==, 0);
827     g_assert_cmpuint(res, ==, 123);
828     g_assert_true(endptr == str + 3);
829 }
830 
test_qemu_strtoui_octal(void)831 static void test_qemu_strtoui_octal(void)
832 {
833     const char *str = "0123";
834     char f = 'X';
835     const char *endptr = &f;
836     unsigned int res = 999;
837     int err;
838 
839     err = qemu_strtoui(str, &endptr, 8, &res);
840 
841     g_assert_cmpint(err, ==, 0);
842     g_assert_cmpuint(res, ==, 0123);
843     g_assert_true(endptr == str + strlen(str));
844 
845     res = 999;
846     endptr = &f;
847     err = qemu_strtoui(str, &endptr, 0, &res);
848 
849     g_assert_cmpint(err, ==, 0);
850     g_assert_cmpuint(res, ==, 0123);
851     g_assert_true(endptr == str + strlen(str));
852 }
853 
test_qemu_strtoui_decimal(void)854 static void test_qemu_strtoui_decimal(void)
855 {
856     const char *str = "0123";
857     char f = 'X';
858     const char *endptr = &f;
859     unsigned int res = 999;
860     int err;
861 
862     err = qemu_strtoui(str, &endptr, 10, &res);
863 
864     g_assert_cmpint(err, ==, 0);
865     g_assert_cmpuint(res, ==, 123);
866     g_assert_true(endptr == str + strlen(str));
867 
868     str = "123";
869     res = 999;
870     endptr = &f;
871     err = qemu_strtoui(str, &endptr, 0, &res);
872 
873     g_assert_cmpint(err, ==, 0);
874     g_assert_cmpuint(res, ==, 123);
875     g_assert_true(endptr == str + strlen(str));
876 }
877 
test_qemu_strtoui_hex(void)878 static void test_qemu_strtoui_hex(void)
879 {
880     const char *str = "0123";
881     char f = 'X';
882     const char *endptr = &f;
883     unsigned int res = 999;
884     int err;
885 
886     err = qemu_strtoui(str, &endptr, 16, &res);
887 
888     g_assert_cmpint(err, ==, 0);
889     g_assert_cmphex(res, ==, 0x123);
890     g_assert_true(endptr == str + strlen(str));
891 
892     str = "0x123";
893     res = 999;
894     endptr = &f;
895     err = qemu_strtoui(str, &endptr, 0, &res);
896 
897     g_assert_cmpint(err, ==, 0);
898     g_assert_cmphex(res, ==, 0x123);
899     g_assert_true(endptr == str + strlen(str));
900 
901     str = "0x";
902     res = 999;
903     endptr = &f;
904     err = qemu_strtoui(str, &endptr, 16, &res);
905 
906     g_assert_cmpint(err, ==, 0);
907     g_assert_cmphex(res, ==, 0);
908     g_assert_true(endptr == str + 1);
909 }
910 
test_qemu_strtoui_wrap(void)911 static void test_qemu_strtoui_wrap(void)
912 {
913     /* wraparound is consistent with 32-bit strtoul */
914     const char *str = "-4294967295"; /* 1 mod 2^32 */
915     char f = 'X';
916     const char *endptr = &f;
917     unsigned int res = 999;
918     int err;
919 
920     err = qemu_strtoui(str, &endptr, 0, &res);
921 
922     g_assert_cmpint(err, ==, 0);
923     g_assert_cmphex(res, ==, 1);
924     g_assert_true(endptr == str + strlen(str));
925 }
926 
test_qemu_strtoui_max(void)927 static void test_qemu_strtoui_max(void)
928 {
929     char *str = g_strdup_printf("%u", UINT_MAX);
930     char f = 'X';
931     const char *endptr = &f;
932     unsigned int res = 999;
933     int err;
934 
935     err = qemu_strtoui(str, &endptr, 0, &res);
936 
937     g_assert_cmpint(err, ==, 0);
938     g_assert_cmphex(res, ==, UINT_MAX);
939     g_assert_true(endptr == str + strlen(str));
940     g_free(str);
941 }
942 
test_qemu_strtoui_overflow(void)943 static void test_qemu_strtoui_overflow(void)
944 {
945     const char *str;
946     const char *endptr;
947     unsigned int res;
948     int err;
949 
950     str = "4294967296"; /* UINT_MAX + 1ll */
951     endptr = "somewhere";
952     res = 999;
953     err = qemu_strtoui(str, &endptr, 0, &res);
954     g_assert_cmpint(err, ==, -ERANGE);
955     g_assert_cmpuint(res, ==, UINT_MAX);
956     g_assert_true(endptr == str + strlen(str));
957 
958     str = "0x7fffffffffffffff"; /* LLONG_MAX */
959     endptr = "somewhere";
960     res = 999;
961     err = qemu_strtoui(str, &endptr, 0, &res);
962     g_assert_cmpint(err, ==, -ERANGE);
963     g_assert_cmpuint(res, ==, UINT_MAX);
964     g_assert_true(endptr == str + strlen(str));
965 
966     str = "0x8000000000000000"; /* (uint64_t)LLONG_MIN */
967     endptr = "somewhere";
968     res = 999;
969     err = qemu_strtoui(str, &endptr, 0, &res);
970     g_assert_cmpint(err, ==, -ERANGE);
971     g_assert_cmpuint(res, ==, UINT_MAX);
972     g_assert_true(endptr == str + strlen(str));
973 
974     str = "0xffffffff00000001"; /* ULLONG_MAX - UINT_MAX + 1 (not 1) */
975     endptr = "somewhere";
976     res = 999;
977     err = qemu_strtoui(str, &endptr, 0, &res);
978     g_assert_cmpint(err, ==, -ERANGE);
979     g_assert_cmpuint(res, ==, UINT_MAX);
980     g_assert_true(endptr == str + strlen(str));
981 
982     str = "0xfffffffffffffffe"; /* ULLONG_MAX - 1 (not UINT_MAX - 1) */
983     endptr = "somewhere";
984     res = 999;
985     err = qemu_strtoui(str, &endptr, 0, &res);
986     g_assert_cmpint(err, ==, -ERANGE);
987     g_assert_cmpuint(res, ==, UINT_MAX);
988     g_assert_true(endptr == str + strlen(str));
989 
990     str = "0x10000000000000000"; /* 65 bits, 32-bit sign bit clear */
991     endptr = "somewhere";
992     res = 999;
993     err = qemu_strtoui(str, &endptr, 0, &res);
994     g_assert_cmpint(err, ==, -ERANGE);
995     g_assert_cmpuint(res, ==, UINT_MAX);
996     g_assert_true(endptr == str + strlen(str));
997 
998     str = "0x18000000080000000"; /* 65 bits, 32-bit sign bit set */
999     endptr = "somewhere";
1000     res = 999;
1001     err = qemu_strtoui(str, &endptr, 0, &res);
1002     g_assert_cmpint(err, ==, -ERANGE);
1003     g_assert_cmpuint(res, ==, UINT_MAX);
1004     g_assert_true(endptr == str + strlen(str));
1005 }
1006 
test_qemu_strtoui_underflow(void)1007 static void test_qemu_strtoui_underflow(void)
1008 {
1009     const char *str;
1010     const char *endptr;
1011     unsigned int res;
1012     int err;
1013 
1014     str = "-4294967296"; /* -(long long)UINT_MAX - 1ll */
1015     endptr = "somewhere";
1016     res = 999;
1017     err = qemu_strtoui(str, &endptr, 0, &res);
1018     g_assert_cmpint(err, ==, -ERANGE);
1019     g_assert_cmpuint(res, ==, UINT_MAX);
1020     g_assert_true(endptr == str + strlen(str));
1021 
1022     str = "-18446744073709551615"; /* -UINT64_MAX (not -(-1)) */
1023     endptr = "somewhere";
1024     res = 999;
1025     err = qemu_strtoui(str, &endptr, 0, &res);
1026     g_assert_cmpint(err, ==, -ERANGE);
1027     g_assert_cmpuint(res, ==, UINT_MAX);
1028     g_assert_true(endptr == str + strlen(str));
1029 
1030     str = "-0xffffffff00000002";
1031     endptr = "somewhere";
1032     res = 999;
1033     err = qemu_strtoui(str, &endptr, 0, &res);
1034     g_assert_cmpint(err, ==, -ERANGE);
1035     g_assert_cmpuint(res, ==, UINT_MAX);
1036     g_assert_true(endptr == str + strlen(str));
1037 
1038     str = "-0x10000000000000000"; /* 65 bits, 32-bit sign bit clear */
1039     endptr = "somewhere";
1040     res = 999;
1041     err = qemu_strtoui(str, &endptr, 0, &res);
1042     g_assert_cmpint(err, ==, -ERANGE);
1043     g_assert_cmpuint(res, ==, UINT_MAX);
1044     g_assert_true(endptr == str + strlen(str));
1045 
1046     str = "-0x18000000080000000"; /* 65 bits, 32-bit sign bit set */
1047     endptr = "somewhere";
1048     res = 999;
1049     err = qemu_strtoui(str, &endptr, 0, &res);
1050     g_assert_cmpint(err, ==, -ERANGE);
1051     g_assert_cmpuint(res, ==, UINT_MAX);
1052     g_assert_true(endptr == str + strlen(str));
1053 }
1054 
test_qemu_strtoui_negative(void)1055 static void test_qemu_strtoui_negative(void)
1056 {
1057     const char *str = "  \t -321";
1058     char f = 'X';
1059     const char *endptr = &f;
1060     unsigned int res = 999;
1061     int err;
1062 
1063     err = qemu_strtoui(str, &endptr, 0, &res);
1064 
1065     g_assert_cmpint(err, ==, 0);
1066     g_assert_cmpuint(res, ==, (unsigned int)-321);
1067     g_assert_true(endptr == str + strlen(str));
1068 }
1069 
test_qemu_strtoui_negzero(void)1070 static void test_qemu_strtoui_negzero(void)
1071 {
1072     const char *str = " -0";
1073     char f = 'X';
1074     const char *endptr = &f;
1075     unsigned int res = 999;
1076     int err;
1077 
1078     err = qemu_strtoui(str, &endptr, 0, &res);
1079 
1080     g_assert_cmpint(err, ==, 0);
1081     g_assert_cmpuint(res, ==, 0);
1082     g_assert_true(endptr == str + strlen(str));
1083 }
1084 
test_qemu_strtoui_full_correct(void)1085 static void test_qemu_strtoui_full_correct(void)
1086 {
1087     const char *str = "123";
1088     unsigned int res = 999;
1089     int err;
1090 
1091     err = qemu_strtoui(str, NULL, 0, &res);
1092 
1093     g_assert_cmpint(err, ==, 0);
1094     g_assert_cmpuint(res, ==, 123);
1095 }
1096 
test_qemu_strtoui_full_null(void)1097 static void test_qemu_strtoui_full_null(void)
1098 {
1099     unsigned int res = 999;
1100     int err;
1101 
1102     err = qemu_strtoui(NULL, NULL, 0, &res);
1103 
1104     g_assert_cmpint(err, ==, -EINVAL);
1105     g_assert_cmpuint(res, ==, 0);
1106 }
1107 
test_qemu_strtoui_full_empty(void)1108 static void test_qemu_strtoui_full_empty(void)
1109 {
1110     const char *str = "";
1111     unsigned int res = 999;
1112     int err;
1113 
1114     err = qemu_strtoui(str, NULL, 0, &res);
1115 
1116     g_assert_cmpint(err, ==, -EINVAL);
1117     g_assert_cmpuint(res, ==, 0);
1118 }
1119 
test_qemu_strtoui_full_negative(void)1120 static void test_qemu_strtoui_full_negative(void)
1121 {
1122     const char *str = " \t -321";
1123     unsigned int res = 999;
1124     int err;
1125 
1126     err = qemu_strtoui(str, NULL, 0, &res);
1127     g_assert_cmpint(err, ==, 0);
1128     g_assert_cmpuint(res, ==, (unsigned int)-321);
1129 }
1130 
test_qemu_strtoui_full_negzero(void)1131 static void test_qemu_strtoui_full_negzero(void)
1132 {
1133     const char *str = " -0";
1134     unsigned int res = 999;
1135     int err;
1136 
1137     err = qemu_strtoui(str, NULL, 0, &res);
1138     g_assert_cmpint(err, ==, 0);
1139     g_assert_cmpuint(res, ==, 0);
1140 }
1141 
test_qemu_strtoui_full_trailing(void)1142 static void test_qemu_strtoui_full_trailing(void)
1143 {
1144     const char *str = "123xxx";
1145     unsigned int res = 999;
1146     int err;
1147 
1148     err = qemu_strtoui(str, NULL, 0, &res);
1149 
1150     g_assert_cmpint(err, ==, -EINVAL);
1151     g_assert_cmpuint(res, ==, 123);
1152 }
1153 
test_qemu_strtoui_full_max(void)1154 static void test_qemu_strtoui_full_max(void)
1155 {
1156     char *str = g_strdup_printf("%u", UINT_MAX);
1157     unsigned int res = 999;
1158     int err;
1159 
1160     err = qemu_strtoui(str, NULL, 0, &res);
1161 
1162     g_assert_cmpint(err, ==, 0);
1163     g_assert_cmphex(res, ==, UINT_MAX);
1164     g_free(str);
1165 }
1166 
test_qemu_strtoui_full_erange_junk(void)1167 static void test_qemu_strtoui_full_erange_junk(void)
1168 {
1169     /* EINVAL has priority over ERANGE */
1170     const char *str = "-9999999999junk";
1171     unsigned int res = 999;
1172     int err;
1173 
1174     err = qemu_strtoui(str, NULL, 0, &res);
1175 
1176     g_assert_cmpint(err, ==, -EINVAL);
1177     g_assert_cmpuint(res, ==, UINT_MAX);
1178 }
1179 
test_qemu_strtol_correct(void)1180 static void test_qemu_strtol_correct(void)
1181 {
1182     const char *str = "12345 foo";
1183     char f = 'X';
1184     const char *endptr = &f;
1185     long res = 999;
1186     int err;
1187 
1188     err = qemu_strtol(str, &endptr, 0, &res);
1189 
1190     g_assert_cmpint(err, ==, 0);
1191     g_assert_cmpint(res, ==, 12345);
1192     g_assert_true(endptr == str + 5);
1193 }
1194 
test_qemu_strtol_null(void)1195 static void test_qemu_strtol_null(void)
1196 {
1197     char f = 'X';
1198     const char *endptr = &f;
1199     long res = 999;
1200     int err;
1201 
1202     err = qemu_strtol(NULL, &endptr, 0, &res);
1203 
1204     g_assert_cmpint(err, ==, -EINVAL);
1205     g_assert_cmpint(res, ==, 0);
1206     g_assert_null(endptr);
1207 }
1208 
test_qemu_strtol_empty(void)1209 static void test_qemu_strtol_empty(void)
1210 {
1211     const char *str = "";
1212     char f = 'X';
1213     const char *endptr = &f;
1214     long res = 999;
1215     int err;
1216 
1217     err = qemu_strtol(str, &endptr, 0, &res);
1218 
1219     g_assert_cmpint(err, ==, -EINVAL);
1220     g_assert_cmpint(res, ==, 0);
1221     g_assert_true(endptr == str);
1222 }
1223 
test_qemu_strtol_whitespace(void)1224 static void test_qemu_strtol_whitespace(void)
1225 {
1226     const char *str = "  \t  ";
1227     char f = 'X';
1228     const char *endptr = &f;
1229     long res = 999;
1230     int err;
1231 
1232     err = qemu_strtol(str, &endptr, 0, &res);
1233 
1234     g_assert_cmpint(err, ==, -EINVAL);
1235     g_assert_cmpint(res, ==, 0);
1236     g_assert_true(endptr == str);
1237 }
1238 
test_qemu_strtol_invalid(void)1239 static void test_qemu_strtol_invalid(void)
1240 {
1241     const char *str = "   xxxx  \t abc";
1242     char f = 'X';
1243     const char *endptr = &f;
1244     long res = 999;
1245     int err;
1246 
1247     err = qemu_strtol(str, &endptr, 0, &res);
1248 
1249     g_assert_cmpint(err, ==, -EINVAL);
1250     g_assert_cmpint(res, ==, 0);
1251     g_assert_true(endptr == str);
1252 }
1253 
test_qemu_strtol_trailing(void)1254 static void test_qemu_strtol_trailing(void)
1255 {
1256     const char *str = "123xxx";
1257     char f = 'X';
1258     const char *endptr = &f;
1259     long res = 999;
1260     int err;
1261 
1262     err = qemu_strtol(str, &endptr, 0, &res);
1263 
1264     g_assert_cmpint(err, ==, 0);
1265     g_assert_cmpint(res, ==, 123);
1266     g_assert_true(endptr == str + 3);
1267 }
1268 
test_qemu_strtol_octal(void)1269 static void test_qemu_strtol_octal(void)
1270 {
1271     const char *str = "0123";
1272     char f = 'X';
1273     const char *endptr = &f;
1274     long res = 999;
1275     int err;
1276 
1277     err = qemu_strtol(str, &endptr, 8, &res);
1278 
1279     g_assert_cmpint(err, ==, 0);
1280     g_assert_cmpint(res, ==, 0123);
1281     g_assert_true(endptr == str + strlen(str));
1282 
1283     res = 999;
1284     endptr = &f;
1285     err = qemu_strtol(str, &endptr, 0, &res);
1286 
1287     g_assert_cmpint(err, ==, 0);
1288     g_assert_cmpint(res, ==, 0123);
1289     g_assert_true(endptr == str + strlen(str));
1290 }
1291 
test_qemu_strtol_decimal(void)1292 static void test_qemu_strtol_decimal(void)
1293 {
1294     const char *str = "0123";
1295     char f = 'X';
1296     const char *endptr = &f;
1297     long res = 999;
1298     int err;
1299 
1300     err = qemu_strtol(str, &endptr, 10, &res);
1301 
1302     g_assert_cmpint(err, ==, 0);
1303     g_assert_cmpint(res, ==, 123);
1304     g_assert_true(endptr == str + strlen(str));
1305 
1306     str = "123";
1307     res = 999;
1308     endptr = &f;
1309     err = qemu_strtol(str, &endptr, 0, &res);
1310 
1311     g_assert_cmpint(err, ==, 0);
1312     g_assert_cmpint(res, ==, 123);
1313     g_assert_true(endptr == str + strlen(str));
1314 }
1315 
test_qemu_strtol_hex(void)1316 static void test_qemu_strtol_hex(void)
1317 {
1318     const char *str = "0123";
1319     char f = 'X';
1320     const char *endptr = &f;
1321     long res = 999;
1322     int err;
1323 
1324     err = qemu_strtol(str, &endptr, 16, &res);
1325 
1326     g_assert_cmpint(err, ==, 0);
1327     g_assert_cmpint(res, ==, 0x123);
1328     g_assert_true(endptr == str + strlen(str));
1329 
1330     str = "0x123";
1331     res = 999;
1332     endptr = &f;
1333     err = qemu_strtol(str, &endptr, 0, &res);
1334 
1335     g_assert_cmpint(err, ==, 0);
1336     g_assert_cmpint(res, ==, 0x123);
1337     g_assert_true(endptr == str + strlen(str));
1338 
1339     str = "0x";
1340     res = 999;
1341     endptr = &f;
1342     err = qemu_strtol(str, &endptr, 16, &res);
1343 
1344     g_assert_cmpint(err, ==, 0);
1345     g_assert_cmpint(res, ==, 0);
1346     g_assert_true(endptr == str + 1);
1347 }
1348 
test_qemu_strtol_max(void)1349 static void test_qemu_strtol_max(void)
1350 {
1351     char *str = g_strdup_printf("%ld", LONG_MAX);
1352     char f = 'X';
1353     const char *endptr = &f;
1354     long res = 999;
1355     int err;
1356 
1357     err = qemu_strtol(str, &endptr, 0, &res);
1358 
1359     g_assert_cmpint(err, ==, 0);
1360     g_assert_cmpint(res, ==, LONG_MAX);
1361     g_assert_true(endptr == str + strlen(str));
1362     g_free(str);
1363 }
1364 
test_qemu_strtol_overflow(void)1365 static void test_qemu_strtol_overflow(void)
1366 {
1367     const char *str;
1368     const char *endptr;
1369     long res;
1370     int err;
1371 
1372     /* 1 more than LONG_MAX */
1373     str = LONG_MAX == INT_MAX ? "2147483648" : "9223372036854775808";
1374     endptr = "somewhere";
1375     res = 999;
1376     err = qemu_strtol(str, &endptr, 0, &res);
1377     g_assert_cmpint(err, ==, -ERANGE);
1378     g_assert_cmpint(res, ==, LONG_MAX);
1379     g_assert_true(endptr == str + strlen(str));
1380 
1381     if (LONG_MAX == INT_MAX) {
1382         str = "0xffffffff00000001"; /* ULLONG_MAX - UINT_MAX + 1 (not 1) */
1383         endptr = "somewhere";
1384         res = 999;
1385         err = qemu_strtol(str, &endptr, 0, &res);
1386         g_assert_cmpint(err, ==, -ERANGE);
1387         g_assert_cmpint(res, ==, LONG_MAX);
1388         g_assert_true(endptr == str + strlen(str));
1389     }
1390 
1391     str = "0x10000000000000000"; /* 65 bits, either sign bit position clear */
1392     endptr = "somewhere";
1393     res = 999;
1394     err = qemu_strtol(str, &endptr, 0, &res);
1395     g_assert_cmpint(err, ==, -ERANGE);
1396     g_assert_cmpint(res, ==, LONG_MAX);
1397     g_assert_true(endptr == str + strlen(str));
1398 
1399     str = "0x18000000080000000"; /* 65 bits, either sign bit position set */
1400     endptr = "somewhere";
1401     res = 999;
1402     err = qemu_strtol(str, &endptr, 0, &res);
1403     g_assert_cmpint(err, ==, -ERANGE);
1404     g_assert_cmpint(res, ==, LONG_MAX);
1405     g_assert_true(endptr == str + strlen(str));
1406 }
1407 
test_qemu_strtol_min(void)1408 static void test_qemu_strtol_min(void)
1409 {
1410     char *str = g_strdup_printf("%ld", LONG_MIN);
1411     char f = 'X';
1412     const char *endptr = &f;
1413     long res = 999;
1414     int err;
1415 
1416     err = qemu_strtol(str, &endptr, 0, &res);
1417 
1418     g_assert_cmpint(err, ==, 0);
1419     g_assert_cmpint(res, ==, LONG_MIN);
1420     g_assert_true(endptr == str + strlen(str));
1421     g_free(str);
1422 }
1423 
test_qemu_strtol_underflow(void)1424 static void test_qemu_strtol_underflow(void)
1425 {
1426     const char *str;
1427     const char *endptr;
1428     long res;
1429     int err;
1430 
1431     /* 1 less than LONG_MIN */
1432     str = LONG_MIN == INT_MIN ? "-2147483649" : "-9223372036854775809";
1433     endptr = "somewhere";
1434     res = 999;
1435     err = qemu_strtol(str, &endptr, 0, &res);
1436     g_assert_cmpint(err, ==, -ERANGE);
1437     g_assert_cmpint(res, ==, LONG_MIN);
1438     g_assert_true(endptr == str + strlen(str));
1439 
1440     if (LONG_MAX == INT_MAX) {
1441         str = "-18446744073709551615"; /* -UINT64_MAX (not 1) */
1442         endptr = "somewhere";
1443         res = 999;
1444         err = qemu_strtol(str, &endptr, 0, &res);
1445         g_assert_cmpint(err, ==, -ERANGE);
1446         g_assert_cmpint(res, ==, LONG_MIN);
1447         g_assert_true(endptr == str + strlen(str));
1448     }
1449 
1450     str = "-0x10000000000000000"; /* 65 bits, either sign bit position clear */
1451     endptr = "somewhere";
1452     res = 999;
1453     err = qemu_strtol(str, &endptr, 0, &res);
1454     g_assert_cmpint(err, ==, -ERANGE);
1455     g_assert_cmpint(res, ==, LONG_MIN);
1456     g_assert_true(endptr == str + strlen(str));
1457 
1458     str = "-0x18000000080000000"; /* 65 bits, either sign bit position set */
1459     endptr = "somewhere";
1460     res = 999;
1461     err = qemu_strtol(str, &endptr, 0, &res);
1462     g_assert_cmpint(err, ==, -ERANGE);
1463     g_assert_cmpint(res, ==, LONG_MIN);
1464     g_assert_true(endptr == str + strlen(str));
1465 }
1466 
test_qemu_strtol_negative(void)1467 static void test_qemu_strtol_negative(void)
1468 {
1469     const char *str = "  \t -321";
1470     char f = 'X';
1471     const char *endptr = &f;
1472     long res = 999;
1473     int err;
1474 
1475     err = qemu_strtol(str, &endptr, 0, &res);
1476 
1477     g_assert_cmpint(err, ==, 0);
1478     g_assert_cmpint(res, ==, -321);
1479     g_assert_true(endptr == str + strlen(str));
1480 }
1481 
test_qemu_strtol_negzero(void)1482 static void test_qemu_strtol_negzero(void)
1483 {
1484     const char *str = " -0";
1485     char f = 'X';
1486     const char *endptr = &f;
1487     long res = 999;
1488     int err;
1489 
1490     err = qemu_strtol(str, &endptr, 0, &res);
1491 
1492     g_assert_cmpint(err, ==, 0);
1493     g_assert_cmpint(res, ==, 0);
1494     g_assert_true(endptr == str + strlen(str));
1495 }
1496 
test_qemu_strtol_full_correct(void)1497 static void test_qemu_strtol_full_correct(void)
1498 {
1499     const char *str = "123";
1500     long res = 999;
1501     int err;
1502 
1503     err = qemu_strtol(str, NULL, 0, &res);
1504 
1505     g_assert_cmpint(err, ==, 0);
1506     g_assert_cmpint(res, ==, 123);
1507 }
1508 
test_qemu_strtol_full_null(void)1509 static void test_qemu_strtol_full_null(void)
1510 {
1511     char f = 'X';
1512     const char *endptr = &f;
1513     long res = 999;
1514     int err;
1515 
1516     err = qemu_strtol(NULL, &endptr, 0, &res);
1517 
1518     g_assert_cmpint(err, ==, -EINVAL);
1519     g_assert_cmpint(res, ==, 0);
1520     g_assert_null(endptr);
1521 }
1522 
test_qemu_strtol_full_empty(void)1523 static void test_qemu_strtol_full_empty(void)
1524 {
1525     const char *str = "";
1526     long res = 999L;
1527     int err;
1528 
1529     err = qemu_strtol(str, NULL, 0, &res);
1530 
1531     g_assert_cmpint(err, ==, -EINVAL);
1532     g_assert_cmpint(res, ==, 0);
1533 }
1534 
test_qemu_strtol_full_negative(void)1535 static void test_qemu_strtol_full_negative(void)
1536 {
1537     const char *str = " \t -321";
1538     long res = 999;
1539     int err;
1540 
1541     err = qemu_strtol(str, NULL, 0, &res);
1542 
1543     g_assert_cmpint(err, ==, 0);
1544     g_assert_cmpint(res, ==, -321);
1545 }
1546 
test_qemu_strtol_full_negzero(void)1547 static void test_qemu_strtol_full_negzero(void)
1548 {
1549     const char *str = " -0";
1550     long res = 999;
1551     int err;
1552 
1553     err = qemu_strtol(str, NULL, 0, &res);
1554 
1555     g_assert_cmpint(err, ==, 0);
1556     g_assert_cmpint(res, ==, 0);
1557 }
1558 
test_qemu_strtol_full_trailing(void)1559 static void test_qemu_strtol_full_trailing(void)
1560 {
1561     const char *str = "123xxx";
1562     long res = 999;
1563     int err;
1564 
1565     err = qemu_strtol(str, NULL, 0, &res);
1566 
1567     g_assert_cmpint(err, ==, -EINVAL);
1568     g_assert_cmpint(res, ==, 123);
1569 }
1570 
test_qemu_strtol_full_max(void)1571 static void test_qemu_strtol_full_max(void)
1572 {
1573     char *str = g_strdup_printf("%ld", LONG_MAX);
1574     long res = 999;
1575     int err;
1576 
1577     err = qemu_strtol(str, NULL, 0, &res);
1578 
1579     g_assert_cmpint(err, ==, 0);
1580     g_assert_cmpint(res, ==, LONG_MAX);
1581     g_free(str);
1582 }
1583 
test_qemu_strtol_full_erange_junk(void)1584 static void test_qemu_strtol_full_erange_junk(void)
1585 {
1586     /* EINVAL has priority over ERANGE */
1587     const char *str = "-99999999999999999999junk";
1588     long res = 999;
1589     int err;
1590 
1591     err = qemu_strtol(str, NULL, 0, &res);
1592 
1593     g_assert_cmpint(err, ==, -EINVAL);
1594     g_assert_cmpint(res, ==, LONG_MIN);
1595 }
1596 
test_qemu_strtoul_correct(void)1597 static void test_qemu_strtoul_correct(void)
1598 {
1599     const char *str = "12345 foo";
1600     char f = 'X';
1601     const char *endptr = &f;
1602     unsigned long res = 999;
1603     int err;
1604 
1605     err = qemu_strtoul(str, &endptr, 0, &res);
1606 
1607     g_assert_cmpint(err, ==, 0);
1608     g_assert_cmpuint(res, ==, 12345);
1609     g_assert_true(endptr == str + 5);
1610 }
1611 
test_qemu_strtoul_null(void)1612 static void test_qemu_strtoul_null(void)
1613 {
1614     char f = 'X';
1615     const char *endptr = &f;
1616     unsigned long res = 999;
1617     int err;
1618 
1619     err = qemu_strtoul(NULL, &endptr, 0, &res);
1620 
1621     g_assert_cmpint(err, ==, -EINVAL);
1622     g_assert_cmpuint(res, ==, 0);
1623     g_assert_null(endptr);
1624 }
1625 
test_qemu_strtoul_empty(void)1626 static void test_qemu_strtoul_empty(void)
1627 {
1628     const char *str = "";
1629     char f = 'X';
1630     const char *endptr = &f;
1631     unsigned long res = 999;
1632     int err;
1633 
1634     err = qemu_strtoul(str, &endptr, 0, &res);
1635 
1636     g_assert_cmpint(err, ==, -EINVAL);
1637     g_assert_cmpuint(res, ==, 0);
1638     g_assert_true(endptr == str);
1639 }
1640 
test_qemu_strtoul_whitespace(void)1641 static void test_qemu_strtoul_whitespace(void)
1642 {
1643     const char *str = "  \t  ";
1644     char f = 'X';
1645     const char *endptr = &f;
1646     unsigned long res = 999;
1647     int err;
1648 
1649     err = qemu_strtoul(str, &endptr, 0, &res);
1650 
1651     g_assert_cmpint(err, ==, -EINVAL);
1652     g_assert_cmpuint(res, ==, 0);
1653     g_assert_true(endptr == str);
1654 }
1655 
test_qemu_strtoul_invalid(void)1656 static void test_qemu_strtoul_invalid(void)
1657 {
1658     const char *str = "   xxxx  \t abc";
1659     char f = 'X';
1660     const char *endptr = &f;
1661     unsigned long res = 999;
1662     int err;
1663 
1664     err = qemu_strtoul(str, &endptr, 0, &res);
1665 
1666     g_assert_cmpint(err, ==, -EINVAL);
1667     g_assert_cmpuint(res, ==, 0);
1668     g_assert_true(endptr == str);
1669 }
1670 
test_qemu_strtoul_trailing(void)1671 static void test_qemu_strtoul_trailing(void)
1672 {
1673     const char *str = "123xxx";
1674     char f = 'X';
1675     const char *endptr = &f;
1676     unsigned long res = 999;
1677     int err;
1678 
1679     err = qemu_strtoul(str, &endptr, 0, &res);
1680 
1681     g_assert_cmpint(err, ==, 0);
1682     g_assert_cmpuint(res, ==, 123);
1683     g_assert_true(endptr == str + 3);
1684 }
1685 
test_qemu_strtoul_octal(void)1686 static void test_qemu_strtoul_octal(void)
1687 {
1688     const char *str = "0123";
1689     char f = 'X';
1690     const char *endptr = &f;
1691     unsigned long res = 999;
1692     int err;
1693 
1694     err = qemu_strtoul(str, &endptr, 8, &res);
1695 
1696     g_assert_cmpint(err, ==, 0);
1697     g_assert_cmpuint(res, ==, 0123);
1698     g_assert_true(endptr == str + strlen(str));
1699 
1700     res = 999;
1701     endptr = &f;
1702     err = qemu_strtoul(str, &endptr, 0, &res);
1703 
1704     g_assert_cmpint(err, ==, 0);
1705     g_assert_cmpuint(res, ==, 0123);
1706     g_assert_true(endptr == str + strlen(str));
1707 }
1708 
test_qemu_strtoul_decimal(void)1709 static void test_qemu_strtoul_decimal(void)
1710 {
1711     const char *str = "0123";
1712     char f = 'X';
1713     const char *endptr = &f;
1714     unsigned long res = 999;
1715     int err;
1716 
1717     err = qemu_strtoul(str, &endptr, 10, &res);
1718 
1719     g_assert_cmpint(err, ==, 0);
1720     g_assert_cmpuint(res, ==, 123);
1721     g_assert_true(endptr == str + strlen(str));
1722 
1723     str = "123";
1724     res = 999;
1725     endptr = &f;
1726     err = qemu_strtoul(str, &endptr, 0, &res);
1727 
1728     g_assert_cmpint(err, ==, 0);
1729     g_assert_cmpuint(res, ==, 123);
1730     g_assert_true(endptr == str + strlen(str));
1731 }
1732 
test_qemu_strtoul_hex(void)1733 static void test_qemu_strtoul_hex(void)
1734 {
1735     const char *str = "0123";
1736     char f = 'X';
1737     const char *endptr = &f;
1738     unsigned long res = 999;
1739     int err;
1740 
1741     err = qemu_strtoul(str, &endptr, 16, &res);
1742 
1743     g_assert_cmpint(err, ==, 0);
1744     g_assert_cmphex(res, ==, 0x123);
1745     g_assert_true(endptr == str + strlen(str));
1746 
1747     str = "0x123";
1748     res = 999;
1749     endptr = &f;
1750     err = qemu_strtoul(str, &endptr, 0, &res);
1751 
1752     g_assert_cmpint(err, ==, 0);
1753     g_assert_cmphex(res, ==, 0x123);
1754     g_assert_true(endptr == str + strlen(str));
1755 
1756     str = "0x";
1757     res = 999;
1758     endptr = &f;
1759     err = qemu_strtoul(str, &endptr, 16, &res);
1760 
1761     g_assert_cmpint(err, ==, 0);
1762     g_assert_cmphex(res, ==, 0);
1763     g_assert_true(endptr == str + 1);
1764 }
1765 
test_qemu_strtoul_wrap(void)1766 static void test_qemu_strtoul_wrap(void)
1767 {
1768     const char *str;
1769     char f = 'X';
1770     const char *endptr = &f;
1771     unsigned long res = 999;
1772     int err;
1773 
1774     /* 1 mod 2^(sizeof(long)*8) */
1775     str = LONG_MAX == INT_MAX ? "-4294967295" : "-18446744073709551615";
1776     err = qemu_strtoul(str, &endptr, 0, &res);
1777 
1778     g_assert_cmpint(err, ==, 0);
1779     g_assert_cmphex(res, ==, 1);
1780     g_assert_true(endptr == str + strlen(str));
1781 }
1782 
test_qemu_strtoul_max(void)1783 static void test_qemu_strtoul_max(void)
1784 {
1785     char *str = g_strdup_printf("%lu", ULONG_MAX);
1786     char f = 'X';
1787     const char *endptr = &f;
1788     unsigned long res = 999;
1789     int err;
1790 
1791     err = qemu_strtoul(str, &endptr, 0, &res);
1792 
1793     g_assert_cmpint(err, ==, 0);
1794     g_assert_cmphex(res, ==, ULONG_MAX);
1795     g_assert_true(endptr == str + strlen(str));
1796     g_free(str);
1797 }
1798 
test_qemu_strtoul_overflow(void)1799 static void test_qemu_strtoul_overflow(void)
1800 {
1801     const char *str;
1802     const char *endptr;
1803     unsigned long res;
1804     int err;
1805 
1806     /* 1 more than ULONG_MAX */
1807     str = ULONG_MAX == UINT_MAX ? "4294967296" : "18446744073709551616";
1808     endptr = "somewhere";
1809     res = 999;
1810     err = qemu_strtoul(str, &endptr, 0, &res);
1811     g_assert_cmpint(err, ==, -ERANGE);
1812     g_assert_cmpuint(res, ==, ULONG_MAX);
1813     g_assert_true(endptr == str + strlen(str));
1814 
1815     if (LONG_MAX == INT_MAX) {
1816         str = "0xffffffff00000001"; /* UINT64_MAX - UINT_MAX + 1 (not 1) */
1817         endptr = "somewhere";
1818         res = 999;
1819         err = qemu_strtoul(str, &endptr, 0, &res);
1820         g_assert_cmpint(err, ==, -ERANGE);
1821         g_assert_cmpuint(res, ==, ULONG_MAX);
1822         g_assert_true(endptr == str + strlen(str));
1823     }
1824 
1825     str = "0x10000000000000000"; /* 65 bits, either sign bit position clear */
1826     endptr = "somewhere";
1827     res = 999;
1828     err = qemu_strtoul(str, &endptr, 0, &res);
1829     g_assert_cmpint(err, ==, -ERANGE);
1830     g_assert_cmpuint(res, ==, ULONG_MAX);
1831     g_assert_true(endptr == str + strlen(str));
1832 
1833     str = "0x18000000080000000"; /* 65 bits, either sign bit position set */
1834     endptr = "somewhere";
1835     res = 999;
1836     err = qemu_strtoul(str, &endptr, 0, &res);
1837     g_assert_cmpint(err, ==, -ERANGE);
1838     g_assert_cmpuint(res, ==, ULONG_MAX);
1839     g_assert_true(endptr == str + strlen(str));
1840 }
1841 
test_qemu_strtoul_underflow(void)1842 static void test_qemu_strtoul_underflow(void)
1843 {
1844     const char *str;
1845     const char *endptr;
1846     unsigned long res;
1847     int err;
1848 
1849     /* 1 less than -ULONG_MAX */
1850     str = ULONG_MAX == UINT_MAX ? "-4294967296" : "-18446744073709551616";
1851     endptr = "somewhere";
1852     res = 999;
1853     err = qemu_strtoul(str, &endptr, 0, &res);
1854     g_assert_cmpint(err, ==, -ERANGE);
1855     g_assert_cmpuint(res, ==, ULONG_MAX);
1856     g_assert_true(endptr == str + strlen(str));
1857 
1858     if (LONG_MAX == INT_MAX) {
1859         str = "-0xffffffff00000002";
1860         endptr = "somewhere";
1861         res = 999;
1862         err = qemu_strtoul(str, &endptr, 0, &res);
1863         g_assert_cmpint(err, ==, -ERANGE);
1864         g_assert_cmpuint(res, ==, ULONG_MAX);
1865         g_assert_true(endptr == str + strlen(str));
1866     }
1867 
1868     str = "-0x10000000000000000"; /* 65 bits, either sign bit position clear */
1869     endptr = "somewhere";
1870     res = 999;
1871     err = qemu_strtoul(str, &endptr, 0, &res);
1872     g_assert_cmpint(err, ==, -ERANGE);
1873     g_assert_cmpuint(res, ==, ULONG_MAX);
1874     g_assert_true(endptr == str + strlen(str));
1875 
1876     str = "-0x18000000080000000"; /* 65 bits, either sign bit position set */
1877     endptr = "somewhere";
1878     res = 999;
1879     err = qemu_strtoul(str, &endptr, 0, &res);
1880     g_assert_cmpint(err, ==, -ERANGE);
1881     g_assert_cmpuint(res, ==, ULONG_MAX);
1882     g_assert_true(endptr == str + strlen(str));
1883 }
1884 
test_qemu_strtoul_negative(void)1885 static void test_qemu_strtoul_negative(void)
1886 {
1887     const char *str = "  \t -321";
1888     char f = 'X';
1889     const char *endptr = &f;
1890     unsigned long res = 999;
1891     int err;
1892 
1893     err = qemu_strtoul(str, &endptr, 0, &res);
1894 
1895     g_assert_cmpint(err, ==, 0);
1896     g_assert_cmpuint(res, ==, -321ul);
1897     g_assert_true(endptr == str + strlen(str));
1898 }
1899 
test_qemu_strtoul_negzero(void)1900 static void test_qemu_strtoul_negzero(void)
1901 {
1902     const char *str = " -0";
1903     char f = 'X';
1904     const char *endptr = &f;
1905     unsigned long res = 999;
1906     int err;
1907 
1908     err = qemu_strtoul(str, &endptr, 0, &res);
1909 
1910     g_assert_cmpint(err, ==, 0);
1911     g_assert_cmpuint(res, ==, 0);
1912     g_assert_true(endptr == str + strlen(str));
1913 }
1914 
test_qemu_strtoul_full_correct(void)1915 static void test_qemu_strtoul_full_correct(void)
1916 {
1917     const char *str = "123";
1918     unsigned long res = 999;
1919     int err;
1920 
1921     err = qemu_strtoul(str, NULL, 0, &res);
1922 
1923     g_assert_cmpint(err, ==, 0);
1924     g_assert_cmpuint(res, ==, 123);
1925 }
1926 
test_qemu_strtoul_full_null(void)1927 static void test_qemu_strtoul_full_null(void)
1928 {
1929     unsigned long res = 999;
1930     int err;
1931 
1932     err = qemu_strtoul(NULL, NULL, 0, &res);
1933 
1934     g_assert_cmpint(err, ==, -EINVAL);
1935     g_assert_cmpuint(res, ==, 0);
1936 }
1937 
test_qemu_strtoul_full_empty(void)1938 static void test_qemu_strtoul_full_empty(void)
1939 {
1940     const char *str = "";
1941     unsigned long res = 999;
1942     int err;
1943 
1944     err = qemu_strtoul(str, NULL, 0, &res);
1945 
1946     g_assert_cmpint(err, ==, -EINVAL);
1947     g_assert_cmpuint(res, ==, 0);
1948 }
1949 
test_qemu_strtoul_full_negative(void)1950 static void test_qemu_strtoul_full_negative(void)
1951 {
1952     const char *str = " \t -321";
1953     unsigned long res = 999;
1954     int err;
1955 
1956     err = qemu_strtoul(str, NULL, 0, &res);
1957     g_assert_cmpint(err, ==, 0);
1958     g_assert_cmpuint(res, ==, -321ul);
1959 }
1960 
test_qemu_strtoul_full_negzero(void)1961 static void test_qemu_strtoul_full_negzero(void)
1962 {
1963     const char *str = " -0";
1964     unsigned long res = 999;
1965     int err;
1966 
1967     err = qemu_strtoul(str, NULL, 0, &res);
1968     g_assert_cmpint(err, ==, 0);
1969     g_assert_cmpuint(res, ==, 0);
1970 }
1971 
test_qemu_strtoul_full_trailing(void)1972 static void test_qemu_strtoul_full_trailing(void)
1973 {
1974     const char *str = "123xxx";
1975     unsigned long res = 999;
1976     int err;
1977 
1978     err = qemu_strtoul(str, NULL, 0, &res);
1979 
1980     g_assert_cmpint(err, ==, -EINVAL);
1981     g_assert_cmpuint(res, ==, 123);
1982 }
1983 
test_qemu_strtoul_full_max(void)1984 static void test_qemu_strtoul_full_max(void)
1985 {
1986     char *str = g_strdup_printf("%lu", ULONG_MAX);
1987     unsigned long res = 999;
1988     int err;
1989 
1990     err = qemu_strtoul(str, NULL, 0, &res);
1991 
1992     g_assert_cmpint(err, ==, 0);
1993     g_assert_cmphex(res, ==, ULONG_MAX);
1994     g_free(str);
1995 }
1996 
test_qemu_strtoul_full_erange_junk(void)1997 static void test_qemu_strtoul_full_erange_junk(void)
1998 {
1999     /* EINVAL has priority over ERANGE */
2000     const char *str = "-99999999999999999999junk";
2001     unsigned long res = 999;
2002     int err;
2003 
2004     err = qemu_strtoul(str, NULL, 0, &res);
2005 
2006     g_assert_cmpint(err, ==, -EINVAL);
2007     g_assert_cmpuint(res, ==, ULONG_MAX);
2008 }
2009 
test_qemu_strtoi64_correct(void)2010 static void test_qemu_strtoi64_correct(void)
2011 {
2012     const char *str = "12345 foo";
2013     char f = 'X';
2014     const char *endptr = &f;
2015     int64_t res = 999;
2016     int err;
2017 
2018     err = qemu_strtoi64(str, &endptr, 0, &res);
2019 
2020     g_assert_cmpint(err, ==, 0);
2021     g_assert_cmpint(res, ==, 12345);
2022     g_assert_true(endptr == str + 5);
2023 }
2024 
test_qemu_strtoi64_null(void)2025 static void test_qemu_strtoi64_null(void)
2026 {
2027     char f = 'X';
2028     const char *endptr = &f;
2029     int64_t res = 999;
2030     int err;
2031 
2032     err = qemu_strtoi64(NULL, &endptr, 0, &res);
2033 
2034     g_assert_cmpint(err, ==, -EINVAL);
2035     g_assert_cmpint(res, ==, 0);
2036     g_assert_null(endptr);
2037 }
2038 
test_qemu_strtoi64_empty(void)2039 static void test_qemu_strtoi64_empty(void)
2040 {
2041     const char *str = "";
2042     char f = 'X';
2043     const char *endptr = &f;
2044     int64_t res = 999;
2045     int err;
2046 
2047     err = qemu_strtoi64(str, &endptr, 0, &res);
2048 
2049     g_assert_cmpint(err, ==, -EINVAL);
2050     g_assert_cmpint(res, ==, 0);
2051     g_assert_true(endptr == str);
2052 }
2053 
test_qemu_strtoi64_whitespace(void)2054 static void test_qemu_strtoi64_whitespace(void)
2055 {
2056     const char *str = "  \t  ";
2057     char f = 'X';
2058     const char *endptr = &f;
2059     int64_t res = 999;
2060     int err;
2061 
2062     err = qemu_strtoi64(str, &endptr, 0, &res);
2063 
2064     g_assert_cmpint(err, ==, -EINVAL);
2065     g_assert_cmpint(res, ==, 0);
2066     g_assert_true(endptr == str);
2067 }
2068 
test_qemu_strtoi64_invalid(void)2069 static void test_qemu_strtoi64_invalid(void)
2070 {
2071     const char *str = "   xxxx  \t abc";
2072     char f = 'X';
2073     const char *endptr = &f;
2074     int64_t res = 999;
2075     int err;
2076 
2077     err = qemu_strtoi64(str, &endptr, 0, &res);
2078 
2079     g_assert_cmpint(err, ==, -EINVAL);
2080     g_assert_cmpint(res, ==, 0);
2081     g_assert_true(endptr == str);
2082 }
2083 
test_qemu_strtoi64_trailing(void)2084 static void test_qemu_strtoi64_trailing(void)
2085 {
2086     const char *str = "123xxx";
2087     char f = 'X';
2088     const char *endptr = &f;
2089     int64_t res = 999;
2090     int err;
2091 
2092     err = qemu_strtoi64(str, &endptr, 0, &res);
2093 
2094     g_assert_cmpint(err, ==, 0);
2095     g_assert_cmpint(res, ==, 123);
2096     g_assert_true(endptr == str + 3);
2097 }
2098 
test_qemu_strtoi64_octal(void)2099 static void test_qemu_strtoi64_octal(void)
2100 {
2101     const char *str = "0123";
2102     char f = 'X';
2103     const char *endptr = &f;
2104     int64_t res = 999;
2105     int err;
2106 
2107     err = qemu_strtoi64(str, &endptr, 8, &res);
2108 
2109     g_assert_cmpint(err, ==, 0);
2110     g_assert_cmpint(res, ==, 0123);
2111     g_assert_true(endptr == str + strlen(str));
2112 
2113     endptr = &f;
2114     res = 999;
2115     err = qemu_strtoi64(str, &endptr, 0, &res);
2116 
2117     g_assert_cmpint(err, ==, 0);
2118     g_assert_cmpint(res, ==, 0123);
2119     g_assert_true(endptr == str + strlen(str));
2120 }
2121 
test_qemu_strtoi64_decimal(void)2122 static void test_qemu_strtoi64_decimal(void)
2123 {
2124     const char *str = "0123";
2125     char f = 'X';
2126     const char *endptr = &f;
2127     int64_t res = 999;
2128     int err;
2129 
2130     err = qemu_strtoi64(str, &endptr, 10, &res);
2131 
2132     g_assert_cmpint(err, ==, 0);
2133     g_assert_cmpint(res, ==, 123);
2134     g_assert_true(endptr == str + strlen(str));
2135 
2136     str = "123";
2137     endptr = &f;
2138     res = 999;
2139     err = qemu_strtoi64(str, &endptr, 0, &res);
2140 
2141     g_assert_cmpint(err, ==, 0);
2142     g_assert_cmpint(res, ==, 123);
2143     g_assert_true(endptr == str + strlen(str));
2144 }
2145 
test_qemu_strtoi64_hex(void)2146 static void test_qemu_strtoi64_hex(void)
2147 {
2148     const char *str = "0123";
2149     char f = 'X';
2150     const char *endptr = &f;
2151     int64_t res = 999;
2152     int err;
2153 
2154     err = qemu_strtoi64(str, &endptr, 16, &res);
2155 
2156     g_assert_cmpint(err, ==, 0);
2157     g_assert_cmpint(res, ==, 0x123);
2158     g_assert_true(endptr == str + strlen(str));
2159 
2160     str = "0x123";
2161     endptr = &f;
2162     res = 999;
2163     err = qemu_strtoi64(str, &endptr, 0, &res);
2164 
2165     g_assert_cmpint(err, ==, 0);
2166     g_assert_cmpint(res, ==, 0x123);
2167     g_assert_true(endptr == str + strlen(str));
2168 
2169     str = "0x";
2170     endptr = &f;
2171     res = 999;
2172     err = qemu_strtoi64(str, &endptr, 16, &res);
2173 
2174     g_assert_cmpint(err, ==, 0);
2175     g_assert_cmpint(res, ==, 0);
2176     g_assert_true(endptr == str + 1);
2177 }
2178 
test_qemu_strtoi64_max(void)2179 static void test_qemu_strtoi64_max(void)
2180 {
2181     char *str = g_strdup_printf("%lld", LLONG_MAX);
2182     char f = 'X';
2183     const char *endptr = &f;
2184     int64_t res = 999;
2185     int err;
2186 
2187     err = qemu_strtoi64(str, &endptr, 0, &res);
2188 
2189     g_assert_cmpint(err, ==, 0);
2190     g_assert_cmpint(res, ==, LLONG_MAX);
2191     g_assert_true(endptr == str + strlen(str));
2192     g_free(str);
2193 }
2194 
test_qemu_strtoi64_overflow(void)2195 static void test_qemu_strtoi64_overflow(void)
2196 {
2197     const char *str;
2198     const char *endptr;
2199     int64_t res;
2200     int err;
2201 
2202     str = "9223372036854775808"; /* 1 more than INT64_MAX */
2203     endptr = "somewhere";
2204     res = 999;
2205     err = qemu_strtoi64(str, &endptr, 0, &res);
2206     g_assert_cmpint(err, ==, -ERANGE);
2207     g_assert_cmpint(res, ==, INT64_MAX);
2208     g_assert_true(endptr == str + strlen(str));
2209 
2210     str = "0x10000000000000000"; /* 65 bits, 64-bit sign bit clear */
2211     endptr = "somewhere";
2212     res = 999;
2213     err = qemu_strtoi64(str, &endptr, 0, &res);
2214     g_assert_cmpint(err, ==, -ERANGE);
2215     g_assert_cmpint(res, ==, INT64_MAX);
2216     g_assert_true(endptr == str + strlen(str));
2217 
2218     str = "0x18000000080000000"; /* 65 bits, 64-bit sign bit set */
2219     endptr = "somewhere";
2220     res = 999;
2221     err = qemu_strtoi64(str, &endptr, 0, &res);
2222     g_assert_cmpint(err, ==, -ERANGE);
2223     g_assert_cmpint(res, ==, INT64_MAX);
2224     g_assert_true(endptr == str + strlen(str));
2225 }
2226 
test_qemu_strtoi64_min(void)2227 static void test_qemu_strtoi64_min(void)
2228 {
2229     char *str = g_strdup_printf("%lld", LLONG_MIN);
2230     char f = 'X';
2231     const char *endptr = &f;
2232     int64_t res = 999;
2233     int err;
2234 
2235     err = qemu_strtoi64(str, &endptr, 0, &res);
2236 
2237     g_assert_cmpint(err, ==, 0);
2238     g_assert_cmpint(res, ==, LLONG_MIN);
2239     g_assert_true(endptr == str + strlen(str));
2240     g_free(str);
2241 }
2242 
test_qemu_strtoi64_underflow(void)2243 static void test_qemu_strtoi64_underflow(void)
2244 {
2245     const char *str;
2246     const char *endptr;
2247     int64_t res;
2248     int err;
2249 
2250     str = "-9223372036854775809"; /* 1 less than INT64_MIN */
2251     endptr = "somewhere";
2252     res = 999;
2253     err = qemu_strtoi64(str, &endptr, 0, &res);
2254     g_assert_cmpint(err, ==, -ERANGE);
2255     g_assert_cmpint(res, ==, INT64_MIN);
2256     g_assert_true(endptr == str + strlen(str));
2257 
2258     str = "-0x10000000000000000"; /* 65 bits, 64-bit sign bit clear */
2259     endptr = "somewhere";
2260     res = 999;
2261     err = qemu_strtoi64(str, &endptr, 0, &res);
2262     g_assert_cmpint(err, ==, -ERANGE);
2263     g_assert_cmpint(res, ==, INT64_MIN);
2264     g_assert_true(endptr == str + strlen(str));
2265 
2266     str = "-0x18000000080000000"; /* 65 bits, 64-bit sign bit set */
2267     endptr = "somewhere";
2268     res = 999;
2269     err = qemu_strtoi64(str, &endptr, 0, &res);
2270     g_assert_cmpint(err, ==, -ERANGE);
2271     g_assert_cmpint(res, ==, INT64_MIN);
2272     g_assert_true(endptr == str + strlen(str));
2273 }
2274 
test_qemu_strtoi64_negative(void)2275 static void test_qemu_strtoi64_negative(void)
2276 {
2277     const char *str = "  \t -321";
2278     char f = 'X';
2279     const char *endptr = &f;
2280     int64_t res = 999;
2281     int err;
2282 
2283     err = qemu_strtoi64(str, &endptr, 0, &res);
2284 
2285     g_assert_cmpint(err, ==, 0);
2286     g_assert_cmpint(res, ==, -321);
2287     g_assert_true(endptr == str + strlen(str));
2288 }
2289 
test_qemu_strtoi64_negzero(void)2290 static void test_qemu_strtoi64_negzero(void)
2291 {
2292     const char *str = " -0";
2293     char f = 'X';
2294     const char *endptr = &f;
2295     int64_t res = 999;
2296     int err;
2297 
2298     err = qemu_strtoi64(str, &endptr, 0, &res);
2299 
2300     g_assert_cmpint(err, ==, 0);
2301     g_assert_cmpint(res, ==, 0);
2302     g_assert_true(endptr == str + strlen(str));
2303 }
2304 
test_qemu_strtoi64_full_correct(void)2305 static void test_qemu_strtoi64_full_correct(void)
2306 {
2307     const char *str = "123";
2308     int64_t res = 999;
2309     int err;
2310 
2311     err = qemu_strtoi64(str, NULL, 0, &res);
2312 
2313     g_assert_cmpint(err, ==, 0);
2314     g_assert_cmpint(res, ==, 123);
2315 }
2316 
test_qemu_strtoi64_full_null(void)2317 static void test_qemu_strtoi64_full_null(void)
2318 {
2319     int64_t res = 999;
2320     int err;
2321 
2322     err = qemu_strtoi64(NULL, NULL, 0, &res);
2323 
2324     g_assert_cmpint(err, ==, -EINVAL);
2325     g_assert_cmpint(res, ==, 0);
2326 }
2327 
test_qemu_strtoi64_full_empty(void)2328 static void test_qemu_strtoi64_full_empty(void)
2329 {
2330     const char *str = "";
2331     int64_t res = 999;
2332     int err;
2333 
2334     err = qemu_strtoi64(str, NULL, 0, &res);
2335 
2336     g_assert_cmpint(err, ==, -EINVAL);
2337     g_assert_cmpint(res, ==, 0);
2338 }
2339 
test_qemu_strtoi64_full_negative(void)2340 static void test_qemu_strtoi64_full_negative(void)
2341 {
2342     const char *str = " \t -321";
2343     int64_t res = 999;
2344     int err;
2345 
2346     err = qemu_strtoi64(str, NULL, 0, &res);
2347 
2348     g_assert_cmpint(err, ==, 0);
2349     g_assert_cmpint(res, ==, -321);
2350 }
2351 
test_qemu_strtoi64_full_negzero(void)2352 static void test_qemu_strtoi64_full_negzero(void)
2353 {
2354     const char *str = " -0";
2355     int64_t res = 999;
2356     int err;
2357 
2358     err = qemu_strtoi64(str, NULL, 0, &res);
2359 
2360     g_assert_cmpint(err, ==, 0);
2361     g_assert_cmpint(res, ==, 0);
2362 }
2363 
test_qemu_strtoi64_full_trailing(void)2364 static void test_qemu_strtoi64_full_trailing(void)
2365 {
2366     const char *str = "123xxx";
2367     int64_t res = 999;
2368     int err;
2369 
2370     err = qemu_strtoi64(str, NULL, 0, &res);
2371 
2372     g_assert_cmpint(err, ==, -EINVAL);
2373     g_assert_cmpint(res, ==, 123);
2374 }
2375 
test_qemu_strtoi64_full_max(void)2376 static void test_qemu_strtoi64_full_max(void)
2377 {
2378 
2379     char *str = g_strdup_printf("%lld", LLONG_MAX);
2380     int64_t res = 999;
2381     int err;
2382 
2383     err = qemu_strtoi64(str, NULL, 0, &res);
2384 
2385     g_assert_cmpint(err, ==, 0);
2386     g_assert_cmpint(res, ==, LLONG_MAX);
2387     g_free(str);
2388 }
2389 
test_qemu_strtoi64_full_erange_junk(void)2390 static void test_qemu_strtoi64_full_erange_junk(void)
2391 {
2392     /* EINVAL has priority over ERANGE */
2393     const char *str = "-99999999999999999999junk";
2394     int64_t res = 999;
2395     int err;
2396 
2397     err = qemu_strtoi64(str, NULL, 0, &res);
2398 
2399     g_assert_cmpint(err, ==, -EINVAL);
2400     g_assert_cmpint(res, ==, INT64_MIN);
2401 }
2402 
test_qemu_strtou64_correct(void)2403 static void test_qemu_strtou64_correct(void)
2404 {
2405     const char *str = "12345 foo";
2406     char f = 'X';
2407     const char *endptr = &f;
2408     uint64_t res = 999;
2409     int err;
2410 
2411     err = qemu_strtou64(str, &endptr, 0, &res);
2412 
2413     g_assert_cmpint(err, ==, 0);
2414     g_assert_cmpuint(res, ==, 12345);
2415     g_assert_true(endptr == str + 5);
2416 }
2417 
test_qemu_strtou64_null(void)2418 static void test_qemu_strtou64_null(void)
2419 {
2420     char f = 'X';
2421     const char *endptr = &f;
2422     uint64_t res = 999;
2423     int err;
2424 
2425     err = qemu_strtou64(NULL, &endptr, 0, &res);
2426 
2427     g_assert_cmpint(err, ==, -EINVAL);
2428     g_assert_cmpuint(res, ==, 0);
2429     g_assert_null(endptr);
2430 }
2431 
test_qemu_strtou64_empty(void)2432 static void test_qemu_strtou64_empty(void)
2433 {
2434     const char *str = "";
2435     char f = 'X';
2436     const char *endptr = &f;
2437     uint64_t res = 999;
2438     int err;
2439 
2440     err = qemu_strtou64(str, &endptr, 0, &res);
2441 
2442     g_assert_cmpint(err, ==, -EINVAL);
2443     g_assert_cmpuint(res, ==, 0);
2444     g_assert_true(endptr == str);
2445 }
2446 
test_qemu_strtou64_whitespace(void)2447 static void test_qemu_strtou64_whitespace(void)
2448 {
2449     const char *str = "  \t  ";
2450     char f = 'X';
2451     const char *endptr = &f;
2452     uint64_t res = 999;
2453     int err;
2454 
2455     err = qemu_strtou64(str, &endptr, 0, &res);
2456 
2457     g_assert_cmpint(err, ==, -EINVAL);
2458     g_assert_cmpuint(res, ==, 0);
2459     g_assert_true(endptr == str);
2460 }
2461 
test_qemu_strtou64_invalid(void)2462 static void test_qemu_strtou64_invalid(void)
2463 {
2464     const char *str = "   xxxx  \t abc";
2465     char f = 'X';
2466     const char *endptr = &f;
2467     uint64_t res = 999;
2468     int err;
2469 
2470     err = qemu_strtou64(str, &endptr, 0, &res);
2471 
2472     g_assert_cmpint(err, ==, -EINVAL);
2473     g_assert_cmpuint(res, ==, 0);
2474     g_assert_true(endptr == str);
2475 }
2476 
test_qemu_strtou64_trailing(void)2477 static void test_qemu_strtou64_trailing(void)
2478 {
2479     const char *str = "123xxx";
2480     char f = 'X';
2481     const char *endptr = &f;
2482     uint64_t res = 999;
2483     int err;
2484 
2485     err = qemu_strtou64(str, &endptr, 0, &res);
2486 
2487     g_assert_cmpint(err, ==, 0);
2488     g_assert_cmpuint(res, ==, 123);
2489     g_assert_true(endptr == str + 3);
2490 }
2491 
test_qemu_strtou64_octal(void)2492 static void test_qemu_strtou64_octal(void)
2493 {
2494     const char *str = "0123";
2495     char f = 'X';
2496     const char *endptr = &f;
2497     uint64_t res = 999;
2498     int err;
2499 
2500     err = qemu_strtou64(str, &endptr, 8, &res);
2501 
2502     g_assert_cmpint(err, ==, 0);
2503     g_assert_cmpuint(res, ==, 0123);
2504     g_assert_true(endptr == str + strlen(str));
2505 
2506     endptr = &f;
2507     res = 999;
2508     err = qemu_strtou64(str, &endptr, 0, &res);
2509 
2510     g_assert_cmpint(err, ==, 0);
2511     g_assert_cmpuint(res, ==, 0123);
2512     g_assert_true(endptr == str + strlen(str));
2513 }
2514 
test_qemu_strtou64_decimal(void)2515 static void test_qemu_strtou64_decimal(void)
2516 {
2517     const char *str = "0123";
2518     char f = 'X';
2519     const char *endptr = &f;
2520     uint64_t res = 999;
2521     int err;
2522 
2523     err = qemu_strtou64(str, &endptr, 10, &res);
2524 
2525     g_assert_cmpint(err, ==, 0);
2526     g_assert_cmpuint(res, ==, 123);
2527     g_assert_true(endptr == str + strlen(str));
2528 
2529     str = "123";
2530     endptr = &f;
2531     res = 999;
2532     err = qemu_strtou64(str, &endptr, 0, &res);
2533 
2534     g_assert_cmpint(err, ==, 0);
2535     g_assert_cmpuint(res, ==, 123);
2536     g_assert_true(endptr == str + strlen(str));
2537 }
2538 
test_qemu_strtou64_hex(void)2539 static void test_qemu_strtou64_hex(void)
2540 {
2541     const char *str = "0123";
2542     char f = 'X';
2543     const char *endptr = &f;
2544     uint64_t res = 999;
2545     int err;
2546 
2547     err = qemu_strtou64(str, &endptr, 16, &res);
2548 
2549     g_assert_cmpint(err, ==, 0);
2550     g_assert_cmphex(res, ==, 0x123);
2551     g_assert_true(endptr == str + strlen(str));
2552 
2553     str = "0x123";
2554     endptr = &f;
2555     res = 999;
2556     err = qemu_strtou64(str, &endptr, 0, &res);
2557 
2558     g_assert_cmpint(err, ==, 0);
2559     g_assert_cmphex(res, ==, 0x123);
2560     g_assert_true(endptr == str + strlen(str));
2561 
2562     str = "0x";
2563     endptr = &f;
2564     res = 999;
2565     err = qemu_strtou64(str, &endptr, 16, &res);
2566 
2567     g_assert_cmpint(err, ==, 0);
2568     g_assert_cmphex(res, ==, 0);
2569     g_assert_true(endptr == str + 1);
2570 }
2571 
test_qemu_strtou64_wrap(void)2572 static void test_qemu_strtou64_wrap(void)
2573 {
2574     const char *str = "-18446744073709551615"; /* 1 mod 2^64 */
2575     char f = 'X';
2576     const char *endptr = &f;
2577     uint64_t res = 999;
2578     int err;
2579 
2580     err = qemu_strtou64(str, &endptr, 0, &res);
2581 
2582     g_assert_cmpint(err, ==, 0);
2583     g_assert_cmpuint(res, ==, 1);
2584     g_assert_true(endptr == str + strlen(str));
2585 }
2586 
test_qemu_strtou64_max(void)2587 static void test_qemu_strtou64_max(void)
2588 {
2589     char *str = g_strdup_printf("%llu", ULLONG_MAX);
2590     char f = 'X';
2591     const char *endptr = &f;
2592     uint64_t res = 999;
2593     int err;
2594 
2595     err = qemu_strtou64(str, &endptr, 0, &res);
2596 
2597     g_assert_cmpint(err, ==, 0);
2598     g_assert_cmphex(res, ==, ULLONG_MAX);
2599     g_assert_true(endptr == str + strlen(str));
2600     g_free(str);
2601 }
2602 
test_qemu_strtou64_overflow(void)2603 static void test_qemu_strtou64_overflow(void)
2604 {
2605     const char *str;
2606     const char *endptr;
2607     uint64_t res;
2608     int err;
2609 
2610     str = "18446744073709551616"; /* 1 more than UINT64_MAX */
2611     endptr = "somewhere";
2612     res = 999;
2613     err = qemu_strtou64(str, &endptr, 0, &res);
2614     g_assert_cmpint(err, ==, -ERANGE);
2615     g_assert_cmpuint(res, ==, UINT64_MAX);
2616     g_assert_true(endptr == str + strlen(str));
2617 
2618     str = "0x10000000000000000"; /* 65 bits, 64-bit sign bit clear */
2619     endptr = "somewhere";
2620     res = 999;
2621     err = qemu_strtou64(str, &endptr, 0, &res);
2622     g_assert_cmpint(err, ==, -ERANGE);
2623     g_assert_cmpuint(res, ==, UINT64_MAX);
2624     g_assert_true(endptr == str + strlen(str));
2625 
2626     str = "0x18000000080000000"; /* 65 bits, 64-bit sign bit set */
2627     endptr = "somewhere";
2628     res = 999;
2629     err = qemu_strtou64(str, &endptr, 0, &res);
2630     g_assert_cmpint(err, ==, -ERANGE);
2631     g_assert_cmpuint(res, ==, UINT64_MAX);
2632     g_assert_true(endptr == str + strlen(str));
2633 }
2634 
test_qemu_strtou64_underflow(void)2635 static void test_qemu_strtou64_underflow(void)
2636 {
2637     const char *str;
2638     const char *endptr;
2639     uint64_t res;
2640     int err;
2641 
2642     str = "-99999999999999999999999999999999999999999999";
2643     endptr = "somewhere";
2644     res = 999;
2645     err = qemu_strtou64(str, &endptr, 0, &res);
2646     g_assert_cmpint(err, ==, -ERANGE);
2647     g_assert_cmpuint(res, ==, UINT64_MAX);
2648     g_assert_true(endptr == str + strlen(str));
2649 
2650     str = "-0x10000000000000000"; /* 65 bits, 64-bit sign bit clear */
2651     endptr = "somewhere";
2652     res = 999;
2653     err = qemu_strtou64(str, &endptr, 0, &res);
2654     g_assert_cmpint(err, ==, -ERANGE);
2655     g_assert_cmpuint(res, ==, UINT64_MAX);
2656     g_assert_true(endptr == str + strlen(str));
2657 
2658     str = "-0x18000000080000000"; /* 65 bits, 64-bit sign bit set */
2659     endptr = "somewhere";
2660     res = 999;
2661     err = qemu_strtou64(str, &endptr, 0, &res);
2662     g_assert_cmpint(err, ==, -ERANGE);
2663     g_assert_cmpuint(res, ==, UINT64_MAX);
2664     g_assert_true(endptr == str + strlen(str));
2665 }
2666 
test_qemu_strtou64_negative(void)2667 static void test_qemu_strtou64_negative(void)
2668 {
2669     const char *str = "  \t -321";
2670     char f = 'X';
2671     const char *endptr = &f;
2672     uint64_t res = 999;
2673     int err;
2674 
2675     err = qemu_strtou64(str, &endptr, 0, &res);
2676 
2677     g_assert_cmpint(err, ==, 0);
2678     g_assert_cmpuint(res, ==, -321ull);
2679     g_assert_true(endptr == str + strlen(str));
2680 }
2681 
test_qemu_strtou64_negzero(void)2682 static void test_qemu_strtou64_negzero(void)
2683 {
2684     const char *str = " -0";
2685     char f = 'X';
2686     const char *endptr = &f;
2687     uint64_t res = 999;
2688     int err;
2689 
2690     err = qemu_strtou64(str, &endptr, 0, &res);
2691 
2692     g_assert_cmpint(err, ==, 0);
2693     g_assert_cmpuint(res, ==, 0);
2694     g_assert_true(endptr == str + strlen(str));
2695 }
2696 
test_qemu_strtou64_full_correct(void)2697 static void test_qemu_strtou64_full_correct(void)
2698 {
2699     const char *str = "18446744073709551614";
2700     uint64_t res = 999;
2701     int err;
2702 
2703     err = qemu_strtou64(str, NULL, 0, &res);
2704 
2705     g_assert_cmpint(err, ==, 0);
2706     g_assert_cmpuint(res, ==, 18446744073709551614ull);
2707 }
2708 
test_qemu_strtou64_full_null(void)2709 static void test_qemu_strtou64_full_null(void)
2710 {
2711     uint64_t res = 999;
2712     int err;
2713 
2714     err = qemu_strtou64(NULL, NULL, 0, &res);
2715 
2716     g_assert_cmpint(err, ==, -EINVAL);
2717     g_assert_cmpuint(res, ==, 0);
2718 }
2719 
test_qemu_strtou64_full_empty(void)2720 static void test_qemu_strtou64_full_empty(void)
2721 {
2722     const char *str = "";
2723     uint64_t res = 999;
2724     int err;
2725 
2726     err = qemu_strtou64(str, NULL, 0, &res);
2727 
2728     g_assert_cmpint(err, ==, -EINVAL);
2729     g_assert_cmpuint(res, ==, 0);
2730 }
2731 
test_qemu_strtou64_full_negative(void)2732 static void test_qemu_strtou64_full_negative(void)
2733 {
2734     const char *str = " \t -321";
2735     uint64_t res = 999;
2736     int err;
2737 
2738     err = qemu_strtou64(str, NULL, 0, &res);
2739 
2740     g_assert_cmpint(err, ==, 0);
2741     g_assert_cmpuint(res, ==, -321ull);
2742 }
2743 
test_qemu_strtou64_full_negzero(void)2744 static void test_qemu_strtou64_full_negzero(void)
2745 {
2746     const char *str = " -0";
2747     uint64_t res = 999;
2748     int err;
2749 
2750     err = qemu_strtou64(str, NULL, 0, &res);
2751 
2752     g_assert_cmpint(err, ==, 0);
2753     g_assert_cmpuint(res, ==, 0);
2754 }
2755 
test_qemu_strtou64_full_trailing(void)2756 static void test_qemu_strtou64_full_trailing(void)
2757 {
2758     const char *str = "18446744073709551614xxxxxx";
2759     uint64_t res = 999;
2760     int err;
2761 
2762     err = qemu_strtou64(str, NULL, 0, &res);
2763 
2764     g_assert_cmpint(err, ==, -EINVAL);
2765     g_assert_cmpuint(res, ==, 18446744073709551614ULL);
2766 }
2767 
test_qemu_strtou64_full_max(void)2768 static void test_qemu_strtou64_full_max(void)
2769 {
2770     char *str = g_strdup_printf("%lld", ULLONG_MAX);
2771     uint64_t res = 999;
2772     int err;
2773 
2774     err = qemu_strtou64(str, NULL, 0, &res);
2775 
2776     g_assert_cmpint(err, ==, 0);
2777     g_assert_cmphex(res, ==, ULLONG_MAX);
2778     g_free(str);
2779 }
2780 
test_qemu_strtou64_full_erange_junk(void)2781 static void test_qemu_strtou64_full_erange_junk(void)
2782 {
2783     /* EINVAL has priority over ERANGE */
2784     const char *str = "-99999999999999999999junk";
2785     uint64_t res = 999;
2786     int err;
2787 
2788     err = qemu_strtou64(str, NULL, 0, &res);
2789 
2790     g_assert_cmpint(err, ==, -EINVAL);
2791     g_assert_cmpuint(res, ==, UINT64_MAX);
2792 }
2793 
test_qemu_strtod_simple(void)2794 static void test_qemu_strtod_simple(void)
2795 {
2796     const char *str;
2797     const char *endptr;
2798     int err;
2799     double res;
2800 
2801     /* no radix or exponent */
2802     str = "1";
2803     endptr = "somewhere";
2804     res = 999;
2805     err = qemu_strtod(str, &endptr, &res);
2806     g_assert_cmpint(err, ==, 0);
2807     g_assert_cmpfloat(res, ==, 1.0);
2808     g_assert_true(endptr == str + 1);
2809 
2810     /* leading space and sign */
2811     str = " -0.0";
2812     endptr = "somewhere";
2813     res = 999;
2814     err = qemu_strtod(str, &endptr, &res);
2815     g_assert_cmpint(err, ==, 0);
2816     g_assert_cmpfloat(res, ==, -0.0);
2817     g_assert_true(signbit(res));
2818     g_assert_true(endptr == str + 5);
2819 
2820     /* fraction only */
2821     str = "+.5";
2822     endptr = "somewhere";
2823     res = 999;
2824     err = qemu_strtod(str, &endptr, &res);
2825     g_assert_cmpint(err, ==, 0);
2826     g_assert_cmpfloat(res, ==, 0.5);
2827     g_assert_true(endptr == str + 3);
2828 
2829     /* exponent */
2830     str = "1.e+1";
2831     endptr = "somewhere";
2832     res = 999;
2833     err = qemu_strtod(str, &endptr, &res);
2834     g_assert_cmpint(err, ==, 0);
2835     g_assert_cmpfloat(res, ==, 10.0);
2836     g_assert_true(endptr == str + 5);
2837 
2838     /* hex without radix */
2839     str = "0x10";
2840     endptr = "somewhere";
2841     res = 999;
2842     err = qemu_strtod(str, &endptr, &res);
2843     g_assert_cmpint(err, ==, 0);
2844     g_assert_cmpfloat(res, ==, 16.0);
2845     g_assert_true(endptr == str + 4);
2846 }
2847 
test_qemu_strtod_einval(void)2848 static void test_qemu_strtod_einval(void)
2849 {
2850     const char *str;
2851     const char *endptr;
2852     int err;
2853     double res;
2854 
2855     /* empty */
2856     str = "";
2857     endptr = "somewhere";
2858     res = 999;
2859     err = qemu_strtod(str, &endptr, &res);
2860     g_assert_cmpint(err, ==, -EINVAL);
2861     g_assert_cmpfloat(res, ==, 0.0);
2862     g_assert_false(signbit(res));
2863     g_assert_true(endptr == str);
2864 
2865     /* NULL */
2866     str = NULL;
2867     endptr = "random";
2868     res = 999;
2869     err = qemu_strtod(str, &endptr, &res);
2870     g_assert_cmpint(err, ==, -EINVAL);
2871     g_assert_cmpfloat(res, ==, 0.0);
2872     g_assert_false(signbit(res));
2873     g_assert_null(endptr);
2874 
2875     /* not recognizable */
2876     str = " junk";
2877     endptr = "somewhere";
2878     res = 999;
2879     err = qemu_strtod(str, &endptr, &res);
2880     g_assert_cmpint(err, ==, -EINVAL);
2881     g_assert_cmpfloat(res, ==, 0.0);
2882     g_assert_false(signbit(res));
2883     g_assert_true(endptr == str);
2884 }
2885 
test_qemu_strtod_erange(void)2886 static void test_qemu_strtod_erange(void)
2887 {
2888     const char *str;
2889     const char *endptr;
2890     int err;
2891     double res;
2892 
2893     /* overflow */
2894     str = "9e999";
2895     endptr = "somewhere";
2896     res = 999;
2897     err = qemu_strtod(str, &endptr, &res);
2898     g_assert_cmpint(err, ==, -ERANGE);
2899     g_assert_cmpfloat(res, ==, HUGE_VAL);
2900     g_assert_true(endptr == str + 5);
2901 
2902     str = "-9e+999";
2903     endptr = "somewhere";
2904     res = 999;
2905     err = qemu_strtod(str, &endptr, &res);
2906     g_assert_cmpint(err, ==, -ERANGE);
2907     g_assert_cmpfloat(res, ==, -HUGE_VAL);
2908     g_assert_true(endptr == str + 7);
2909 
2910     /* underflow */
2911     str = "-9e-999";
2912     endptr = "somewhere";
2913     res = 999;
2914     err = qemu_strtod(str, &endptr, &res);
2915     g_assert_cmpint(err, ==, -ERANGE);
2916     g_assert_cmpfloat(res, >=, -DBL_MIN);
2917     g_assert_cmpfloat(res, <=, -0.0);
2918     g_assert_true(signbit(res));
2919     g_assert_true(endptr == str + 7);
2920 }
2921 
test_qemu_strtod_nonfinite(void)2922 static void test_qemu_strtod_nonfinite(void)
2923 {
2924     const char *str;
2925     const char *endptr;
2926     int err;
2927     double res;
2928 
2929     /* infinity */
2930     str = "inf";
2931     endptr = "somewhere";
2932     res = 999;
2933     err = qemu_strtod(str, &endptr, &res);
2934     g_assert_cmpint(err, ==, 0);
2935     g_assert_true(isinf(res));
2936     g_assert_false(signbit(res));
2937     g_assert_true(endptr == str + 3);
2938 
2939     str = "-infinity";
2940     endptr = "somewhere";
2941     res = 999;
2942     err = qemu_strtod(str, &endptr, &res);
2943     g_assert_cmpint(err, ==, 0);
2944     g_assert_true(isinf(res));
2945     g_assert_true(signbit(res));
2946     g_assert_true(endptr == str + 9);
2947 
2948     /* not a number */
2949     str = " NaN";
2950     endptr = "somewhere";
2951     res = 999;
2952     err = qemu_strtod(str, &endptr, &res);
2953     g_assert_cmpint(err, ==, 0);
2954     g_assert_true(isnan(res));
2955     g_assert_true(endptr == str + 4);
2956 }
2957 
test_qemu_strtod_trailing(void)2958 static void test_qemu_strtod_trailing(void)
2959 {
2960     const char *str;
2961     const char *endptr;
2962     int err;
2963     double res;
2964 
2965     /* trailing whitespace */
2966     str = "1. ";
2967     endptr = "somewhere";
2968     res = 999;
2969     err = qemu_strtod(str, &endptr, &res);
2970     g_assert_cmpint(err, ==, 0);
2971     g_assert_cmpfloat(res, ==, 1.0);
2972     g_assert_true(endptr == str + 2);
2973 
2974     endptr = "somewhere";
2975     res = 999;
2976     err = qemu_strtod(str, NULL, &res);
2977     g_assert_cmpint(err, ==, -EINVAL);
2978     g_assert_cmpfloat(res, ==, 1.0);
2979 
2980     /* trailing e is not an exponent */
2981     str = ".5e";
2982     endptr = "somewhere";
2983     res = 999;
2984     err = qemu_strtod(str, &endptr, &res);
2985     g_assert_cmpint(err, ==, 0);
2986     g_assert_cmpfloat(res, ==, 0.5);
2987     g_assert_true(endptr == str + 2);
2988 
2989     endptr = "somewhere";
2990     res = 999;
2991     err = qemu_strtod(str, NULL, &res);
2992     g_assert_cmpint(err, ==, -EINVAL);
2993     g_assert_cmpfloat(res, ==, 0.5);
2994 
2995     /* trailing ( not part of long NaN */
2996     str = "nan(";
2997     endptr = "somewhere";
2998     res = 999;
2999     err = qemu_strtod(str, &endptr, &res);
3000     g_assert_cmpint(err, ==, 0);
3001     g_assert_true(isnan(res));
3002     g_assert_true(endptr == str + 3);
3003 
3004     endptr = "somewhere";
3005     res = 999;
3006     err = qemu_strtod(str, NULL, &res);
3007     g_assert_cmpint(err, ==, -EINVAL);
3008     g_assert_true(isnan(res));
3009 }
3010 
test_qemu_strtod_erange_junk(void)3011 static void test_qemu_strtod_erange_junk(void)
3012 {
3013     const char *str;
3014     const char *endptr;
3015     int err;
3016     double res;
3017 
3018     /* ERANGE with trailing junk... */
3019     str = "1e-999junk";
3020     endptr = "somewhere";
3021     res = 999;
3022     err = qemu_strtod(str, &endptr, &res);
3023     g_assert_cmpint(err, ==, -ERANGE);
3024     g_assert_cmpfloat(res, <=, DBL_MIN);
3025     g_assert_cmpfloat(res, >=, 0.0);
3026     g_assert_false(signbit(res));
3027     g_assert_true(endptr == str + 6);
3028 
3029     /* ...has less priority than EINVAL when full parse not possible */
3030     endptr = "somewhere";
3031     res = 999;
3032     err = qemu_strtod(str, NULL, &res);
3033     g_assert_cmpint(err, ==, -EINVAL);
3034     g_assert_cmpfloat(res, ==, 0.0);
3035     g_assert_false(signbit(res));
3036 }
3037 
test_qemu_strtod_finite_simple(void)3038 static void test_qemu_strtod_finite_simple(void)
3039 {
3040     const char *str;
3041     const char *endptr;
3042     int err;
3043     double res;
3044 
3045     /* no radix or exponent */
3046     str = "1";
3047     endptr = "somewhere";
3048     res = 999;
3049     err = qemu_strtod_finite(str, &endptr, &res);
3050     g_assert_cmpint(err, ==, 0);
3051     g_assert_cmpfloat(res, ==, 1.0);
3052     g_assert_true(endptr == str + 1);
3053 
3054     /* leading space and sign */
3055     str = " -0.0";
3056     endptr = "somewhere";
3057     res = 999;
3058     err = qemu_strtod_finite(str, &endptr, &res);
3059     g_assert_cmpint(err, ==, 0);
3060     g_assert_cmpfloat(res, ==, -0.0);
3061     g_assert_true(signbit(res));
3062     g_assert_true(endptr == str + 5);
3063 
3064     /* fraction only */
3065     str = "+.5";
3066     endptr = "somewhere";
3067     res = 999;
3068     err = qemu_strtod_finite(str, &endptr, &res);
3069     g_assert_cmpint(err, ==, 0);
3070     g_assert_cmpfloat(res, ==, 0.5);
3071     g_assert_true(endptr == str + 3);
3072 
3073     /* exponent */
3074     str = "1.e+1";
3075     endptr = "somewhere";
3076     res = 999;
3077     err = qemu_strtod_finite(str, &endptr, &res);
3078     g_assert_cmpint(err, ==, 0);
3079     g_assert_cmpfloat(res, ==, 10.0);
3080     g_assert_true(endptr == str + 5);
3081 
3082     /* hex without radix */
3083     str = "0x10";
3084     endptr = "somewhere";
3085     res = 999;
3086     err = qemu_strtod(str, &endptr, &res);
3087     g_assert_cmpint(err, ==, 0);
3088     g_assert_cmpfloat(res, ==, 16.0);
3089     g_assert_true(endptr == str + 4);
3090 }
3091 
test_qemu_strtod_finite_einval(void)3092 static void test_qemu_strtod_finite_einval(void)
3093 {
3094     const char *str;
3095     const char *endptr;
3096     int err;
3097     double res;
3098 
3099     /* empty */
3100     str = "";
3101     endptr = "somewhere";
3102     res = 999;
3103     err = qemu_strtod_finite(str, &endptr, &res);
3104     g_assert_cmpint(err, ==, -EINVAL);
3105     g_assert_cmpfloat(res, ==, 0.0);
3106     g_assert_false(signbit(res));
3107     g_assert_true(endptr == str);
3108 
3109     /* NULL */
3110     str = NULL;
3111     endptr = "random";
3112     res = 999;
3113     err = qemu_strtod_finite(str, &endptr, &res);
3114     g_assert_cmpint(err, ==, -EINVAL);
3115     g_assert_cmpfloat(res, ==, 0.0);
3116     g_assert_false(signbit(res));
3117     g_assert_null(endptr);
3118 
3119     /* not recognizable */
3120     str = " junk";
3121     endptr = "somewhere";
3122     res = 999;
3123     err = qemu_strtod_finite(str, &endptr, &res);
3124     g_assert_cmpint(err, ==, -EINVAL);
3125     g_assert_cmpfloat(res, ==, 0.0);
3126     g_assert_false(signbit(res));
3127     g_assert_true(endptr == str);
3128 }
3129 
test_qemu_strtod_finite_erange(void)3130 static void test_qemu_strtod_finite_erange(void)
3131 {
3132     const char *str;
3133     const char *endptr;
3134     int err;
3135     double res;
3136 
3137     /* overflow turns into EINVAL */
3138     str = "9e999";
3139     endptr = "somewhere";
3140     res = 999;
3141     err = qemu_strtod_finite(str, &endptr, &res);
3142     g_assert_cmpint(err, ==, -EINVAL);
3143     g_assert_cmpfloat(res, ==, 0.0);
3144     g_assert_false(signbit(res));
3145     g_assert_true(endptr == str);
3146 
3147     str = "-9e+999";
3148     endptr = "somewhere";
3149     res = 999;
3150     err = qemu_strtod_finite(str, &endptr, &res);
3151     g_assert_cmpint(err, ==, -EINVAL);
3152     g_assert_cmpfloat(res, ==, 0.0);
3153     g_assert_false(signbit(res));
3154     g_assert_true(endptr == str);
3155 
3156     /* underflow is still possible */
3157     str = "-9e-999";
3158     endptr = "somewhere";
3159     res = 999;
3160     err = qemu_strtod_finite(str, &endptr, &res);
3161     g_assert_cmpint(err, ==, -ERANGE);
3162     g_assert_cmpfloat(res, >=, -DBL_MIN);
3163     g_assert_cmpfloat(res, <=, -0.0);
3164     g_assert_true(signbit(res));
3165     g_assert_true(endptr == str + 7);
3166 }
3167 
test_qemu_strtod_finite_nonfinite(void)3168 static void test_qemu_strtod_finite_nonfinite(void)
3169 {
3170     const char *str;
3171     const char *endptr;
3172     int err;
3173     double res;
3174 
3175     /* infinity */
3176     str = "inf";
3177     endptr = "somewhere";
3178     res = 999;
3179     err = qemu_strtod_finite(str, &endptr, &res);
3180     g_assert_cmpint(err, ==, -EINVAL);
3181     g_assert_cmpfloat(res, ==, 0.0);
3182     g_assert_false(signbit(res));
3183     g_assert_true(endptr == str);
3184 
3185     str = "-infinity";
3186     endptr = "somewhere";
3187     res = 999;
3188     err = qemu_strtod_finite(str, &endptr, &res);
3189     g_assert_cmpint(err, ==, -EINVAL);
3190     g_assert_cmpfloat(res, ==, 0.0);
3191     g_assert_false(signbit(res));
3192     g_assert_true(endptr == str);
3193 
3194     /* not a number */
3195     str = " NaN";
3196     endptr = "somewhere";
3197     res = 999;
3198     err = qemu_strtod_finite(str, &endptr, &res);
3199     g_assert_cmpint(err, ==, -EINVAL);
3200     g_assert_cmpfloat(res, ==, 0.0);
3201     g_assert_false(signbit(res));
3202     g_assert_true(endptr == str);
3203 }
3204 
test_qemu_strtod_finite_trailing(void)3205 static void test_qemu_strtod_finite_trailing(void)
3206 {
3207     const char *str;
3208     const char *endptr;
3209     int err;
3210     double res;
3211 
3212     /* trailing whitespace */
3213     str = "1. ";
3214     endptr = "somewhere";
3215     res = 999;
3216     err = qemu_strtod_finite(str, &endptr, &res);
3217     g_assert_cmpint(err, ==, 0);
3218     g_assert_cmpfloat(res, ==, 1.0);
3219     g_assert_true(endptr == str + 2);
3220 
3221     endptr = "somewhere";
3222     res = 999;
3223     err = qemu_strtod_finite(str, NULL, &res);
3224     g_assert_cmpint(err, ==, -EINVAL);
3225     g_assert_cmpfloat(res, ==, 1.0);
3226     g_assert_false(signbit(res));
3227 
3228     /* trailing e is not an exponent */
3229     str = ".5e";
3230     endptr = "somewhere";
3231     res = 999;
3232     err = qemu_strtod_finite(str, &endptr, &res);
3233     g_assert_cmpint(err, ==, 0);
3234     g_assert_cmpfloat(res, ==, 0.5);
3235     g_assert_true(endptr == str + 2);
3236 
3237     endptr = "somewhere";
3238     res = 999;
3239     err = qemu_strtod_finite(str, NULL, &res);
3240     g_assert_cmpint(err, ==, -EINVAL);
3241     g_assert_cmpfloat(res, ==, 0.5);
3242 
3243     /* trailing ( not part of long NaN */
3244     str = "nan(";
3245     endptr = "somewhere";
3246     res = 999;
3247     err = qemu_strtod_finite(str, &endptr, &res);
3248     g_assert_cmpint(err, ==, -EINVAL);
3249     g_assert_cmpfloat(res, ==, 0.0);
3250     g_assert_false(signbit(res));
3251     g_assert_true(endptr == str);
3252 
3253     endptr = "somewhere";
3254     res = 999;
3255     err = qemu_strtod_finite(str, NULL, &res);
3256     g_assert_cmpint(err, ==, -EINVAL);
3257     g_assert_cmpfloat(res, ==, 0.0);
3258     g_assert_false(signbit(res));
3259 }
3260 
test_qemu_strtod_finite_erange_junk(void)3261 static void test_qemu_strtod_finite_erange_junk(void)
3262 {
3263     const char *str;
3264     const char *endptr;
3265     int err;
3266     double res;
3267 
3268     /* ERANGE with trailing junk... */
3269     str = "1e-999junk";
3270     endptr = "somewhere";
3271     res = 999;
3272     err = qemu_strtod_finite(str, &endptr, &res);
3273     g_assert_cmpint(err, ==, -ERANGE);
3274     g_assert_cmpfloat(res, <=, DBL_MIN);
3275     g_assert_cmpfloat(res, >=, 0.0);
3276     g_assert_false(signbit(res));
3277     g_assert_true(endptr == str + 6);
3278 
3279     /* ...has less priority than EINVAL when full parse not possible */
3280     endptr = "somewhere";
3281     res = 999;
3282     err = qemu_strtod_finite(str, NULL, &res);
3283     g_assert_cmpint(err, ==, -EINVAL);
3284     g_assert_cmpfloat(res, ==, 0.0);
3285     g_assert_false(signbit(res));
3286 }
3287 
3288 typedef int (*qemu_strtosz_fn)(const char *, const char **, uint64_t *);
do_strtosz_full(const char * str,qemu_strtosz_fn fn,int exp_ptr_ret,uint64_t exp_ptr_val,size_t exp_ptr_offset,int exp_null_ret,uint64_t exp_null_val)3289 static void do_strtosz_full(const char *str, qemu_strtosz_fn fn,
3290                             int exp_ptr_ret, uint64_t exp_ptr_val,
3291                             size_t exp_ptr_offset, int exp_null_ret,
3292                             uint64_t exp_null_val)
3293 {
3294     const char *endptr = "somewhere";
3295     uint64_t val = 0xbaadf00d;
3296     int ret;
3297 
3298     ret = fn(str, &endptr, &val);
3299     g_assert_cmpint(ret, ==, exp_ptr_ret);
3300     g_assert_cmpuint(val, ==, exp_ptr_val);
3301     if (str) {
3302         g_assert_true(endptr == str + exp_ptr_offset);
3303     } else {
3304         g_assert_cmpint(exp_ptr_offset, ==, 0);
3305         g_assert_null(endptr);
3306     }
3307 
3308     val = 0xbaadf00d;
3309     ret = fn(str, NULL, &val);
3310     g_assert_cmpint(ret, ==, exp_null_ret);
3311     g_assert_cmpuint(val, ==, exp_null_val);
3312 }
3313 
do_strtosz(const char * str,int exp_ret,uint64_t exp_val,size_t exp_offset)3314 static void do_strtosz(const char *str, int exp_ret, uint64_t exp_val,
3315                        size_t exp_offset)
3316 {
3317     do_strtosz_full(str, qemu_strtosz, exp_ret, exp_val, exp_offset,
3318                     exp_ret, exp_val);
3319 }
3320 
do_strtosz_MiB(const char * str,int exp_ret,uint64_t exp_val,size_t exp_offset)3321 static void do_strtosz_MiB(const char *str, int exp_ret, uint64_t exp_val,
3322                            size_t exp_offset)
3323 {
3324     do_strtosz_full(str, qemu_strtosz_MiB, exp_ret, exp_val, exp_offset,
3325                     exp_ret, exp_val);
3326 }
3327 
do_strtosz_metric(const char * str,int exp_ret,uint64_t exp_val,size_t exp_offset)3328 static void do_strtosz_metric(const char *str, int exp_ret, uint64_t exp_val,
3329                               size_t exp_offset)
3330 {
3331     do_strtosz_full(str, qemu_strtosz_metric, exp_ret, exp_val, exp_offset,
3332                     exp_ret, exp_val);
3333 }
3334 
test_qemu_strtosz_simple(void)3335 static void test_qemu_strtosz_simple(void)
3336 {
3337     do_strtosz("0", 0, 0, 1);
3338 
3339     /* Leading 0 gives decimal results, not octal */
3340     do_strtosz("08", 0, 8, 2);
3341 
3342     /* Leading space and + are ignored */
3343     do_strtosz(" +12345", 0, 12345, 7);
3344 
3345     /* 2^53-1 */
3346     do_strtosz("9007199254740991", 0, 0x1fffffffffffffULL, 16);
3347 
3348     /* 2^53 */
3349     do_strtosz("9007199254740992", 0, 0x20000000000000ULL, 16);
3350 
3351     /* 2^53+1 */
3352     do_strtosz("9007199254740993", 0, 0x20000000000001ULL, 16);
3353 
3354     /* 0xfffffffffffff800 (53 msbs set) */
3355     do_strtosz("18446744073709549568", 0, 0xfffffffffffff800ULL, 20);
3356 
3357     /* 0xfffffffffffffbff */
3358     do_strtosz("18446744073709550591", 0, 0xfffffffffffffbffULL, 20);
3359 
3360     /* 0xffffffffffffffff */
3361     do_strtosz("18446744073709551615", 0, 0xffffffffffffffffULL, 20);
3362 }
3363 
test_qemu_strtosz_hex(void)3364 static void test_qemu_strtosz_hex(void)
3365 {
3366     do_strtosz("0x0", 0, 0, 3);
3367 
3368     do_strtosz("0xab", 0, 171, 4);
3369 
3370     do_strtosz(" +0xae", 0, 174, 6);
3371 }
3372 
test_qemu_strtosz_units(void)3373 static void test_qemu_strtosz_units(void)
3374 {
3375     /* default scale depends on function */
3376     do_strtosz("1", 0, 1, 1);
3377     do_strtosz_MiB("1", 0, MiB, 1);
3378     do_strtosz_metric("1", 0, 1, 1);
3379 
3380     /* Explicit byte suffix works for all functions */
3381     do_strtosz("1B", 0, 1, 2);
3382     do_strtosz_MiB("1B", 0, 1, 2);
3383     do_strtosz_metric("1B", 0, 1, 2);
3384 
3385     /* Expose the scale */
3386     do_strtosz("1K", 0, KiB, 2);
3387     do_strtosz_MiB("1K", 0, KiB, 2);
3388     do_strtosz_metric("1K", 0, 1000, 2);
3389 
3390     /* Other suffixes, see also test_qemu_strtosz_metric */
3391     do_strtosz("1M", 0, MiB, 2);
3392     do_strtosz("1G", 0, GiB, 2);
3393     do_strtosz("1T", 0, TiB, 2);
3394     do_strtosz("1P", 0, PiB, 2);
3395     do_strtosz("1E", 0, EiB, 2);
3396 }
3397 
test_qemu_strtosz_float(void)3398 static void test_qemu_strtosz_float(void)
3399 {
3400     do_strtosz("0.5E", 0, EiB / 2, 4);
3401 
3402     /* Implied M suffix okay */
3403     do_strtosz_MiB("0.5", 0, MiB / 2, 3);
3404 
3405     /* For convenience, a fraction of 0 is tolerated even on bytes */
3406     do_strtosz("1.0B", 0, 1, 4);
3407 
3408     /* An empty fraction tail is tolerated */
3409     do_strtosz("1.k", 0, 1024, 3);
3410 
3411     /* An empty fraction head is tolerated */
3412     do_strtosz(" .5k", 0, 512, 4);
3413 
3414     /* For convenience, we permit values that are not byte-exact */
3415     do_strtosz("12.345M", 0, (uint64_t) (12.345 * MiB + 0.5), 7);
3416 
3417     /* Fraction tail can round up */
3418     do_strtosz("1.9999k", 0, 2048, 7);
3419     do_strtosz("1.9999999999999999999999999999999999999999999999999999k", 0,
3420                2048, 55);
3421 
3422     /* ERANGE underflow in the fraction tail does not matter for 'k' */
3423     do_strtosz("1."
3424                "00000000000000000000000000000000000000000000000000"
3425                "00000000000000000000000000000000000000000000000000"
3426                "00000000000000000000000000000000000000000000000000"
3427                "00000000000000000000000000000000000000000000000000"
3428                "00000000000000000000000000000000000000000000000000"
3429                "00000000000000000000000000000000000000000000000000"
3430                "00000000000000000000000000000000000000000000000000"
3431                "1k", 0, 1024, 354);
3432 }
3433 
test_qemu_strtosz_invalid(void)3434 static void test_qemu_strtosz_invalid(void)
3435 {
3436     do_strtosz(NULL, -EINVAL, 0, 0);
3437 
3438     /* Must parse at least one digit */
3439     do_strtosz("", -EINVAL, 0, 0);
3440     do_strtosz(" \t ", -EINVAL, 0, 0);
3441     do_strtosz(".", -EINVAL, 0, 0);
3442     do_strtosz(" .", -EINVAL, 0, 0);
3443     do_strtosz(" .k", -EINVAL, 0, 0);
3444     do_strtosz("inf", -EINVAL, 0, 0);
3445     do_strtosz("NaN", -EINVAL, 0, 0);
3446 
3447     /* Lone suffix is not okay */
3448     do_strtosz("k", -EINVAL, 0, 0);
3449     do_strtosz(" M", -EINVAL, 0, 0);
3450 
3451     /* Fractional values require scale larger than bytes */
3452     do_strtosz("1.1B", -EINVAL, 0, 0);
3453     do_strtosz("1.1", -EINVAL, 0, 0);
3454 
3455     /* 'B' cannot have any nonzero fraction, even with rounding or underflow */
3456     do_strtosz("1.00001B", -EINVAL, 0, 0);
3457     do_strtosz("1.00000000000000000001B", -EINVAL, 0, 0);
3458     do_strtosz("1."
3459                "00000000000000000000000000000000000000000000000000"
3460                "00000000000000000000000000000000000000000000000000"
3461                "00000000000000000000000000000000000000000000000000"
3462                "00000000000000000000000000000000000000000000000000"
3463                "00000000000000000000000000000000000000000000000000"
3464                "00000000000000000000000000000000000000000000000000"
3465                "00000000000000000000000000000000000000000000000000"
3466                "1B", -EINVAL, 0, 0);
3467 
3468     /* No hex fractions */
3469     do_strtosz("0x1.8k", -EINVAL, 0, 0);
3470     do_strtosz("0x1.k", -EINVAL, 0, 0);
3471 
3472     /* No hex suffixes */
3473     do_strtosz("0x18M", -EINVAL, 0, 0);
3474     do_strtosz("0x1p1", -EINVAL, 0, 0);
3475 
3476     /* decimal in place of scaling suffix */
3477     do_strtosz("1.1.k", -EINVAL, 0, 0);
3478     do_strtosz("1.1.", -EINVAL, 0, 0);
3479 }
3480 
test_qemu_strtosz_trailing(void)3481 static void test_qemu_strtosz_trailing(void)
3482 {
3483     /* Trailing whitespace */
3484     do_strtosz_full("1k ", qemu_strtosz, 0, 1024, 2, -EINVAL, 0);
3485 
3486     /* Unknown suffix overrides even implied scale*/
3487     do_strtosz_full("123xxx", qemu_strtosz, 0, 123, 3, -EINVAL, 0);
3488 
3489     /* Implied scale allows partial parse */
3490     do_strtosz_full("123xxx", qemu_strtosz_MiB, 0, 123 * MiB, 3, -EINVAL, 0);
3491     do_strtosz_full("1.5.k", qemu_strtosz_MiB, 0, 1.5 * MiB, 3, -EINVAL, 0);
3492 
3493     /* Junk after one-byte suffix */
3494     do_strtosz_full("1kiB", qemu_strtosz, 0, 1024, 2, -EINVAL, 0);
3495 
3496     /* Incomplete hex is an unknown suffix */
3497     do_strtosz_full("0x", qemu_strtosz, 0, 0, 1, -EINVAL, 0);
3498 
3499     /* Hex literals use only one leading zero */
3500     do_strtosz_full("00x1", qemu_strtosz, 0, 0, 2, -EINVAL, 0);
3501 
3502     /* No support for binary literals; 'b' is valid suffix */
3503     do_strtosz_full("0b1000", qemu_strtosz, 0, 0, 2, -EINVAL, 0);
3504 
3505     /* Junk after decimal */
3506     do_strtosz_full("0.NaN", qemu_strtosz, 0, 0, 2, -EINVAL, 0);
3507 
3508     /* Although negatives are invalid, '-' may be in trailing junk */
3509     do_strtosz_full("123-45", qemu_strtosz, 0, 123, 3, -EINVAL, 0);
3510     do_strtosz_full(" 123 - 45", qemu_strtosz, 0, 123, 4, -EINVAL, 0);
3511 
3512     /* Parse stops at 'e', which is not a floating point exponent */
3513     do_strtosz_full("1.5e1k", qemu_strtosz, 0, EiB * 1.5, 4, -EINVAL, 0);
3514     do_strtosz_full("1.5E+0k", qemu_strtosz, 0, EiB * 1.5, 4, -EINVAL, 0);
3515     do_strtosz_full("1.5E999", qemu_strtosz, 0, EiB * 1.5, 4, -EINVAL, 0);
3516 }
3517 
test_qemu_strtosz_erange(void)3518 static void test_qemu_strtosz_erange(void)
3519 {
3520     /* no negative values */
3521     do_strtosz(" -0", -ERANGE, 0, 3);
3522     do_strtosz("-1", -ERANGE, 0, 2);
3523     do_strtosz_full("-2M", qemu_strtosz, -ERANGE, 0, 2, -EINVAL, 0);
3524     do_strtosz(" -.0", -ERANGE, 0, 4);
3525     do_strtosz_full("-.1k", qemu_strtosz, -ERANGE, 0, 3, -EINVAL, 0);
3526     do_strtosz_full(" -."
3527                     "00000000000000000000000000000000000000000000000000"
3528                     "00000000000000000000000000000000000000000000000000"
3529                     "00000000000000000000000000000000000000000000000000"
3530                     "00000000000000000000000000000000000000000000000000"
3531                     "00000000000000000000000000000000000000000000000000"
3532                     "00000000000000000000000000000000000000000000000000"
3533                     "00000000000000000000000000000000000000000000000000"
3534                     "1M", qemu_strtosz, -ERANGE, 0, 354, -EINVAL, 0);
3535 
3536     /* 2^64; see strtosz_simple for 2^64-1 */
3537     do_strtosz("18446744073709551616", -ERANGE, 0, 20);
3538 
3539     do_strtosz("20E", -ERANGE, 0, 3);
3540 
3541     /* Fraction tail can cause ERANGE overflow */
3542     do_strtosz("15.9999999999999999999999999999999999999999999999999999E",
3543                -ERANGE, 0, 56);
3544 
3545     /* EINVAL has priority over ERANGE */
3546     do_strtosz_full("100000Pjunk", qemu_strtosz, -ERANGE, 0, 7, -EINVAL, 0);
3547 }
3548 
test_qemu_strtosz_metric(void)3549 static void test_qemu_strtosz_metric(void)
3550 {
3551     do_strtosz_metric("12345k", 0, 12345000, 6);
3552     do_strtosz_metric("12.345M", 0, 12345000, 7);
3553 
3554     /* Fraction is affected by floating-point rounding */
3555     /* This would be 0xfffffffffffffbff with infinite precision */
3556     do_strtosz_metric("18.446744073709550591E", 0, 0xfffffffffffffc0cULL, 22);
3557 }
3558 
test_freq_to_str(void)3559 static void test_freq_to_str(void)
3560 {
3561     char *str;
3562 
3563     str = freq_to_str(999);
3564     g_assert_cmpstr(str, ==, "999 Hz");
3565     g_free(str);
3566 
3567     str = freq_to_str(1000);
3568     g_assert_cmpstr(str, ==, "1 KHz");
3569     g_free(str);
3570 
3571     str = freq_to_str(1010);
3572     g_assert_cmpstr(str, ==, "1.01 KHz");
3573     g_free(str);
3574 }
3575 
test_size_to_str(void)3576 static void test_size_to_str(void)
3577 {
3578     char *str;
3579 
3580     str = size_to_str(0);
3581     g_assert_cmpstr(str, ==, "0 B");
3582     g_free(str);
3583 
3584     str = size_to_str(1);
3585     g_assert_cmpstr(str, ==, "1 B");
3586     g_free(str);
3587 
3588     str = size_to_str(1016);
3589     g_assert_cmpstr(str, ==, "0.992 KiB");
3590     g_free(str);
3591 
3592     str = size_to_str(1024);
3593     g_assert_cmpstr(str, ==, "1 KiB");
3594     g_free(str);
3595 
3596     str = size_to_str(512ull << 20);
3597     g_assert_cmpstr(str, ==, "512 MiB");
3598     g_free(str);
3599 }
3600 
test_iec_binary_prefix(void)3601 static void test_iec_binary_prefix(void)
3602 {
3603     g_assert_cmpstr(iec_binary_prefix(0), ==, "");
3604     g_assert_cmpstr(iec_binary_prefix(10), ==, "Ki");
3605     g_assert_cmpstr(iec_binary_prefix(20), ==, "Mi");
3606     g_assert_cmpstr(iec_binary_prefix(30), ==, "Gi");
3607     g_assert_cmpstr(iec_binary_prefix(40), ==, "Ti");
3608     g_assert_cmpstr(iec_binary_prefix(50), ==, "Pi");
3609     g_assert_cmpstr(iec_binary_prefix(60), ==, "Ei");
3610 }
3611 
test_si_prefix(void)3612 static void test_si_prefix(void)
3613 {
3614     g_assert_cmpstr(si_prefix(-18), ==, "a");
3615     g_assert_cmpstr(si_prefix(-15), ==, "f");
3616     g_assert_cmpstr(si_prefix(-12), ==, "p");
3617     g_assert_cmpstr(si_prefix(-9), ==, "n");
3618     g_assert_cmpstr(si_prefix(-6), ==, "u");
3619     g_assert_cmpstr(si_prefix(-3), ==, "m");
3620     g_assert_cmpstr(si_prefix(0), ==, "");
3621     g_assert_cmpstr(si_prefix(3), ==, "K");
3622     g_assert_cmpstr(si_prefix(6), ==, "M");
3623     g_assert_cmpstr(si_prefix(9), ==, "G");
3624     g_assert_cmpstr(si_prefix(12), ==, "T");
3625     g_assert_cmpstr(si_prefix(15), ==, "P");
3626     g_assert_cmpstr(si_prefix(18), ==, "E");
3627 }
3628 
main(int argc,char ** argv)3629 int main(int argc, char **argv)
3630 {
3631     g_test_init(&argc, &argv, NULL);
3632 
3633     g_test_add_func("/cutils/parse_uint/null", test_parse_uint_null);
3634     g_test_add_func("/cutils/parse_uint/empty", test_parse_uint_empty);
3635     g_test_add_func("/cutils/parse_uint/whitespace",
3636                     test_parse_uint_whitespace);
3637     g_test_add_func("/cutils/parse_uint/invalid", test_parse_uint_invalid);
3638     g_test_add_func("/cutils/parse_uint/trailing", test_parse_uint_trailing);
3639     g_test_add_func("/cutils/parse_uint/correct", test_parse_uint_correct);
3640     g_test_add_func("/cutils/parse_uint/octal", test_parse_uint_octal);
3641     g_test_add_func("/cutils/parse_uint/decimal", test_parse_uint_decimal);
3642     g_test_add_func("/cutils/parse_uint/llong_max", test_parse_uint_llong_max);
3643     g_test_add_func("/cutils/parse_uint/max", test_parse_uint_max);
3644     g_test_add_func("/cutils/parse_uint/overflow", test_parse_uint_overflow);
3645     g_test_add_func("/cutils/parse_uint/negative", test_parse_uint_negative);
3646     g_test_add_func("/cutils/parse_uint/negzero", test_parse_uint_negzero);
3647     g_test_add_func("/cutils/parse_uint_full/trailing",
3648                     test_parse_uint_full_trailing);
3649     g_test_add_func("/cutils/parse_uint_full/correct",
3650                     test_parse_uint_full_correct);
3651     g_test_add_func("/cutils/parse_uint_full/erange_junk",
3652                     test_parse_uint_full_erange_junk);
3653     g_test_add_func("/cutils/parse_uint_full/null",
3654                     test_parse_uint_full_null);
3655 
3656     /* qemu_strtoi() tests */
3657     g_test_add_func("/cutils/qemu_strtoi/correct",
3658                     test_qemu_strtoi_correct);
3659     g_test_add_func("/cutils/qemu_strtoi/null",
3660                     test_qemu_strtoi_null);
3661     g_test_add_func("/cutils/qemu_strtoi/empty",
3662                     test_qemu_strtoi_empty);
3663     g_test_add_func("/cutils/qemu_strtoi/whitespace",
3664                     test_qemu_strtoi_whitespace);
3665     g_test_add_func("/cutils/qemu_strtoi/invalid",
3666                     test_qemu_strtoi_invalid);
3667     g_test_add_func("/cutils/qemu_strtoi/trailing",
3668                     test_qemu_strtoi_trailing);
3669     g_test_add_func("/cutils/qemu_strtoi/octal",
3670                     test_qemu_strtoi_octal);
3671     g_test_add_func("/cutils/qemu_strtoi/decimal",
3672                     test_qemu_strtoi_decimal);
3673     g_test_add_func("/cutils/qemu_strtoi/hex",
3674                     test_qemu_strtoi_hex);
3675     g_test_add_func("/cutils/qemu_strtoi/max",
3676                     test_qemu_strtoi_max);
3677     g_test_add_func("/cutils/qemu_strtoi/overflow",
3678                     test_qemu_strtoi_overflow);
3679     g_test_add_func("/cutils/qemu_strtoi/min",
3680                     test_qemu_strtoi_min);
3681     g_test_add_func("/cutils/qemu_strtoi/underflow",
3682                     test_qemu_strtoi_underflow);
3683     g_test_add_func("/cutils/qemu_strtoi/negative",
3684                     test_qemu_strtoi_negative);
3685     g_test_add_func("/cutils/qemu_strtoi/negzero",
3686                     test_qemu_strtoi_negzero);
3687     g_test_add_func("/cutils/qemu_strtoi_full/correct",
3688                     test_qemu_strtoi_full_correct);
3689     g_test_add_func("/cutils/qemu_strtoi_full/null",
3690                     test_qemu_strtoi_full_null);
3691     g_test_add_func("/cutils/qemu_strtoi_full/empty",
3692                     test_qemu_strtoi_full_empty);
3693     g_test_add_func("/cutils/qemu_strtoi_full/negative",
3694                     test_qemu_strtoi_full_negative);
3695     g_test_add_func("/cutils/qemu_strtoi_full/negzero",
3696                     test_qemu_strtoi_full_negzero);
3697     g_test_add_func("/cutils/qemu_strtoi_full/trailing",
3698                     test_qemu_strtoi_full_trailing);
3699     g_test_add_func("/cutils/qemu_strtoi_full/max",
3700                     test_qemu_strtoi_full_max);
3701     g_test_add_func("/cutils/qemu_strtoi_full/erange_junk",
3702                     test_qemu_strtoi_full_erange_junk);
3703 
3704     /* qemu_strtoui() tests */
3705     g_test_add_func("/cutils/qemu_strtoui/correct",
3706                     test_qemu_strtoui_correct);
3707     g_test_add_func("/cutils/qemu_strtoui/null",
3708                     test_qemu_strtoui_null);
3709     g_test_add_func("/cutils/qemu_strtoui/empty",
3710                     test_qemu_strtoui_empty);
3711     g_test_add_func("/cutils/qemu_strtoui/whitespace",
3712                     test_qemu_strtoui_whitespace);
3713     g_test_add_func("/cutils/qemu_strtoui/invalid",
3714                     test_qemu_strtoui_invalid);
3715     g_test_add_func("/cutils/qemu_strtoui/trailing",
3716                     test_qemu_strtoui_trailing);
3717     g_test_add_func("/cutils/qemu_strtoui/octal",
3718                     test_qemu_strtoui_octal);
3719     g_test_add_func("/cutils/qemu_strtoui/decimal",
3720                     test_qemu_strtoui_decimal);
3721     g_test_add_func("/cutils/qemu_strtoui/hex",
3722                     test_qemu_strtoui_hex);
3723     g_test_add_func("/cutils/qemu_strtoui/wrap",
3724                     test_qemu_strtoui_wrap);
3725     g_test_add_func("/cutils/qemu_strtoui/max",
3726                     test_qemu_strtoui_max);
3727     g_test_add_func("/cutils/qemu_strtoui/overflow",
3728                     test_qemu_strtoui_overflow);
3729     g_test_add_func("/cutils/qemu_strtoui/underflow",
3730                     test_qemu_strtoui_underflow);
3731     g_test_add_func("/cutils/qemu_strtoui/negative",
3732                     test_qemu_strtoui_negative);
3733     g_test_add_func("/cutils/qemu_strtoui/negzero",
3734                     test_qemu_strtoui_negzero);
3735     g_test_add_func("/cutils/qemu_strtoui_full/correct",
3736                     test_qemu_strtoui_full_correct);
3737     g_test_add_func("/cutils/qemu_strtoui_full/null",
3738                     test_qemu_strtoui_full_null);
3739     g_test_add_func("/cutils/qemu_strtoui_full/empty",
3740                     test_qemu_strtoui_full_empty);
3741     g_test_add_func("/cutils/qemu_strtoui_full/negative",
3742                     test_qemu_strtoui_full_negative);
3743     g_test_add_func("/cutils/qemu_strtoui_full/negzero",
3744                     test_qemu_strtoui_full_negzero);
3745     g_test_add_func("/cutils/qemu_strtoui_full/trailing",
3746                     test_qemu_strtoui_full_trailing);
3747     g_test_add_func("/cutils/qemu_strtoui_full/max",
3748                     test_qemu_strtoui_full_max);
3749     g_test_add_func("/cutils/qemu_strtoui_full/erange_junk",
3750                     test_qemu_strtoui_full_erange_junk);
3751 
3752     /* qemu_strtol() tests */
3753     g_test_add_func("/cutils/qemu_strtol/correct",
3754                     test_qemu_strtol_correct);
3755     g_test_add_func("/cutils/qemu_strtol/null",
3756                     test_qemu_strtol_null);
3757     g_test_add_func("/cutils/qemu_strtol/empty",
3758                     test_qemu_strtol_empty);
3759     g_test_add_func("/cutils/qemu_strtol/whitespace",
3760                     test_qemu_strtol_whitespace);
3761     g_test_add_func("/cutils/qemu_strtol/invalid",
3762                     test_qemu_strtol_invalid);
3763     g_test_add_func("/cutils/qemu_strtol/trailing",
3764                     test_qemu_strtol_trailing);
3765     g_test_add_func("/cutils/qemu_strtol/octal",
3766                     test_qemu_strtol_octal);
3767     g_test_add_func("/cutils/qemu_strtol/decimal",
3768                     test_qemu_strtol_decimal);
3769     g_test_add_func("/cutils/qemu_strtol/hex",
3770                     test_qemu_strtol_hex);
3771     g_test_add_func("/cutils/qemu_strtol/max",
3772                     test_qemu_strtol_max);
3773     g_test_add_func("/cutils/qemu_strtol/overflow",
3774                     test_qemu_strtol_overflow);
3775     g_test_add_func("/cutils/qemu_strtol/min",
3776                     test_qemu_strtol_min);
3777     g_test_add_func("/cutils/qemu_strtol/underflow",
3778                     test_qemu_strtol_underflow);
3779     g_test_add_func("/cutils/qemu_strtol/negative",
3780                     test_qemu_strtol_negative);
3781     g_test_add_func("/cutils/qemu_strtol/negzero",
3782                     test_qemu_strtol_negzero);
3783     g_test_add_func("/cutils/qemu_strtol_full/correct",
3784                     test_qemu_strtol_full_correct);
3785     g_test_add_func("/cutils/qemu_strtol_full/null",
3786                     test_qemu_strtol_full_null);
3787     g_test_add_func("/cutils/qemu_strtol_full/empty",
3788                     test_qemu_strtol_full_empty);
3789     g_test_add_func("/cutils/qemu_strtol_full/negative",
3790                     test_qemu_strtol_full_negative);
3791     g_test_add_func("/cutils/qemu_strtol_full/negzero",
3792                     test_qemu_strtol_full_negzero);
3793     g_test_add_func("/cutils/qemu_strtol_full/trailing",
3794                     test_qemu_strtol_full_trailing);
3795     g_test_add_func("/cutils/qemu_strtol_full/max",
3796                     test_qemu_strtol_full_max);
3797     g_test_add_func("/cutils/qemu_strtol_full/erange_junk",
3798                     test_qemu_strtol_full_erange_junk);
3799 
3800     /* qemu_strtoul() tests */
3801     g_test_add_func("/cutils/qemu_strtoul/correct",
3802                     test_qemu_strtoul_correct);
3803     g_test_add_func("/cutils/qemu_strtoul/null",
3804                     test_qemu_strtoul_null);
3805     g_test_add_func("/cutils/qemu_strtoul/empty",
3806                     test_qemu_strtoul_empty);
3807     g_test_add_func("/cutils/qemu_strtoul/whitespace",
3808                     test_qemu_strtoul_whitespace);
3809     g_test_add_func("/cutils/qemu_strtoul/invalid",
3810                     test_qemu_strtoul_invalid);
3811     g_test_add_func("/cutils/qemu_strtoul/trailing",
3812                     test_qemu_strtoul_trailing);
3813     g_test_add_func("/cutils/qemu_strtoul/octal",
3814                     test_qemu_strtoul_octal);
3815     g_test_add_func("/cutils/qemu_strtoul/decimal",
3816                     test_qemu_strtoul_decimal);
3817     g_test_add_func("/cutils/qemu_strtoul/hex",
3818                     test_qemu_strtoul_hex);
3819     g_test_add_func("/cutils/qemu_strtoul/wrap",
3820                     test_qemu_strtoul_wrap);
3821     g_test_add_func("/cutils/qemu_strtoul/max",
3822                     test_qemu_strtoul_max);
3823     g_test_add_func("/cutils/qemu_strtoul/overflow",
3824                     test_qemu_strtoul_overflow);
3825     g_test_add_func("/cutils/qemu_strtoul/underflow",
3826                     test_qemu_strtoul_underflow);
3827     g_test_add_func("/cutils/qemu_strtoul/negative",
3828                     test_qemu_strtoul_negative);
3829     g_test_add_func("/cutils/qemu_strtoul/negzero",
3830                     test_qemu_strtoul_negzero);
3831     g_test_add_func("/cutils/qemu_strtoul_full/correct",
3832                     test_qemu_strtoul_full_correct);
3833     g_test_add_func("/cutils/qemu_strtoul_full/null",
3834                     test_qemu_strtoul_full_null);
3835     g_test_add_func("/cutils/qemu_strtoul_full/empty",
3836                     test_qemu_strtoul_full_empty);
3837     g_test_add_func("/cutils/qemu_strtoul_full/negative",
3838                     test_qemu_strtoul_full_negative);
3839     g_test_add_func("/cutils/qemu_strtoul_full/negzero",
3840                     test_qemu_strtoul_full_negzero);
3841     g_test_add_func("/cutils/qemu_strtoul_full/trailing",
3842                     test_qemu_strtoul_full_trailing);
3843     g_test_add_func("/cutils/qemu_strtoul_full/max",
3844                     test_qemu_strtoul_full_max);
3845     g_test_add_func("/cutils/qemu_strtoul_full/erange_junk",
3846                     test_qemu_strtoul_full_erange_junk);
3847 
3848     /* qemu_strtoi64() tests */
3849     g_test_add_func("/cutils/qemu_strtoi64/correct",
3850                     test_qemu_strtoi64_correct);
3851     g_test_add_func("/cutils/qemu_strtoi64/null",
3852                     test_qemu_strtoi64_null);
3853     g_test_add_func("/cutils/qemu_strtoi64/empty",
3854                     test_qemu_strtoi64_empty);
3855     g_test_add_func("/cutils/qemu_strtoi64/whitespace",
3856                     test_qemu_strtoi64_whitespace);
3857     g_test_add_func("/cutils/qemu_strtoi64/invalid",
3858                     test_qemu_strtoi64_invalid);
3859     g_test_add_func("/cutils/qemu_strtoi64/trailing",
3860                     test_qemu_strtoi64_trailing);
3861     g_test_add_func("/cutils/qemu_strtoi64/octal",
3862                     test_qemu_strtoi64_octal);
3863     g_test_add_func("/cutils/qemu_strtoi64/decimal",
3864                     test_qemu_strtoi64_decimal);
3865     g_test_add_func("/cutils/qemu_strtoi64/hex",
3866                     test_qemu_strtoi64_hex);
3867     g_test_add_func("/cutils/qemu_strtoi64/max",
3868                     test_qemu_strtoi64_max);
3869     g_test_add_func("/cutils/qemu_strtoi64/overflow",
3870                     test_qemu_strtoi64_overflow);
3871     g_test_add_func("/cutils/qemu_strtoi64/min",
3872                     test_qemu_strtoi64_min);
3873     g_test_add_func("/cutils/qemu_strtoi64/underflow",
3874                     test_qemu_strtoi64_underflow);
3875     g_test_add_func("/cutils/qemu_strtoi64/negative",
3876                     test_qemu_strtoi64_negative);
3877     g_test_add_func("/cutils/qemu_strtoi64/negzero",
3878                     test_qemu_strtoi64_negzero);
3879     g_test_add_func("/cutils/qemu_strtoi64_full/correct",
3880                     test_qemu_strtoi64_full_correct);
3881     g_test_add_func("/cutils/qemu_strtoi64_full/null",
3882                     test_qemu_strtoi64_full_null);
3883     g_test_add_func("/cutils/qemu_strtoi64_full/empty",
3884                     test_qemu_strtoi64_full_empty);
3885     g_test_add_func("/cutils/qemu_strtoi64_full/negative",
3886                     test_qemu_strtoi64_full_negative);
3887     g_test_add_func("/cutils/qemu_strtoi64_full/negzero",
3888                     test_qemu_strtoi64_full_negzero);
3889     g_test_add_func("/cutils/qemu_strtoi64_full/trailing",
3890                     test_qemu_strtoi64_full_trailing);
3891     g_test_add_func("/cutils/qemu_strtoi64_full/max",
3892                     test_qemu_strtoi64_full_max);
3893     g_test_add_func("/cutils/qemu_strtoi64_full/erange_junk",
3894                     test_qemu_strtoi64_full_erange_junk);
3895 
3896     /* qemu_strtou64() tests */
3897     g_test_add_func("/cutils/qemu_strtou64/correct",
3898                     test_qemu_strtou64_correct);
3899     g_test_add_func("/cutils/qemu_strtou64/null",
3900                     test_qemu_strtou64_null);
3901     g_test_add_func("/cutils/qemu_strtou64/empty",
3902                     test_qemu_strtou64_empty);
3903     g_test_add_func("/cutils/qemu_strtou64/whitespace",
3904                     test_qemu_strtou64_whitespace);
3905     g_test_add_func("/cutils/qemu_strtou64/invalid",
3906                     test_qemu_strtou64_invalid);
3907     g_test_add_func("/cutils/qemu_strtou64/trailing",
3908                     test_qemu_strtou64_trailing);
3909     g_test_add_func("/cutils/qemu_strtou64/octal",
3910                     test_qemu_strtou64_octal);
3911     g_test_add_func("/cutils/qemu_strtou64/decimal",
3912                     test_qemu_strtou64_decimal);
3913     g_test_add_func("/cutils/qemu_strtou64/hex",
3914                     test_qemu_strtou64_hex);
3915     g_test_add_func("/cutils/qemu_strtou64/wrap",
3916                     test_qemu_strtou64_wrap);
3917     g_test_add_func("/cutils/qemu_strtou64/max",
3918                     test_qemu_strtou64_max);
3919     g_test_add_func("/cutils/qemu_strtou64/overflow",
3920                     test_qemu_strtou64_overflow);
3921     g_test_add_func("/cutils/qemu_strtou64/underflow",
3922                     test_qemu_strtou64_underflow);
3923     g_test_add_func("/cutils/qemu_strtou64/negative",
3924                     test_qemu_strtou64_negative);
3925     g_test_add_func("/cutils/qemu_strtou64/negzero",
3926                     test_qemu_strtou64_negzero);
3927     g_test_add_func("/cutils/qemu_strtou64_full/correct",
3928                     test_qemu_strtou64_full_correct);
3929     g_test_add_func("/cutils/qemu_strtou64_full/null",
3930                     test_qemu_strtou64_full_null);
3931     g_test_add_func("/cutils/qemu_strtou64_full/empty",
3932                     test_qemu_strtou64_full_empty);
3933     g_test_add_func("/cutils/qemu_strtou64_full/negative",
3934                     test_qemu_strtou64_full_negative);
3935     g_test_add_func("/cutils/qemu_strtou64_full/negzero",
3936                     test_qemu_strtou64_full_negzero);
3937     g_test_add_func("/cutils/qemu_strtou64_full/trailing",
3938                     test_qemu_strtou64_full_trailing);
3939     g_test_add_func("/cutils/qemu_strtou64_full/max",
3940                     test_qemu_strtou64_full_max);
3941     g_test_add_func("/cutils/qemu_strtou64_full/erange_junk",
3942                     test_qemu_strtou64_full_erange_junk);
3943 
3944     /* qemu_strtod() tests */
3945     g_test_add_func("/cutils/qemu_strtod/simple",
3946                     test_qemu_strtod_simple);
3947     g_test_add_func("/cutils/qemu_strtod/einval",
3948                     test_qemu_strtod_einval);
3949     g_test_add_func("/cutils/qemu_strtod/erange",
3950                     test_qemu_strtod_erange);
3951     g_test_add_func("/cutils/qemu_strtod/nonfinite",
3952                     test_qemu_strtod_nonfinite);
3953     g_test_add_func("/cutils/qemu_strtod/trailing",
3954                     test_qemu_strtod_trailing);
3955     g_test_add_func("/cutils/qemu_strtod/erange_junk",
3956                     test_qemu_strtod_erange_junk);
3957 
3958     /* qemu_strtod_finite() tests */
3959     g_test_add_func("/cutils/qemu_strtod_finite/simple",
3960                     test_qemu_strtod_finite_simple);
3961     g_test_add_func("/cutils/qemu_strtod_finite/einval",
3962                     test_qemu_strtod_finite_einval);
3963     g_test_add_func("/cutils/qemu_strtod_finite/erange",
3964                     test_qemu_strtod_finite_erange);
3965     g_test_add_func("/cutils/qemu_strtod_finite/nonfinite",
3966                     test_qemu_strtod_finite_nonfinite);
3967     g_test_add_func("/cutils/qemu_strtod_finite/trailing",
3968                     test_qemu_strtod_finite_trailing);
3969     g_test_add_func("/cutils/qemu_strtod_finite/erange_junk",
3970                     test_qemu_strtod_finite_erange_junk);
3971 
3972     /* qemu_strtosz() tests */
3973     g_test_add_func("/cutils/strtosz/simple",
3974                     test_qemu_strtosz_simple);
3975     g_test_add_func("/cutils/strtosz/hex",
3976                     test_qemu_strtosz_hex);
3977     g_test_add_func("/cutils/strtosz/units",
3978                     test_qemu_strtosz_units);
3979     g_test_add_func("/cutils/strtosz/float",
3980                     test_qemu_strtosz_float);
3981     g_test_add_func("/cutils/strtosz/invalid",
3982                     test_qemu_strtosz_invalid);
3983     g_test_add_func("/cutils/strtosz/trailing",
3984                     test_qemu_strtosz_trailing);
3985     g_test_add_func("/cutils/strtosz/erange",
3986                     test_qemu_strtosz_erange);
3987     g_test_add_func("/cutils/strtosz/metric",
3988                     test_qemu_strtosz_metric);
3989 
3990     g_test_add_func("/cutils/size_to_str",
3991                     test_size_to_str);
3992     g_test_add_func("/cutils/freq_to_str",
3993                     test_freq_to_str);
3994     g_test_add_func("/cutils/iec_binary_prefix",
3995                     test_iec_binary_prefix);
3996     g_test_add_func("/cutils/si_prefix",
3997                     test_si_prefix);
3998     return g_test_run();
3999 }
4000