diff --git a/lib/Makefile.am b/lib/Makefile.am index 308099fc..0254977b 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -30,6 +30,8 @@ libshadow_la_SOURCES = \ agetpass.h \ alloc.c \ alloc.h \ + atoi/strtou_noneg.c \ + atoi/strtou_noneg.h \ attr.h \ audit_help.c \ basename.c \ diff --git a/lib/atoi/strtou_noneg.c b/lib/atoi/strtou_noneg.c new file mode 100644 index 00000000..14602a9b --- /dev/null +++ b/lib/atoi/strtou_noneg.c @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2023, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#include + +#include "atoi/strtou_noneg.h" + + +extern inline unsigned long strtoul_noneg(const char *s, + char **restrict endp, int base); +extern inline unsigned long long strtoull_noneg(const char *s, + char **restrict endp, int base); diff --git a/lib/atoi/strtou_noneg.h b/lib/atoi/strtou_noneg.h new file mode 100644 index 00000000..5670dc9b --- /dev/null +++ b/lib/atoi/strtou_noneg.h @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2023, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOU_NONEG_H_ +#define SHADOW_INCLUDE_LIB_ATOI_STRTOU_NONEG_H_ + + +#include + +#include +#include + +#include "attr.h" + + +ATTR_STRING(1) ATTR_ACCESS(write_only, 2) +inline unsigned long strtoul_noneg(const char *s, + char **restrict endp, int base); +ATTR_STRING(1) ATTR_ACCESS(write_only, 2) +inline unsigned long long strtoull_noneg(const char *s, + char **restrict endp, int base); + + +inline unsigned long +strtoul_noneg(const char *s, char **restrict endp, int base) +{ + if (strtol(s, endp, base) < 0) { + errno = ERANGE; + return 0; + } + return strtoul(s, endp, base); +} + + +inline unsigned long long +strtoull_noneg(const char *s, char **restrict endp, int base) +{ + if (strtol(s, endp, base) < 0) { + errno = ERANGE; + return 0; + } + return strtoull(s, endp, base); +} + + +#endif // include guard