Description
In the C programming language, atoi()
and atol()
don't check errors. If the input string is invalid, their behavior is undefined with no guaranteed return value (a particular implementation of libc may have defined return value, but it's not guaranteed by the C standard). strtol()
is better, but its error checking is complicated, one need to test three conditions, errno != 0
for overflows and invalid integers, nptr != endptr
for strings without digits, and *endptr != '\0'
for strings mixed with letters and numbers, it is easily misused. Also, it ignores the leading space in the string that can hide bugs. *BSD's strtonum()
is the best function for this job, but it's not portable.
To solve this problem, the NUT project already has a builtin library common/str.c
that provides easy-to-use and portable string conversion functions with robust error handling, such as str_to_short()
, str_to_ushort()
, str_to_long()
(they are implemented by calling strtol()
with correct error checking), "strict" versions that report errors if there are leading spaces also exist. Unfortunately, these good string functions is used by almost nobody. They are only used by 3 drivers, and it's not used in server code at all.
$ grep -R str_to *.c *.h | uniq
nutdrv_siemens_sitop.c: if (str_to_uint(maxPollsString, &parsed, 10) == 1) {
snmp-ups.c: if ( !str_to_long(val ? val : su_info_p->dfl, &value, 10) ) {
snmp-ups.c: if ( !str_to_long(val, &value, 10) ) {
$ grep -R str_to *.c *.h | wc -l
0
All atoi()
, atol()
, strtol()
in the existing code should be converted to use str_to_*()
instead, if it's not practical to convert existing code, at least they should be disallowed in new code. Ideally, the "strict" version of the functions should be preferred.
The new-drivers.txt
document should inform the developers about the existence of these functions.