From: Alejandro Colomar Date: Wed, 20 Dec 2023 20:43:03 +0000 (+0100) Subject: lib/adds.[ch]: Add addsl() and addsl3() X-Git-Tag: 4.15.0-rc1~58 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=89e5a3296662cdaf930e6ea372afbab812384f10;p=thirdparty%2Fshadow.git lib/adds.[ch]: Add addsl() and addsl3() These functions add 2 or 3 longs, saturating to LONG_{MIN,MAX} instead of overflowing. Cc: Tobias Stoeckmann Signed-off-by: Alejandro Colomar --- diff --git a/lib/Makefile.am b/lib/Makefile.am index cc79326b3..b437bbd39 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -23,6 +23,8 @@ libshadow_la_CFLAGS = $(LIBBSD_CFLAGS) $(LIBCRYPT_PAM) $(LIBSYSTEMD) libshadow_la_SOURCES = \ addgrps.c \ + adds.c \ + adds.h \ age.c \ agetpass.c \ agetpass.h \ diff --git a/lib/adds.c b/lib/adds.c new file mode 100644 index 000000000..d442b7541 --- /dev/null +++ b/lib/adds.c @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2023, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#include + +#include "adds.h" + + +extern inline long addsl(long a, long b); +extern inline long addsl3(long a, long b, long c); + +extern inline int cmpl(const void *p1, const void *p2); diff --git a/lib/adds.h b/lib/adds.h new file mode 100644 index 000000000..dde5b5c72 --- /dev/null +++ b/lib/adds.h @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: 2023, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#ifndef SHADOW_INCLUDE_LIB_ADDS_H_ +#define SHADOW_INCLUDE_LIB_ADDS_H_ + + +#include + +#include +#include +#include + +#include "sizeof.h" + + +inline long addsl(long a, long b); +inline long addsl3(long a, long b, long c); + +inline int cmpl(const void *p1, const void *p2); + + +inline long +addsl(long a, long b) +{ + if (a > 0 && b > LONG_MAX - a) { + errno = EOVERFLOW; + return LONG_MAX; + } + if (a < 0 && b < LONG_MIN - a) { + errno = EOVERFLOW; + return LONG_MIN; + } + return a + b; +} + + +inline long +addsl3(long a, long b, long c) +{ + int e; + long sum; + long n[3] = {a, b, c}; + + e = errno; + qsort(n, NITEMS(n), sizeof(n[0]), cmpl); + + errno = 0; + sum = addsl(n[0], n[2]); + if (errno == EOVERFLOW) + return sum; + errno = e; + return addsl(sum, n[1]); +} + + +inline int +cmpl(const void *p1, const void *p2) +{ + const long *l1 = p1; + const long *l2 = p2; + + if (*l1 < *l2) + return -1; + if (*l1 > *l2) + return +1; + return 0; +} + + +#endif // include guard