refactor: add overflow-safe CeilDiv helper

Introduce `CeilDiv()` for integral ceiling division without the typical `(dividend + divisor - 1) / divisor` overflow, asserting a non-zero divisor.

Replace existing ceiling-division expressions with `CeilDiv()` to centralize the preconditions.

Add unit tests covering return type deduction, max-value behavior, and divisor checks.
This commit is contained in:
Lőrinc
2026-01-28 14:45:30 +01:00
parent 4a05825a3f
commit 02d047fd5b
15 changed files with 85 additions and 19 deletions

View File

@@ -7,6 +7,7 @@
#include <crypto/hex_base.h>
#include <span.h>
#include <util/overflow.h>
#include <array>
#include <cassert>
@@ -100,7 +101,7 @@ std::string EncodeBase64(std::span<const unsigned char> input)
static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string str;
str.reserve(((input.size() + 2) / 3) * 4);
str.reserve(CeilDiv(input.size(), 3u) * 4);
ConvertBits<8, 6, true>([&](int v) { str += pbase64[v]; }, input.begin(), input.end());
while (str.size() % 4) str += '=';
return str;
@@ -146,7 +147,7 @@ std::string EncodeBase32(std::span<const unsigned char> input, bool pad)
static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
std::string str;
str.reserve(((input.size() + 4) / 5) * 8);
str.reserve(CeilDiv(input.size(), 5u) * 8);
ConvertBits<8, 5, true>([&](int v) { str += pbase32[v]; }, input.begin(), input.end());
if (pad) {
while (str.size() % 8) {