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 <tobias@stoeckmann.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
This commit is contained in:
committed by
Serge Hallyn
parent
1a383194ff
commit
89e5a32966
@@ -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 \
|
||||
|
||||
13
lib/adds.c
Normal file
13
lib/adds.c
Normal file
@@ -0,0 +1,13 @@
|
||||
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#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);
|
||||
72
lib/adds.h
Normal file
72
lib/adds.h
Normal file
@@ -0,0 +1,72 @@
|
||||
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ADDS_H_
|
||||
#define SHADOW_INCLUDE_LIB_ADDS_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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
|
||||
Reference in New Issue
Block a user