mirror of
https://github.com/isc-projects/bind9.git
synced 2026-04-21 06:09:13 -04:00
The `ISC_OVERFLOW_XXX()` macros are usually wrappers around `__builtin_xxx_overflow()`, with alternative implementations for compilers that lack the builtins. Replace the overflow checks in `isc/time.c` with the new macros.
95 lines
3.4 KiB
C
95 lines
3.4 KiB
C
/*
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
*
|
|
* SPDX-License-Identifier: MPL-2.0
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
* information regarding copyright ownership.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <isc/util.h>
|
|
|
|
/*
|
|
* It is awkward to support signed numbers as well, so keep it simple
|
|
* (with a safety check).
|
|
*/
|
|
#define ISC_OVERFLOW_IS_UNSIGNED(a) \
|
|
({ \
|
|
STATIC_ASSERT((typeof(a))-1 > 0, \
|
|
"overflow checks require unsigned types"); \
|
|
(a); \
|
|
})
|
|
|
|
#define ISC_OVERFLOW_UINT_MAX(a) ISC_OVERFLOW_IS_UNSIGNED((typeof(a))-1)
|
|
|
|
#define ISC_OVERFLOW_UINT_MIN(a) ISC_OVERFLOW_IS_UNSIGNED(0)
|
|
|
|
/*
|
|
* Return true on overflow, e.g.
|
|
*
|
|
* bool overflow = ISC_OVERFLOW_MUL(count, sizeof(array[0]), &bytes);
|
|
* INSIST(!overflow);
|
|
*/
|
|
|
|
#if HAVE_BUILTIN_MUL_OVERFLOW
|
|
#define ISC_OVERFLOW_MUL(a, b, cp) __builtin_mul_overflow(a, b, cp)
|
|
#else
|
|
#define ISC_OVERFLOW_MUL(a, b, cp) \
|
|
((ISC_OVERFLOW_UINT_MAX(a) / (b) > (a)) ? (*(cp) = (a) * (b), false) \
|
|
: true)
|
|
#endif
|
|
|
|
#if HAVE_BUILTIN_ADD_OVERFLOW
|
|
#define ISC_OVERFLOW_ADD(a, b, cp) __builtin_add_overflow(a, b, cp)
|
|
#else
|
|
#define ISC_OVERFLOW_ADD(a, b, cp) \
|
|
((ISC_OVERFLOW_UINT_MAX(a) - (b) > (a)) ? (*(cp) = (a) + (b), false) \
|
|
: true)
|
|
#endif
|
|
|
|
#if HAVE_BUILTIN_SUB_OVERFLOW
|
|
#define ISC_OVERFLOW_SUB(a, b, cp) __builtin_sub_overflow(a, b, cp)
|
|
#else
|
|
#define ISC_OVERFLOW_SUB(a, b, cp) \
|
|
((ISC_OVERFLOW_UINT_MIN(a) + (b) < (a)) ? (*(cp) = (a) - (b), false) \
|
|
: true)
|
|
#endif
|
|
|
|
#define ISC_CHECKED_MUL(a, b) \
|
|
({ \
|
|
typeof(a) _c; \
|
|
bool _overflow = ISC_OVERFLOW_MUL(a, b, &_c); \
|
|
INSIST(!_overflow); \
|
|
_c; \
|
|
})
|
|
|
|
#define ISC_CHECKED_ADD(a, b) \
|
|
({ \
|
|
typeof(a) _c; \
|
|
bool _overflow = ISC_OVERFLOW_ADD(a, b, &_c); \
|
|
INSIST(!_overflow); \
|
|
_c; \
|
|
})
|
|
|
|
#define ISC_CHECKED_SUB(a, b) \
|
|
({ \
|
|
typeof(a) _c; \
|
|
bool _overflow = ISC_OVERFLOW_SUB(a, b, cp); \
|
|
INSIST(!_overflow); \
|
|
_c; \
|
|
})
|
|
|
|
#define ISC_CHECKED_MUL_ADD(a, b, c) \
|
|
({ \
|
|
size_t _d; \
|
|
bool _overflow = ISC_OVERFLOW_MUL(a, b, &_d) || \
|
|
ISC_OVERFLOW_ADD(_d, c, &_d); \
|
|
INSIST(!_overflow); \
|
|
_d; \
|
|
})
|