diff --git a/regcomp.c b/regcomp.c index 6e35d95d2ac6..34c0516d6cd5 100644 --- a/regcomp.c +++ b/regcomp.c @@ -14461,7 +14461,7 @@ S_parse_uniprop_string(pTHX_ * compile perl to know about them) */ bool is_nv_type = FALSE; - unsigned int i, j = 0; + unsigned int i = 0, i_zero = 0, j = 0; int equals_pos = -1; /* Where the '=' is found, or negative if none */ int slash_pos = -1; /* Where the '/' is found, or negative if none */ int table_index = 0; /* The entry number for this property in the table @@ -14593,9 +14593,13 @@ S_parse_uniprop_string(pTHX_ * all of them are considered to be for that package. For the purposes of * parsing the rest of the property, strip it off */ if (non_pkg_begin == STRLENs("utf8::") && memBEGINPs(name, name_len, "utf8::")) { - lookup_name += STRLENs("utf8::"); - j -= STRLENs("utf8::"); - equals_pos -= STRLENs("utf8::"); + lookup_name += STRLENs("utf8::"); + j -= STRLENs("utf8::"); + equals_pos -= STRLENs("utf8::"); + i_zero = STRLENs("utf8::"); /* When resetting 'i' to reparse + from the beginning, it has to be + set past what we're stripping + off */ stripped_utf8_pkg = TRUE; } @@ -15009,7 +15013,8 @@ S_parse_uniprop_string(pTHX_ /* We set the inputs back to 0 and the code below will reparse, * using strict */ - i = j = 0; + i = i_zero; + j = 0; } } @@ -15030,7 +15035,7 @@ S_parse_uniprop_string(pTHX_ * separates two digits */ if (cur == '_') { if ( stricter - && ( i == 0 || (int) i == equals_pos || i == name_len- 1 + && ( i == i_zero || (int) i == equals_pos || i == name_len- 1 || ! isDIGIT_A(name[i-1]) || ! isDIGIT_A(name[i+1]))) { lookup_name[j++] = '_'; diff --git a/t/re/pat_advanced.t b/t/re/pat_advanced.t index c237c5879d18..4d62f62c9014 100644 --- a/t/re/pat_advanced.t +++ b/t/re/pat_advanced.t @@ -2699,6 +2699,14 @@ EOF_DEBUG_OUT "Related to Github Issue #19350, forward \\g{x} pattern segv under use re Debug => 'PARSE'"); } + { # perl-security#140, read/write past buffer end + fresh_perl_like('qr/\p{utf8::perl x}/', + qr/Illegal user-defined property name "utf8::perl x" in regex/, + {}, "perl-security#140"); + fresh_perl_is('qr/\p{utf8::_perl_surrogate}/', "", + {}, "perl-security#140"); + } + { # GH 20009 my $x = "awesome quotes"; utf8::upgrade($x);