1 /* Copyright (c) 2003, Roger Dingledine
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
8 * \brief Convert strings into the integers they encode, with bounds checking.
11 #include "lib/string/parse_int.h"
12 #include "lib/cc/compat_compiler.h"
18 /* Helper: common code to check whether the result of a strtol or strtoul or
19 * strtoll is correct. */
20 #define CHECK_STRTOX_RESULT() \
22 /* Did an overflow occur? */ \
23 if (errno == ERANGE) \
25 /* Was at least one character converted? */ \
28 /* Were there unexpected unconverted characters? */ \
29 if (!next && *endptr) \
31 /* Illogical (max, min) inputs? */ \
34 /* Is r within limits? */ \
35 if (r < min || r > max) \
38 if (next) *next = endptr; \
42 if (next) *next = endptr; \
46 /** Extract a long from the start of <b>s</b>, in the given numeric
47 * <b>base</b>. If <b>base</b> is 0, <b>s</b> is parsed as a decimal,
48 * octal, or hex number in the syntax of a C integer literal. If
49 * there is unconverted data and <b>next</b> is provided, set
50 * *<b>next</b> to the first unconverted character. An error has
51 * occurred if no characters are converted; or if there are
52 * unconverted characters and <b>next</b> is NULL; or if the parsed
53 * value is not between <b>min</b> and <b>max</b>. When no error
54 * occurs, return the parsed value and set *<b>ok</b> (if provided) to
55 * 1. When an error occurs, return 0 and set *<b>ok</b> (if provided)
59 tor_parse_long(const char *s
, int base
, long min
, long max
,
72 r
= strtol(s
, &endptr
, base
);
73 CHECK_STRTOX_RESULT();
76 /** As tor_parse_long(), but return an unsigned long. */
78 tor_parse_ulong(const char *s
, int base
, unsigned long min
,
79 unsigned long max
, int *ok
, char **next
)
91 r
= strtoul(s
, &endptr
, base
);
92 CHECK_STRTOX_RESULT();
95 /** As tor_parse_long(), but return a double. */
97 tor_parse_double(const char *s
, double min
, double max
, int *ok
, char **next
)
103 r
= strtod(s
, &endptr
);
104 CHECK_STRTOX_RESULT();
107 /** As tor_parse_long, but return a uint64_t. Only base 10 is guaranteed to
110 tor_parse_uint64(const char *s
, int base
, uint64_t min
,
111 uint64_t max
, int *ok
, char **next
)
124 r
= (uint64_t)strtoull(s
, &endptr
, base
);
125 #elif defined(_WIN32)
126 r
= (uint64_t)_strtoui64(s
, &endptr
, base
);
127 #elif SIZEOF_LONG == 8
128 r
= (uint64_t)strtoul(s
, &endptr
, base
);
130 #error "I don't know how to parse 64-bit numbers."
131 #endif /* defined(HAVE_STRTOULL) || ... */
133 CHECK_STRTOX_RESULT();