1 1.8 christos /* $NetBSD: t_strtol.c,v 1.8 2024/07/22 16:41:05 christos Exp $ */ 2 1.1 jruoho 3 1.1 jruoho /*- 4 1.1 jruoho * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 1.1 jruoho * All rights reserved. 6 1.1 jruoho * 7 1.1 jruoho * This code is derived from software contributed to The NetBSD Foundation 8 1.1 jruoho * by Jukka Ruohonen. 9 1.1 jruoho * 10 1.1 jruoho * Redistribution and use in source and binary forms, with or without 11 1.1 jruoho * modification, are permitted provided that the following conditions 12 1.1 jruoho * are met: 13 1.1 jruoho * 1. Redistributions of source code must retain the above copyright 14 1.1 jruoho * notice, this list of conditions and the following disclaimer. 15 1.1 jruoho * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 jruoho * notice, this list of conditions and the following disclaimer in the 17 1.1 jruoho * documentation and/or other materials provided with the distribution. 18 1.1 jruoho * 19 1.1 jruoho * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 jruoho * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 jruoho * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 jruoho * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 jruoho * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 jruoho * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 jruoho * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 jruoho * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 jruoho * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 jruoho * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 jruoho * POSSIBILITY OF SUCH DAMAGE. 30 1.1 jruoho */ 31 1.1 jruoho 32 1.1 jruoho #include <sys/cdefs.h> 33 1.8 christos __RCSID("$NetBSD: t_strtol.c,v 1.8 2024/07/22 16:41:05 christos Exp $"); 34 1.1 jruoho 35 1.1 jruoho #include <atf-c.h> 36 1.1 jruoho #include <errno.h> 37 1.8 christos #include <inttypes.h> 38 1.1 jruoho #include <stdlib.h> 39 1.1 jruoho #include <string.h> 40 1.1 jruoho #include <limits.h> 41 1.1 jruoho 42 1.1 jruoho struct test { 43 1.1 jruoho const char *str; 44 1.4 jruoho int64_t res; 45 1.1 jruoho int base; 46 1.1 jruoho const char *end; 47 1.1 jruoho }; 48 1.1 jruoho 49 1.1 jruoho static void 50 1.8 christos check(struct test *t, long int li, long long int lli, intmax_t ji, char *end) 51 1.1 jruoho { 52 1.1 jruoho 53 1.1 jruoho if (li != -1 && li != t->res) 54 1.1 jruoho atf_tc_fail_nonfatal("strtol(%s, &end, %d) failed " 55 1.1 jruoho "(rv = %ld)", t->str, t->base, li); 56 1.1 jruoho 57 1.3 jruoho if (lli != -1 && lli != t->res) 58 1.1 jruoho atf_tc_fail_nonfatal("strtoll(%s, NULL, %d) failed " 59 1.1 jruoho "(rv = %lld)", t->str, t->base, lli); 60 1.1 jruoho 61 1.8 christos if (ji != -1 && ji != t->res) 62 1.8 christos atf_tc_fail_nonfatal("strtoll(%s, NULL, %d) failed " 63 1.8 christos "(rv = %jd)", t->str, t->base, ji); 64 1.8 christos 65 1.6 pgoyette if ((t->end != NULL && strcmp(t->end, end) != 0) || 66 1.6 pgoyette (t->end == NULL && *end != '\0')) 67 1.7 joerg atf_tc_fail_nonfatal("invalid end pointer (%p) from " 68 1.7 joerg "strtol(%p, &end, %d)", end, t->str, t->base); 69 1.1 jruoho } 70 1.1 jruoho 71 1.1 jruoho ATF_TC(strtol_base); 72 1.1 jruoho ATF_TC_HEAD(strtol_base, tc) 73 1.1 jruoho { 74 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test strtol(3) with different bases"); 75 1.1 jruoho } 76 1.1 jruoho 77 1.1 jruoho ATF_TC_BODY(strtol_base, tc) 78 1.1 jruoho { 79 1.1 jruoho struct test t[] = { 80 1.1 jruoho { "123456789", 123456789, 0, NULL }, 81 1.1 jruoho { "111010110111100110100010101", 123456789, 2, NULL }, 82 1.1 jruoho { "22121022020212200", 123456789, 3, NULL }, 83 1.1 jruoho { "13112330310111", 123456789, 4, NULL }, 84 1.1 jruoho { "223101104124", 123456789, 5, NULL }, 85 1.1 jruoho { "20130035113", 123456789, 6, NULL }, 86 1.1 jruoho { "3026236221", 123456789, 7, NULL }, 87 1.1 jruoho { "726746425", 123456789, 8, NULL }, 88 1.1 jruoho { "277266780", 123456789, 9, NULL }, 89 1.1 jruoho { "123456789", 123456789, 10, NULL }, 90 1.1 jruoho { "63762A05", 123456789, 11, NULL }, 91 1.1 jruoho { "35418A99", 123456789, 12, NULL }, 92 1.1 jruoho { "1C767471", 123456789, 13, NULL }, 93 1.1 jruoho { "12579781", 123456789, 14, NULL }, 94 1.1 jruoho { "AC89BC9", 123456789, 15, NULL }, 95 1.1 jruoho { "75BCD15", 123456789, 16, NULL }, 96 1.6 pgoyette { "1234567", 342391, 8, NULL }, 97 1.6 pgoyette { "01234567", 342391, 0, NULL }, 98 1.1 jruoho { "0123456789", 123456789, 10, NULL }, 99 1.7 joerg { "0x75bcd15", 123456789, 0, NULL }, 100 1.7 joerg { " 0xX", 0, 0, "xX" }, 101 1.7 joerg { " 0xX", 0, 16, "xX" }, 102 1.7 joerg { " 0XX", 0, 0, "XX" }, 103 1.7 joerg { " 0XX", 0, 16, "XX" }, 104 1.1 jruoho }; 105 1.1 jruoho 106 1.1 jruoho long long int lli; 107 1.1 jruoho long int li; 108 1.8 christos intmax_t ji; 109 1.7 joerg long long int ulli; 110 1.7 joerg long int uli; 111 1.8 christos uintmax_t uji; 112 1.7 joerg char *end, *end2; 113 1.1 jruoho size_t i; 114 1.1 jruoho 115 1.1 jruoho for (i = 0; i < __arraycount(t); i++) { 116 1.1 jruoho 117 1.1 jruoho li = strtol(t[i].str, &end, t[i].base); 118 1.1 jruoho lli = strtoll(t[i].str, NULL, t[i].base); 119 1.8 christos ji = strtoimax(t[i].str, NULL, t[i].base); 120 1.1 jruoho 121 1.7 joerg uli = strtoul(t[i].str, &end2, t[i].base); 122 1.7 joerg ulli = strtoull(t[i].str, NULL, t[i].base); 123 1.8 christos uji = strtoumax(t[i].str, NULL, t[i].base); 124 1.7 joerg 125 1.8 christos check(&t[i], li, lli, ji, end); 126 1.7 joerg 127 1.7 joerg if (li != uli) 128 1.7 joerg atf_tc_fail_nonfatal("strtoul(%s, NULL, %d) failed " 129 1.7 joerg "(rv = %lu)", t[i].str, t[i].base, uli); 130 1.8 christos if (lli != ulli) 131 1.8 christos atf_tc_fail_nonfatal("strtoull(%s, NULL, %d) failed " 132 1.8 christos "(rv = %llu)", t[i].str, t[i].base, ulli); 133 1.8 christos if ((uintmax_t)ji != uji) 134 1.8 christos atf_tc_fail_nonfatal("strtoumax(%s, NULL, %d) failed " 135 1.8 christos "(rv = %ju)", t[i].str, t[i].base, uji); 136 1.7 joerg if (end != end2) 137 1.7 joerg atf_tc_fail_nonfatal("invalid end pointer ('%p') from " 138 1.7 joerg "strtoul(%s, &end, %d)", end2, t[i].str, t[i].base); 139 1.1 jruoho } 140 1.1 jruoho } 141 1.1 jruoho 142 1.8 christos ATF_TC(strtol_invbase); 143 1.8 christos ATF_TC_HEAD(strtol_invbase, tc) 144 1.8 christos { 145 1.8 christos atf_tc_set_md_var(tc, "descr", "Test strtol(3) with an invalid base"); 146 1.8 christos } 147 1.8 christos 148 1.8 christos ATF_TC_BODY(strtol_invbase, tc) 149 1.8 christos { 150 1.8 christos long long int lli; 151 1.8 christos long int li; 152 1.8 christos intmax_t ji; 153 1.8 christos long long int ulli; 154 1.8 christos long int uli; 155 1.8 christos uintmax_t uji; 156 1.8 christos char *end; 157 1.8 christos char boo[] = "boo"; 158 1.8 christos const char str[] = "1"; 159 1.8 christos 160 1.8 christos #define CHECK(r, f, fun) \ 161 1.8 christos end = boo; \ 162 1.8 christos r = fun(str, &end, -2); \ 163 1.8 christos if (strcmp(str, end) != 0) \ 164 1.8 christos atf_tc_fail_nonfatal( \ 165 1.8 christos "%s(1, boo, -2) failed endptr=%s ", # fun, end); \ 166 1.8 christos if (r) \ 167 1.8 christos atf_tc_fail_nonfatal( \ 168 1.8 christos "%s(1, boo, -2) failed rv=" f, # fun, r); \ 169 1.8 christos if (errno != EINVAL) \ 170 1.8 christos atf_tc_fail_nonfatal( \ 171 1.8 christos "%s(1, boo, -2) failed errno=%d", # fun, errno) 172 1.8 christos 173 1.8 christos CHECK(li, "%ld", strtol); 174 1.8 christos CHECK(lli, "%lld", strtoll); 175 1.8 christos CHECK(ji, "%jd", strtoimax); 176 1.8 christos CHECK(uli, "%lu", strtoul); 177 1.8 christos CHECK(ulli, "%llu", strtoull); 178 1.8 christos CHECK(uji, "%ju", strtoumax); 179 1.8 christos } 180 1.8 christos 181 1.1 jruoho ATF_TC(strtol_case); 182 1.1 jruoho ATF_TC_HEAD(strtol_case, tc) 183 1.1 jruoho { 184 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Case insensitivity with strtol(3)"); 185 1.1 jruoho } 186 1.1 jruoho 187 1.1 jruoho ATF_TC_BODY(strtol_case, tc) 188 1.1 jruoho { 189 1.1 jruoho struct test t[] = { 190 1.1 jruoho { "abcd", 0xabcd, 16, NULL }, 191 1.1 jruoho { " dcba", 0xdcba, 16, NULL }, 192 1.1 jruoho { "abcd dcba", 0xabcd, 16, " dcba" }, 193 1.6 pgoyette { "abc0x123", 0xabc0, 16, "x123" }, 194 1.1 jruoho { "abcd\0x123", 0xabcd, 16, "\0x123" }, 195 1.1 jruoho { "ABCD", 0xabcd, 16, NULL }, 196 1.1 jruoho { "aBcD", 0xabcd, 16, NULL }, 197 1.1 jruoho { "0xABCD", 0xabcd, 16, NULL }, 198 1.1 jruoho { "0xABCDX", 0xabcd, 16, "X" }, 199 1.1 jruoho }; 200 1.1 jruoho 201 1.1 jruoho long long int lli; 202 1.1 jruoho long int li; 203 1.8 christos intmax_t ji; 204 1.1 jruoho char *end; 205 1.1 jruoho size_t i; 206 1.1 jruoho 207 1.1 jruoho for (i = 0; i < __arraycount(t); i++) { 208 1.1 jruoho 209 1.1 jruoho li = strtol(t[i].str, &end, t[i].base); 210 1.1 jruoho lli = strtoll(t[i].str, NULL, t[i].base); 211 1.8 christos ji = strtoimax(t[i].str, NULL, t[i].base); 212 1.1 jruoho 213 1.8 christos check(&t[i], li, lli, ji, end); 214 1.1 jruoho } 215 1.1 jruoho } 216 1.1 jruoho 217 1.1 jruoho ATF_TC(strtol_range); 218 1.1 jruoho ATF_TC_HEAD(strtol_range, tc) 219 1.1 jruoho { 220 1.1 jruoho atf_tc_set_md_var(tc, "descr", "Test ERANGE from strtol(3)"); 221 1.1 jruoho } 222 1.1 jruoho 223 1.1 jruoho ATF_TC_BODY(strtol_range, tc) 224 1.1 jruoho { 225 1.1 jruoho 226 1.1 jruoho #if LONG_MAX == 0x7fffffff /* XXX: Is this portable? */ 227 1.1 jruoho 228 1.1 jruoho struct test t[] = { 229 1.1 jruoho { "20000000000", 2147483647, 8, NULL }, 230 1.1 jruoho { "2147483648", 2147483647, 10, NULL }, 231 1.1 jruoho { "80000000", 2147483647, 16, NULL }, 232 1.1 jruoho }; 233 1.1 jruoho #else 234 1.1 jruoho struct test t[] = { 235 1.1 jruoho { "1000000000000000000000", 9223372036854775807, 8, NULL }, 236 1.1 jruoho { "9223372036854775808", 9223372036854775807, 10, NULL }, 237 1.1 jruoho { "8000000000000000", 9223372036854775807, 16, NULL }, 238 1.1 jruoho }; 239 1.1 jruoho #endif 240 1.1 jruoho 241 1.1 jruoho long int li; 242 1.1 jruoho char *end; 243 1.1 jruoho size_t i; 244 1.1 jruoho 245 1.1 jruoho for (i = 0; i < __arraycount(t); i++) { 246 1.1 jruoho 247 1.1 jruoho errno = 0; 248 1.1 jruoho li = strtol(t[i].str, &end, t[i].base); 249 1.1 jruoho 250 1.1 jruoho if (errno != ERANGE) 251 1.1 jruoho atf_tc_fail("strtol(3) did not catch ERANGE"); 252 1.1 jruoho 253 1.8 christos check(&t[i], li, -1, -1, end); 254 1.1 jruoho } 255 1.1 jruoho } 256 1.1 jruoho 257 1.1 jruoho ATF_TC(strtol_signed); 258 1.1 jruoho ATF_TC_HEAD(strtol_signed, tc) 259 1.1 jruoho { 260 1.1 jruoho atf_tc_set_md_var(tc, "descr", "A basic test of strtol(3)"); 261 1.1 jruoho } 262 1.1 jruoho 263 1.1 jruoho ATF_TC_BODY(strtol_signed, tc) 264 1.1 jruoho { 265 1.1 jruoho struct test t[] = { 266 1.1 jruoho { "1", 1, 0, NULL }, 267 1.1 jruoho { " 2", 2, 0, NULL }, 268 1.1 jruoho { " 3", 3, 0, NULL }, 269 1.1 jruoho { " -3", -3, 0, NULL }, 270 1.1 jruoho { "--1", 0, 0, "--1" }, 271 1.1 jruoho { "+-2", 0, 0, "+-2" }, 272 1.1 jruoho { "++3", 0, 0, "++3" }, 273 1.1 jruoho { "+9", 9, 0, NULL }, 274 1.1 jruoho { "+123", 123, 0, NULL }, 275 1.1 jruoho { "-1 3", -1, 0, " 3" }, 276 1.1 jruoho { "-1.3", -1, 0, ".3" }, 277 1.1 jruoho { "- 3", 0, 0, "- 3" }, 278 1.1 jruoho { "+33.", 33, 0, "." }, 279 1.1 jruoho { "30x0", 30, 0, "x0" }, 280 1.1 jruoho }; 281 1.1 jruoho 282 1.1 jruoho long long int lli; 283 1.1 jruoho long int li; 284 1.8 christos intmax_t ji; 285 1.1 jruoho char *end; 286 1.1 jruoho size_t i; 287 1.1 jruoho 288 1.1 jruoho for (i = 0; i < __arraycount(t); i++) { 289 1.1 jruoho 290 1.1 jruoho li = strtol(t[i].str, &end, t[i].base); 291 1.1 jruoho lli = strtoll(t[i].str, NULL, t[i].base); 292 1.8 christos ji = strtoimax(t[i].str, NULL, t[i].base); 293 1.1 jruoho 294 1.8 christos check(&t[i], li, lli, ji, end); 295 1.1 jruoho } 296 1.1 jruoho } 297 1.1 jruoho 298 1.1 jruoho ATF_TP_ADD_TCS(tp) 299 1.1 jruoho { 300 1.1 jruoho 301 1.8 christos ATF_TP_ADD_TC(tp, strtol_invbase); 302 1.1 jruoho ATF_TP_ADD_TC(tp, strtol_base); 303 1.1 jruoho ATF_TP_ADD_TC(tp, strtol_case); 304 1.1 jruoho ATF_TP_ADD_TC(tp, strtol_range); 305 1.1 jruoho ATF_TP_ADD_TC(tp, strtol_signed); 306 1.1 jruoho 307 1.1 jruoho return atf_no_error(); 308 1.1 jruoho } 309