From ae966df90745f665aaf17b674f7c740e3514bd53 Mon Sep 17 00:00:00 2001 From: TSUYUSATO Kitsune Date: Mon, 28 Jul 2025 17:50:36 +0900 Subject: Port a Oniguruma patch: Integer overflow in onig_search_gpos() https://github.com/kkos/oniguruma/commit/778a43dd56925ed58bbe26e3a7bb8202d72c3f3f It differs from the Oniguruma patch in that it dosen't use `onigenc_get_prev_char_head()` because this function's signature has been changed by Oniguruma and the change is not ported in Onigmo for now. This patch respects the current Onigmo implementation. Co-Authored-By: K.Kosako --- regexec.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/regexec.c b/regexec.c index b8178637eb..2b1453b905 100644 --- a/regexec.c +++ b/regexec.c @@ -5161,15 +5161,19 @@ onig_search_gpos(regex_t* reg, const UChar* str, const UChar* end, if (reg->optimize != ONIG_OPTIMIZE_NONE) { UChar *sch_range, *low, *high, *low_prev; - sch_range = (UChar* )range; if (reg->dmax != 0) { if (reg->dmax == ONIG_INFINITE_DISTANCE) sch_range = (UChar* )end; else { - sch_range += reg->dmax; - if (sch_range > end) sch_range = (UChar* )end; + if ((end - range) < reg->dmax) + sch_range = (UChar* )end; + else { + sch_range = (UChar* )range + reg->dmax; + } } } + else + sch_range = (UChar* )range; if ((end - start) < reg->threshold_len) goto mismatch; @@ -5241,8 +5245,11 @@ onig_search_gpos(regex_t* reg, const UChar* str, const UChar* end, if (reg->dmax != ONIG_INFINITE_DISTANCE && (end - range) >= reg->threshold_len) { do { - sch_start = s + reg->dmax; - if (sch_start > end) sch_start = (UChar* )end; + if (end - s > reg->dmax) + sch_start = s + reg->dmax; + else + sch_start = (UChar* )end; + if (backward_search_range(reg, str, end, sch_start, min_range, adjrange, &low, &high) <= 0) goto mismatch; @@ -5261,18 +5268,19 @@ onig_search_gpos(regex_t* reg, const UChar* str, const UChar* end, else { /* check only. */ if ((end - range) < reg->threshold_len) goto mismatch; - sch_start = s; if (reg->dmax != 0) { if (reg->dmax == ONIG_INFINITE_DISTANCE) sch_start = (UChar* )end; else { - sch_start += reg->dmax; - if (sch_start > end) sch_start = (UChar* )end; - else + if (end - s > reg->dmax) { + sch_start = s + reg->dmax; sch_start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, start, sch_start, end); + } else + sch_start = (UChar* )end; } } + if (backward_search_range(reg, str, end, sch_start, min_range, adjrange, &low, &high) <= 0) goto mismatch; } -- cgit v1.2.3