libgrapheme

unicode string library
git clone git://git.suckless.org/libgrapheme
Log | Files | Refs | README | LICENSE

commit 004bdcf210baf1a63772bb7eca452bb0aeba010b
parent ef3e52a7f560f66df8ed1e2487872a1e62c5cedb
Author: Laslo Hunhold <dev@frign.de>
Date:   Sat,  8 Oct 2022 13:13:03 +0200

Prevent undefined behaviour in herodotus_reader_copy()

The first part usually catches harmless cases like "NULL + 0", but the
last part prevents integer overflow in some really crazy cases that
are unlikely but can still happen.

Signed-off-by: Laslo Hunhold <dev@frign.de>

Diffstat:
Msrc/util.c | 20+++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/util.c b/src/util.c @@ -37,23 +37,33 @@ herodotus_reader_copy(const HERODOTUS_READER *src, HERODOTUS_READER *dest) */ dest->type = src->type; if (src->type == HERODOTUS_TYPE_CODEPOINT) { - dest->src = ((const uint_least32_t *)(src->src)) + src->off; + dest->src = (src->src == NULL) ? NULL : + ((const uint_least32_t *)(src->src)) + src->off; } else { /* src->type == HERODOTUS_TYPE_UTF8 */ - dest->src = ((const char *)(src->src)) + src->off; + dest->src = (src->src == NULL) ? NULL : + ((const char *)(src->src)) + src->off; } if (src->srclen == SIZE_MAX) { dest->srclen = SIZE_MAX; } else { - dest->srclen = src->srclen - src->off; + dest->srclen = (src->off < src->srclen) ? src->srclen - src->off : 0; } dest->off = 0; dest->terminated_by_null = src->terminated_by_null; for (i = 0; i < LEN(src->soft_limit); i++) { if (src->soft_limit[i] == SIZE_MAX) { - dest->soft_limit[i] = src->soft_limit[i]; + dest->soft_limit[i] = SIZE_MAX; } else { - dest->soft_limit[i] = src->soft_limit[i] - src->off; + /* + * if we have a degenerate case where the offset is + * higher than the soft-limit, we simply clamp the + * soft-limit to zero given we can't decide here + * to release the limit and, instead, we just + * prevent any more reads + */ + dest->soft_limit[i] = (src->off < src->soft_limit[i]) ? + src->soft_limit[i] - src->off : 0; } } }