diff options
| author | TSUYUSATO Kitsune <make.just.on@gmail.com> | 2025-07-28 17:50:36 +0900 |
|---|---|---|
| committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2025-08-01 10:16:55 +0900 |
| commit | ae966df90745f665aaf17b674f7c740e3514bd53 (patch) | |
| tree | 594c5d56a212849029413b3e477cc0380ccd2a6e | |
| parent | f16262e54453d6dc483db3deda5c2674d8c1d52a (diff) | |
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 <kkos@users.noreply.github.com>
| -rw-r--r-- | regexec.c | 26 |
1 files changed, 17 insertions, 9 deletions
@@ -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; } |
