Fix memory leak in String#start_with? when regexp times out

[Bug #20653]

This commit refactors how Onigmo handles timeout. Instead of raising a
timeout error, onig_search will return a ONIGERR_TIMEOUT which the
caller can free memory, and then raise a timeout error.

This fixes a memory leak in String#start_with when the regexp times out.
For example:

    regex = Regexp.new("^#{"(a*)" * 10_000}x$", timeout: 0.000001)
    str = "a" * 1000000 + "x"

    10.times do
      100.times do
        str.start_with?(regex)
      rescue
      end

      puts `ps -o rss= -p #{$$}`
    end

Before:

    33216
    51936
    71152
    81728
    97152
    103248
    120384
    133392
    133520
    133616

After:

    14912
    15376
    15824
    15824
    16128
    16128
    16144
    16144
    16160
    16160
This commit is contained in:
Peter Zhu 2024-07-25 15:28:25 -04:00
parent 67e1ea0028
commit 7464514ca5
Notes: git 2024-07-26 12:42:57 +00:00
4 changed files with 32 additions and 54 deletions

View file

@ -5575,8 +5575,7 @@ onig_search_gpos(regex_t* reg, const UChar* str, const UChar* end,
timeout:
MATCH_ARG_FREE(msa);
onig_region_free(region, false);
HANDLE_REG_TIMEOUT_IN_MATCH_AT;
return ONIGERR_TIMEOUT;
}
extern OnigPosition