use strict;
use warnings;
+no warnings 'experimental::vlb';
use 5.010;
sub run_tests;
skip_all('no re module') unless defined &DynaLoader::boot_DynaLoader;
skip_all_without_unicode_tables();
-plan tests => 855; # Update this when adding/deleting tests.
+plan tests => 965; # Update this when adding/deleting tests.
run_tests() unless caller;
# Tests start here.
#
sub run_tests {
-
my $sharp_s = uni_to_native("\xdf");
{
ok $@ =~ /^\QLookbehind longer than 255 not/, "Lookbehind limit";
}
- {
- # Long Monsters
+ SKIP:
+ { # Long Monsters
+
+ skip('limited memory', 20) if $ENV{'PERL_SKIP_BIG_MEM_TESTS'};
+
for my $l (125, 140, 250, 270, 300000, 30) { # Ordered to free memory
my $a = 'a' x $l;
my $message = "Long monster, length = $l";
}
}
- {
- # 20000 nodes, each taking 3 words per string, and 1 per branch
+ SKIP:
+ { # 20000 nodes, each taking 3 words per string, and 1 per branch
+
+ skip('limited memory', 20) if $ENV{'PERL_SKIP_BIG_MEM_TESTS'};
+
my $long_constant_len = join '|', 12120 .. 32645;
my $long_var_len = join '|', 8120 .. 28645;
my %ans = ( 'ax13876y25677lbc' => 1,
is($#+, 2, $message);
is($#-, 1, $message);
- # Check that values don’t stick
+ # Check that values don't stick
" "=~/()()()(.)(..)/;
my($m,$p,$q) = (\$-[5], \$+[5], \${^CAPTURE}[4]);
() = "$$_" for $m, $p, $q; # FETCH (or eqv.)
ok("\x{017F}\x{017F}" =~ qr/^[$sharp_s]?$/i, "[] to EXACTish optimization");
}
+ { # Test that it avoids spllitting a multi-char fold across nodes.
+ # These all fold to things that are like 'ss', which, if split across
+ # nodes could fail to match a single character that folds to the
+ # combination.
+ my $utf8_locale = find_utf8_ctype_locale();
+ for my $char('F', $sharp_s, "\x{FB00}") {
+ my $length = 260; # Long enough to overflow an EXACTFish regnode
+ my $p = $char x $length;
+ my $s = ($char eq $sharp_s) ? 'ss' : 'ff';
+ $s = $s x $length;
+ for my $charset (qw(u d l aa)) {
+ for my $utf8 (0..1) {
+ SKIP:
+ for my $locale ('C', $utf8_locale) {
+ skip "test skipped for non-C locales", 2
+ if $charset ne 'l'
+ && (! defined $locale || $locale ne 'C');
+ if ($charset eq 'l') {
+ if (! defined $locale) {
+ skip "No UTF-8 locale", 2;
+ }
+
+ use POSIX;
+ POSIX::setlocale(&LC_CTYPE, $locale);
+ }
+
+ my $pat = $p;
+ utf8::upgrade($pat) if $utf8;
+ my $should_pass =
+ ( $charset eq 'u'
+ || ($charset eq 'd' && $utf8)
+ || ($charset eq 'd' && ( $char =~ /[[:ascii:]]/
+ || ord $char > 255))
+ || ($charset eq 'aa' && $char =~ /[[:ascii:]]/)
+ || ($charset eq 'l' && $locale ne 'C')
+ || ($charset eq 'l' && $char =~ /[[:ascii:]]/)
+ );
+ my $name = "(?i$charset), utf8=$utf8, locale=$locale,"
+ . " char=" . sprintf "%x", ord $char;
+ no warnings 'locale';
+ is (eval " '$s' =~ qr/(?i$charset)$pat/;",
+ $should_pass, $name);
+ fail "$name: $@" if $@;
+ is (eval " 'a$s' =~ qr/(?i$charset)a$pat/;",
+ $should_pass, "extra a, $name");
+ fail "$name: $@" if $@;
+ }
+ }
+ }
+ }
+ }
+
+ {
+ my $s = ("0123456789" x 26214) x 2; # Should fill 2 LEXACTS, plus
+ # small change
+ my $pattern_prefix = "use utf8; use re qw(Debug COMPILE)";
+ my $pattern = "$pattern_prefix; qr/$s/;";
+ my $result = fresh_perl($pattern);
+ if ($? != 0) { # Re-run so as to display STDERR.
+ fail($pattern);
+ fresh_perl($pattern, { stderr => 0, verbose => 1 });
+ }
+ like($result, qr/Final program[^X]*\bLEXACT\b[^X]*\bLEXACT\b[^X]*\bEXACT\b[^X]*\bEND\b/s,
+ "Check that LEXACT nodes are generated");
+ like($s, qr/$s/, "Check that LEXACT nodes match");
+ like("a$s", qr/a$s/, "Previous test preceded by an 'a'");
+ substr($s, 260000, 1) = "\x{100}";
+ $pattern = "$pattern_prefix; qr/$s/;";
+ $result = fresh_perl($pattern, { 'wide_chars' => 1 } );
+ if ($? != 0) { # Re-run so as to display STDERR.
+ fail($pattern);
+ fresh_perl($pattern, { stderr => 0, verbose => 1 });
+ }
+ like($result, qr/Final program[^X]*\bLEXACT_ONLY8\b[^X]*\bLEXACT\b[^X]*\bEXACT\b[^X]*\bEND\b/s,
+ "Check that an LEXACT_ONLY node is generated with a \\x{100}");
+ like($s, qr/$s/, "Check that LEXACT_ONLY8 nodes match");
+ }
+
{
for my $char (":", uni_to_native("\x{f7}"), "\x{2010}") {
my $utf8_char = $char;
fresh_perl_is('m m0*0+\Rm', "",{},"Undefined behavior in address sanitizer");
}
{ # [perl #133642]
- fresh_perl_is('m/((?<=(0?)))/', "Variable length lookbehind not implemented in regex m/((?<=(0?)))/ at - line 1.",{},"Was getting 'Double free'");
+ fresh_perl_is('no warnings "experimental::vlb";
+ m/((?<=(0?)))/', "",{},"Was getting 'Double free'");
}
{ # [perl #133782]
# this would panic on DEBUGGING builds
{ # [perl #133871], ASAN/valgrind out-of-bounds access
fresh_perl_like('qr/(?|(())|())|//', qr/syntax error/, {}, "[perl #133871]");
}
+ { # [perl #133921], segfault
+ fresh_perl_is('qr\ 40||ß+p00000F00000ù\Q00000ÿ00000x00000x0c0e0\Qx0\Qx0\x{0c!}\;\;î0\x\0ÿÿÿþ\0\0\0ù\Q`\Qx`\0\ 1{0c!}\ 1e;\0\0\0ù\ò`\Qm`\x{0c!}\;\;îçÿ \0\7fç\0\0\0!\0F\ 5\0\0/;îçÿù\Q\0\ 1\0\0x\10ÿÿÿÿ\0\0\0ù\0\0\0\7f`x{0c!}\ 1e;\0\0\0ù\Q`\Qx`\x{c!}\;\;îç!}\;îçÿù\Q\87 \x\0ÿÿÿÿ\0\0>=\Qx`\Qx`\0\0ù\ò`\Qx`\x{0c!};\;îçÿ \0F\ 5\0n0t0\0c \0\80\ 1d;t \0\0\0ù \0\7fç\80\0\0!00000000000000000000000m/00000000000000000000\ e00000000000m/\10\10\10\10\x{){} \10\10\10\10)|\10\10\ 4i', "", {}, "[perl #133921]");
+ fresh_perl_is('\ 4|ß+W0ü0r0\Qx0\Qx0x0c0G00000000000000000O000000000x0x0x0c!}\;îçÿù\Q0 \x\0ÿÿÿÿ\0\0\0ù\Q`\Qx`\0\ 1{0d ;\0\0\0ù\ò`\Qm`\x{0c!}\;\;îçÿ \0\7fç\0\0\0!\0F\ 5\0\0/;îçÿù\Q\0\ 1\0\0x\10ÿÿÿÿ\0\0\0ù\0\0\0\7f`x{0c!}\ 1;\0\0\0ù\Q`\Qq`\x{c!}\;\;îç!}\;îçÿù\Q\87 \x\0ÿÿÿÿ\0\0>=\Qx`\Qx`\0\0ù\ò`\Qx`\x{0c!};\;îçÿ \00000000F\ 5\0m0t0\0c \0\80\ 1d;t \0\0\0ù \0\7fç\80\0\0!00000000000000000000000m/00000000000000000000\ e00000000000m/\10\10\10\10\x{){} \10\10\10\10)|\10\10\ 4\ 4i', "", {}, "[perl #133921]");
+
+fresh_perl_is('s\ 4|ß+W0ü0f0\Qx0\Qx0x0c0G0xgive0000000000000O0h\8d000x0 \xòÿÿÿ\0\0ù\Q`\Q
+
+\1a
+
+
+ ç
+
+
+
+
+
+
+
+
+
+
+
+
+\ 5
+
+
+x{0c!}\;\;çÿ \0\7fq0/i0/!\0F\ 5\0\0/;îçÿù\Q\0\ 1\0\0x\10ÿÿÿÿ\0\0\0ù\0\0\0\7f`x{0c!}\ 1e;\0\0\0ù\Q`\Qx`\x{0c!}\;ÿÿÿÿ!}\;îçÿù\Q\87\ 1\x\0ÿÿÿÿ\0\0>=\Qx`\Qx`\0\0ù\ò`ÿ\0\0>=\Qx`\Qx`\0\0ù\ò`\Qx`\x{0c!};\;îçÿ \0u00000F\ 5\0000t0\0p \0\80\ 1d? \0\0\0ù \0\7fç\80\0\0!00000000000000000000000m/00000000000000000000\ e00000000000m/0\0\10\10\10\\0\0\ 1\0} \10\10\10\10)|\10\10\ 4\ 4i', "", {}, "[perl #133921]");
+
+ fresh_perl_is('\ 4a aú\0\0úv sWtrt\10\0\ó||ß+W\ eü\16ef\0ù\Qx`\Qx`\x{1c!gGnuc given1111111111111O1111each\8d111\jx` \x\0òÿÿÿ\0\0\0ù\Qx`\Q
+
+
+
+
+
+ ç
+
+
+
+
+
+
+
+
+
+
+
+
+\ 5
+
+
+x{1c!}\;\;îçÿp \0\7fqr/elsif/!\0eF\ 5\0\0/;îçÿù\Q\0\ 1\0\0x\10ÿÿÿÿ\0\0\0ùHQx\0\0\0\7f`Lx{1c!}\ 1e;\0\0\0ù\Qx`\Qx`\x{1c!}\;ÿÿÿÿc!}\;îçÿù\Qx\87\ 1\x\0ÿÿÿÿ\0\0>=\Qx`\Qx`\0\0ù\òx`ÿ\0\0>=\Qx`\Qx`\0\0ù\òx`\Qx`\x{1c!}8;\;îçÿp \0unshifteF\ 5\0normat0\0cmp \0\80\ 1d?not \0\0\0ùp \0\7fç\80\0\0!0000000000000000000000000m/000000000000000000000\ e00000000000m/0R\0\10\10\10\\0\0\ 1\0} \10\10\10\10)|\10\10\ 4\10\10\10\10\10\ 1\aï||K??\8fp\80¿ÿÿfúd{\\ e{\ 4gri\ 4\ 4{\x{1x/}\0 ð¹NuntiÀh', "", {}, "[perl #133921]");
+
+ fresh_perl_is('s\ 4|ß+W0ü0f0\Qx0\Qx0x0c0g0c 000n0000000000000O0h\8d000x0 \xòÿÿÿ\0\0ù\Q`\Q
+
+
+
+
+
+ ç
+
+
+
+
+
+
+
+
+
+
+
+
+\ 5
+
+
+x{0c!}\;\;îçÿ \0\7f/0f/!\0F\ 5\0\0/;îçÿù\Q\0\ 1\0\0x\10ÿÿÿÿ\0\0\0ù\0\0\0\7f`x{0c!}\ 1;\0\0\0ù\Q`\Qx`\x{0c!}\;ÿÿÿÿ!}\;îçÿù\Q\87\ 1\x\0ÿÿÿÿ\0\0>=\Qx`\Qx`\0\0ù\ò`ÿ\0\0>=\Qx`\Qx`\0\0ù\ò`\Qx`\x{0c!};\;îçÿ \0000t0F\ 5\0000t0\0p \0\80\ 1d?n \0\0\0ù \0\7fç\80\0\0!00000000000000000000000m/00000000000000000000\ e00000000000m/\0\10\10\10\\0\0\ 1\0} \10\10\10\10)|\10\10\ 4\ 4i', "", {}, "[perl #133933]");
+ }
+
+ { # perl #133998]
+ fresh_perl_is('print "\x{110000}" =~ qr/(?l)|[^\S\pC\s]/', 1, {},
+ '/[\S\s]/l works');
+ }
+
+ { # perl #133995]
+ use utf8;
+ fresh_perl_is('"έδωσαν ελληνικήვე" =~ m/[^0](?=0)0?/', "",
+ {wide_chars => 1},
+ '[^0] doesnt crash on UTF-8 target string');
+ }
+
+ { # [perl #133992] This is a tokenizer bug of parsing a pattern
+ fresh_perl_is(q:$z = do {
+ use utf8;
+ "q!Ñ\82еÑ\81Ñ\82! =~ m'"
+ };
+ $z .= 'è(?#\84';
+ $z .= "'";
+ eval $z;:, "", {}, 'foo');
+ }
+
+ { # [perl #134325]
+ my $quote="\\Q";
+ my $back="\\\\";
+ my $ff="\xff";
+ my $s = sprintf "/\\1|(|%s)%s%s /i",
+ $quote x 8 . $back x 69,
+ $quote x 5 . $back x 4,
+ $ff x 48;
+ like(runperl(prog => "$s", stderr => 1), qr/Unmatched \(/);
+ }
} # End of sub run_tests