1 /*
2  * Copyright © 2005-2020 Rich Felker
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 
28 /* r = place to store result
29  * f = function call to test (or any expression)
30  * x = expected result
31  * m = message to print on failure (with formats for r & x)
32 **/
33 
34 #pragma GCC diagnostic ignored "-Wpragmas"
35 #pragma GCC diagnostic ignored "-Wunknown-warning-option"
36 #pragma GCC diagnostic ignored "-Wformat-extra-args"
37 #pragma GCC diagnostic ignored "-Wformat"
38 
39 #define TEST(r, f, x, m) ( \
40 msg = #f, ((r) = (f)) == (x) || \
41 (printf(__FILE__ ":%d: %s failed (" m ")\n", __LINE__, #f, r, x), err++, 0) )
42 
43 #define TEST2(r, f, x, m) ( \
44 ((r) = (f)) == (x) || \
45 (printf(__FILE__ ":%d: %s failed (" m ")\n", __LINE__, msg, r, x), err++, 0) )
46 
test_strtol(void)47 int test_strtol(void)
48 {
49 	int i;
50 	long l;
51 	unsigned long ul;
52 	long long ll;
53 	unsigned long long ull;
54 	char *msg="";
55 	int err=0;
56 	char *s, *c;
57 
58         (void) ll;
59         (void) ull;
60 	TEST(l, atol("2147483647"), 2147483647L, "max 32bit signed %ld != %ld");
61 
62 	TEST(l, strtol("2147483647", 0, 0), 2147483647L, "max 32bit signed %ld != %ld");
63 	TEST(ul, strtoul("4294967295", 0, 0), 4294967295UL, "max 32bit unsigned %lu != %lu");
64 
65 	if (sizeof(long) == 4) {
66 		errno = 0;
67 		TEST(l, strtol(s="2147483648", &c, 0), 2147483647L, "uncaught overflow %ld != %ld");
68 		TEST2(i, c-s, 10, "wrong final position %d != %d");
69 		TEST2(i, errno, ERANGE, "missing errno %d != %d");
70 		errno = 0;
71 		TEST(l, strtol(s="-2147483649", &c, 0), -2147483647L-1, "uncaught overflow %ld != %ld");
72 		TEST2(i, c-s, 11, "wrong final position %d != %d");
73 		TEST2(i, errno, ERANGE, "missing errno %d != %d");
74 		errno = 0;
75 		TEST(ul, strtoul(s="4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu");
76 		TEST2(i, c-s, 10, "wrong final position %d != %d");
77 		TEST2(i, errno, ERANGE, "missing errno %d != %d");
78 		errno = 0;
79 		TEST(ul, strtoul(s="-1", &c, 0), -1UL, "rejected negative %lu != %lu");
80 		TEST2(i, c-s, 2, "wrong final position %d != %d");
81 		TEST2(i, errno, 0, "spurious errno %d != %d");
82 		errno = 0;
83 		TEST(ul, strtoul(s="-2", &c, 0), -2UL, "rejected negative %lu != %lu");
84 		TEST2(i, c-s, 2, "wrong final position %d != %d");
85 		TEST2(i, errno, 0, "spurious errno %d != %d");
86 		errno = 0;
87 		TEST(ul, strtoul(s="-2147483648", &c, 0), -2147483648UL, "rejected negative %lu != %lu");
88 		TEST2(i, c-s, 11, "wrong final position %d != %d");
89 		TEST2(i, errno, 0, "spurious errno %d != %d");
90 		errno = 0;
91 		TEST(ul, strtoul(s="-2147483649", &c, 0), -2147483649UL, "rejected negative %lu != %lu");
92 		TEST2(i, c-s, 11, "wrong final position %d != %d");
93 		TEST2(i, errno, 0, "spurious errno %d != %d");
94 	} else {
95 		errno = 0;
96 		TEST(l, strtol(s="9223372036854775808", &c, 0), 9223372036854775807L, "uncaught overflow %ld != %ld");
97 		TEST2(i, c-s, 19, "wrong final position %d != %d");
98 		TEST2(i, errno, ERANGE, "missing errno %d != %d");
99 		errno = 0;
100 		TEST(l, strtol(s="-9223372036854775809", &c, 0), -9223372036854775807L-1, "uncaught overflow %ld != %ld");
101 		TEST2(i, c-s, 20, "wrong final position %d != %d");
102 		TEST2(i, errno, ERANGE, "missing errno %d != %d");
103 		errno = 0;
104 		TEST(ul, strtoul(s="18446744073709551616", &c, 0), 18446744073709551615UL, "uncaught overflow %lu != %lu");
105 		TEST2(i, c-s, 20, "wrong final position %d != %d");
106 		TEST2(i, errno, ERANGE, "missing errno %d != %d");
107 		errno = 0;
108 		TEST(ul, strtoul(s="-1", &c, 0), -1UL, "rejected negative %lu != %lu");
109 		TEST2(i, c-s, 2, "wrong final position %d != %d");
110 		TEST2(i, errno, 0, "spurious errno %d != %d");
111 		errno = 0;
112 		TEST(ul, strtoul(s="-2", &c, 0), -2UL, "rejected negative %lu != %lu");
113 		TEST2(i, c-s, 2, "wrong final position %d != %d");
114 		TEST2(i, errno, 0, "spurious errno %d != %d");
115 		errno = 0;
116 		TEST(ul, strtoul(s="-9223372036854775808", &c, 0), -9223372036854775808UL, "rejected negative %lu != %lu");
117 		TEST2(i, c-s, 20, "wrong final position %d != %d");
118 		TEST2(i, errno, 0, "spurious errno %d != %d");
119 		errno = 0;
120 		TEST(ul, strtoul(s="-9223372036854775809", &c, 0), -9223372036854775809UL, "rejected negative %lu != %lu");
121 		TEST2(i, c-s, 20, "wrong final position %d != %d");
122 		TEST2(i, errno, 0, "spurious errno %d != %d");
123 	}
124 
125 	TEST(l, strtol("z", 0, 36), 35, "%ld != %ld");
126 	TEST(l, strtol("00010010001101000101011001111000", 0, 2), 0x12345678, "%ld != %ld");
127 	TEST(l, strtol(s="0F5F", &c, 16), 0x0f5f, "%ld != %ld");
128 
129 	TEST(l, strtol(s="0xz", &c, 16), 0, "%ld != %ld");
130 	TEST2(i, c-s, 1, "wrong final position %ld != %ld");
131 
132 	TEST(l, strtol(s="0x1234", &c, 16), 0x1234, "%ld != %ld");
133 	TEST2(i, c-s, 6, "wrong final position %ld != %ld");
134 
135         char delim_buf[6] = "09af:";
136 
137         for (int j = 0; j < 256; j++) {
138             delim_buf[4] = j;
139             if (('0' <= j && j <= '9') ||
140                 ('A' <= j && j <= 'F') ||
141                 ('a' <= j && j <= 'f'))
142             {
143                 long k;
144                 if ('0' <= j && j <= '9')
145                     k = j - '0';
146                 else if ('A' <= j && j <= 'Z')
147                     k = j - 'A' + 10;
148                 else if ('a' <= j && j <= 'z')
149                     k = j - 'a' + 10;
150                 else
151                     k = 0xffffffff;
152                 TEST(l, strtol(s=delim_buf, &c, 16), 0x09af0 | k, "%ld != %ld");
153                 TEST2(i, c-s, 5, "wrong final position %ld != %ld");
154             } else {
155                 TEST(l, strtol(s=delim_buf, &c, 16), 0x09af, "%ld != %ld");
156                 TEST2(i, c-s, 4, "wrong final position %ld != %ld");
157             }
158         }
159 
160 	errno = 0;
161 	c = NULL;
162 	TEST(l, strtol(s="123", &c, 37), 0, "%ld != %ld");
163 	TEST2(i, c-s, 0, "wrong final position %d != %d");
164 	TEST2(i, errno, EINVAL, "%d != %d");
165 
166 	TEST(l, strtol(s="  15437", &c, 8), 015437, "%ld != %ld");
167 	TEST2(i, c-s, 7, "wrong final position %d != %d");
168 
169 	TEST(l, strtol(s="  1", &c, 0), 1, "%ld != %ld");
170 	TEST2(i, c-s, 3, "wrong final position %d != %d");
171 
172 	return err;
173 }
174 
175 #define TEST_NAME strtol
176 #include "testcase.h"
177