xref: /freebsd/crypto/openssl/test/strtoultest.c (revision e7be843b4a162e68651d3911f0357ed464915629)
1*e7be843bSPierre Pronchery /*
2*e7be843bSPierre Pronchery  * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
3*e7be843bSPierre Pronchery  *
4*e7be843bSPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5*e7be843bSPierre Pronchery  * this file except in compliance with the License.  You can obtain a copy
6*e7be843bSPierre Pronchery  * in the file LICENSE in the source distribution or at
7*e7be843bSPierre Pronchery  * https://www.openssl.org/source/license.html
8*e7be843bSPierre Pronchery  */
9*e7be843bSPierre Pronchery 
10*e7be843bSPierre Pronchery #include <openssl/crypto.h>
11*e7be843bSPierre Pronchery #include <internal/nelem.h>
12*e7be843bSPierre Pronchery #include "testutil.h"
13*e7be843bSPierre Pronchery 
14*e7be843bSPierre Pronchery struct strtoul_test_entry {
15*e7be843bSPierre Pronchery     char *input; /* the input string */
16*e7be843bSPierre Pronchery     int base; /* the base we are converting in */
17*e7be843bSPierre Pronchery     unsigned long expect_val; /* the expected value we should get */
18*e7be843bSPierre Pronchery     int expect_err;  /* the expected error we expect to receive */
19*e7be843bSPierre Pronchery     size_t expect_endptr_offset; /* the expected endptr offset, +1 for NULL */
20*e7be843bSPierre Pronchery };
21*e7be843bSPierre Pronchery 
22*e7be843bSPierre Pronchery static struct strtoul_test_entry strtoul_tests[] = {
23*e7be843bSPierre Pronchery     /* pass on conv "0" to 0 */
24*e7be843bSPierre Pronchery     {
25*e7be843bSPierre Pronchery         "0", 0, 0, 1, 1
26*e7be843bSPierre Pronchery     },
27*e7be843bSPierre Pronchery     /* pass on conv "12345" to 12345 */
28*e7be843bSPierre Pronchery     {
29*e7be843bSPierre Pronchery         "12345", 0, 12345, 1, 5
30*e7be843bSPierre Pronchery     },
31*e7be843bSPierre Pronchery     /* pass on conv "0x12345" to 0x12345, base 16 */
32*e7be843bSPierre Pronchery     {
33*e7be843bSPierre Pronchery         "0x12345", 0, 0x12345, 1, 7
34*e7be843bSPierre Pronchery     },
35*e7be843bSPierre Pronchery     /* pass on base 10 translation, endptr points to 'x' */
36*e7be843bSPierre Pronchery     {
37*e7be843bSPierre Pronchery         "0x12345", 10, 0, 1, 1
38*e7be843bSPierre Pronchery     },
39*e7be843bSPierre Pronchery #if ULONG_MAX == 4294967295
40*e7be843bSPierre Pronchery     /* pass on ULONG_MAX translation */
41*e7be843bSPierre Pronchery     {
42*e7be843bSPierre Pronchery         "4294967295", 0, ULONG_MAX, 1, 10
43*e7be843bSPierre Pronchery     },
44*e7be843bSPierre Pronchery #else
45*e7be843bSPierre Pronchery     {
46*e7be843bSPierre Pronchery         "18446744073709551615", 0, ULONG_MAX, 1, 20
47*e7be843bSPierre Pronchery     },
48*e7be843bSPierre Pronchery #endif
49*e7be843bSPierre Pronchery 
50*e7be843bSPierre Pronchery     /* fail on negative input */
51*e7be843bSPierre Pronchery     {
52*e7be843bSPierre Pronchery         "-1", 0, 0, 0, 0
53*e7be843bSPierre Pronchery     },
54*e7be843bSPierre Pronchery     /* fail on non-numerical input */
55*e7be843bSPierre Pronchery     {
56*e7be843bSPierre Pronchery         "abcd", 0, 0, 0, 0
57*e7be843bSPierre Pronchery     },
58*e7be843bSPierre Pronchery     /* pass on decimal input */
59*e7be843bSPierre Pronchery     {
60*e7be843bSPierre Pronchery         "1.0", 0, 1, 1, 1
61*e7be843bSPierre Pronchery     },
62*e7be843bSPierre Pronchery     /* Fail on decimal input without leading number */
63*e7be843bSPierre Pronchery     {
64*e7be843bSPierre Pronchery         ".1", 0, 0, 0, 0
65*e7be843bSPierre Pronchery     }
66*e7be843bSPierre Pronchery };
67*e7be843bSPierre Pronchery 
test_strtoul(int idx)68*e7be843bSPierre Pronchery static int test_strtoul(int idx)
69*e7be843bSPierre Pronchery {
70*e7be843bSPierre Pronchery     unsigned long val;
71*e7be843bSPierre Pronchery     char *endptr = NULL;
72*e7be843bSPierre Pronchery     int err;
73*e7be843bSPierre Pronchery     struct strtoul_test_entry *test = &strtoul_tests[idx];
74*e7be843bSPierre Pronchery 
75*e7be843bSPierre Pronchery     /*
76*e7be843bSPierre Pronchery      * For each test, convert the string to an unsigned long
77*e7be843bSPierre Pronchery      */
78*e7be843bSPierre Pronchery     err = OPENSSL_strtoul(test->input, &endptr, test->base, &val);
79*e7be843bSPierre Pronchery 
80*e7be843bSPierre Pronchery     /*
81*e7be843bSPierre Pronchery      * Check to ensure the error returned is expected
82*e7be843bSPierre Pronchery      */
83*e7be843bSPierre Pronchery     if (!TEST_int_eq(err, test->expect_err))
84*e7be843bSPierre Pronchery         return 0;
85*e7be843bSPierre Pronchery     /*
86*e7be843bSPierre Pronchery      * Confirm that the endptr points to where we expect
87*e7be843bSPierre Pronchery      */
88*e7be843bSPierre Pronchery     if (!TEST_ptr_eq(endptr, &test->input[test->expect_endptr_offset]))
89*e7be843bSPierre Pronchery         return 0;
90*e7be843bSPierre Pronchery     /*
91*e7be843bSPierre Pronchery      * And check that we received the proper translated value
92*e7be843bSPierre Pronchery      * Note, we only check the value if the conversion passed
93*e7be843bSPierre Pronchery      */
94*e7be843bSPierre Pronchery     if (test->expect_err == 1) {
95*e7be843bSPierre Pronchery         if (!TEST_ulong_eq(val, test->expect_val))
96*e7be843bSPierre Pronchery             return 0;
97*e7be843bSPierre Pronchery     }
98*e7be843bSPierre Pronchery     return 1;
99*e7be843bSPierre Pronchery 
100*e7be843bSPierre Pronchery }
101*e7be843bSPierre Pronchery 
setup_tests(void)102*e7be843bSPierre Pronchery int setup_tests(void)
103*e7be843bSPierre Pronchery {
104*e7be843bSPierre Pronchery     ADD_ALL_TESTS(test_strtoul, OSSL_NELEM(strtoul_tests));
105*e7be843bSPierre Pronchery     return 1;
106*e7be843bSPierre Pronchery }
107