Commit | Line | Data |
---|---|---|
b45f050a JF |
1 | #!./perl -w |
2 | ||
3 | BEGIN { | |
4 | chdir 't' if -d 't'; | |
20822f61 | 5 | @INC = '../lib'; |
cb79f740 NC |
6 | require './test.pl'; |
7 | eval 'require Config'; # assume defaults if this fails | |
b45f050a JF |
8 | } |
9 | ||
cb79f740 | 10 | use strict; |
b45f050a JF |
11 | |
12 | ## | |
13 | ## If the markers used are changed (search for "MARKER1" in regcomp.c), | |
cb79f740 | 14 | ## update only these two regexs, and leave the {#} in the @death/@warning |
b45f050a JF |
15 | ## arrays below. The {#} is a meta-marker -- it marks where the marker should |
16 | ## go. | |
cb79f740 NC |
17 | ## |
18 | sub fixup_expect { | |
19 | my $expect = shift; | |
20 | $expect =~ s/{\#}/<-- HERE/; | |
21 | $expect =~ s/{\#}/ <-- HERE /; | |
22 | $expect .= " at "; | |
23 | return $expect; | |
24 | } | |
b45f050a | 25 | |
cb79f740 NC |
26 | my $inf_m1 = ($Config::Config{reg_infty} || 32767) - 1; |
27 | my $inf_p1 = $inf_m1 + 2; | |
b45f050a JF |
28 | |
29 | ## | |
30 | ## Key-value pairs of code/error of code that should have fatal errors. | |
31 | ## | |
32 | my @death = | |
33 | ( | |
7253e4e3 | 34 | '/[[=foo=]]/' => 'POSIX syntax [= =] is reserved for future extensions in regex; marked by {#} in m/[[=foo=]{#}]/', |
b45f050a | 35 | |
58e23c8d | 36 | '/(?<= .*)/' => 'Variable length lookbehind not implemented in regex m/(?<= .*)/', |
b45f050a | 37 | |
58e23c8d | 38 | '/(?<= x{1000})/' => 'Lookbehind longer than 255 not implemented in regex m/(?<= x{1000})/', |
b45f050a | 39 | |
7253e4e3 | 40 | '/(?@)/' => 'Sequence (?@...) not implemented in regex; marked by {#} in m/(?@{#})/', |
b45f050a | 41 | |
9da1dd8f | 42 | '/(?{ 1/' => 'Missing right curly or square bracket', |
b45f050a | 43 | |
7253e4e3 | 44 | '/(?(1x))/' => 'Switch condition not recognized in regex; marked by {#} in m/(?(1x{#}))/', |
b45f050a | 45 | |
7253e4e3 | 46 | '/(?(1)x|y|z)/' => 'Switch (?(condition)... contains too many branches in regex; marked by {#} in m/(?(1)x|y|{#}z)/', |
b45f050a | 47 | |
7253e4e3 | 48 | '/(?(x)y|x)/' => 'Unknown switch condition (?(x) in regex; marked by {#} in m/(?({#}x)y|x)/', |
b45f050a | 49 | |
7253e4e3 | 50 | '/(?/' => 'Sequence (? incomplete in regex; marked by {#} in m/(?{#}/', |
b45f050a | 51 | |
7253e4e3 | 52 | '/(?;x/' => 'Sequence (?;...) not recognized in regex; marked by {#} in m/(?;{#}x/', |
1f4f6bf1 | 53 | '/(?<;x/' => 'Group name must start with a non-digit word character in regex; marked by {#} in m/(?<;{#}x/', |
cc74c5bd TS |
54 | '/(?\ix/' => 'Sequence (?\...) not recognized in regex; marked by {#} in m/(?\{#}ix/', |
55 | '/(?\mx/' => 'Sequence (?\...) not recognized in regex; marked by {#} in m/(?\{#}mx/', | |
56 | '/(?\:x/' => 'Sequence (?\...) not recognized in regex; marked by {#} in m/(?\{#}:x/', | |
57 | '/(?\=x/' => 'Sequence (?\...) not recognized in regex; marked by {#} in m/(?\{#}=x/', | |
58 | '/(?\!x/' => 'Sequence (?\...) not recognized in regex; marked by {#} in m/(?\{#}!x/', | |
59 | '/(?\<=x/' => 'Sequence (?\...) not recognized in regex; marked by {#} in m/(?\{#}<=x/', | |
60 | '/(?\<!x/' => 'Sequence (?\...) not recognized in regex; marked by {#} in m/(?\{#}<!x/', | |
61 | '/(?\>x/' => 'Sequence (?\...) not recognized in regex; marked by {#} in m/(?\{#}>x/', | |
9de15fec KW |
62 | '/(?^-i:foo)/' => 'Sequence (?^-...) not recognized in regex; marked by {#} in m/(?^-{#}i:foo)/', |
63 | '/(?^-i)foo/' => 'Sequence (?^-...) not recognized in regex; marked by {#} in m/(?^-{#}i)foo/', | |
64 | '/(?^d:foo)/' => 'Sequence (?^d...) not recognized in regex; marked by {#} in m/(?^d{#}:foo)/', | |
65 | '/(?^d)foo/' => 'Sequence (?^d...) not recognized in regex; marked by {#} in m/(?^d{#})foo/', | |
0c96c706 KW |
66 | '/(?^lu:foo)/' => 'Regexp modifiers "l" and "u" are mutually exclusive in regex; marked by {#} in m/(?^lu{#}:foo)/', |
67 | '/(?^lu)foo/' => 'Regexp modifiers "l" and "u" are mutually exclusive in regex; marked by {#} in m/(?^lu{#})foo/', | |
68 | '/(?da:foo)/' => 'Regexp modifiers "d" and "a" are mutually exclusive in regex; marked by {#} in m/(?da{#}:foo)/', | |
69 | '/(?lil:foo)/' => 'Regexp modifier "l" may not appear twice in regex; marked by {#} in m/(?lil{#}:foo)/', | |
70 | '/(?aaia:foo)/' => 'Regexp modifier "a" may appear a maximum of twice in regex; marked by {#} in m/(?aaia{#}:foo)/', | |
9442e3b8 | 71 | '/(?i-l:foo)/' => 'Regexp modifier "l" may not appear after the "-" in regex; marked by {#} in m/(?i-l{#}:foo)/', |
cc74c5bd | 72 | |
7253e4e3 | 73 | '/((x)/' => 'Unmatched ( in regex; marked by {#} in m/({#}(x)/', |
b45f050a | 74 | |
7253e4e3 | 75 | "/x{$inf_p1}/" => "Quantifier in {,} bigger than $inf_m1 in regex; marked by {#} in m/x{{#}$inf_p1}/", |
b45f050a | 76 | |
b45f050a | 77 | |
7253e4e3 | 78 | '/x**/' => 'Nested quantifiers in regex; marked by {#} in m/x**{#}/', |
b45f050a | 79 | |
7253e4e3 | 80 | '/x[/' => 'Unmatched [ in regex; marked by {#} in m/x[{#}/', |
b45f050a | 81 | |
7253e4e3 | 82 | '/*/', => 'Quantifier follows nothing in regex; marked by {#} in m/*{#}/', |
b45f050a | 83 | |
7253e4e3 | 84 | '/\p{x/' => 'Missing right brace on \p{} in regex; marked by {#} in m/\p{{#}x/', |
b45f050a | 85 | |
169da838 | 86 | '/[\p{x]/' => 'Missing right brace on \p{} in regex; marked by {#} in m/[\p{{#}x]/', |
b45f050a | 87 | |
7253e4e3 | 88 | '/(x)\2/' => 'Reference to nonexistent group in regex; marked by {#} in m/(x)\2{#}/', |
b45f050a | 89 | |
40809656 | 90 | 'my $m = "\\\"; $m =~ $m', => 'Trailing \ in regex m/\/', |
b45f050a | 91 | |
b8de99ca KW |
92 | '/\x{1/' => 'Missing right brace on \x{} in regex; marked by {#} in m/\x{1{#}/', |
93 | '/\x{X/' => 'Missing right brace on \x{} in regex; marked by {#} in m/\x{{#}X/', | |
b45f050a | 94 | |
169da838 | 95 | '/[\x{X]/' => 'Missing right brace on \x{} in regex; marked by {#} in m/[\x{{#}X]/', |
b8de99ca | 96 | '/[\x{A]/' => 'Missing right brace on \x{} in regex; marked by {#} in m/[\x{A{#}]/', |
b45f050a | 97 | |
b8de99ca KW |
98 | '/\o{1/' => 'Missing right brace on \o{ in regex; marked by {#} in m/\o{1{#}/', |
99 | '/\o{X/' => 'Missing right brace on \o{ in regex; marked by {#} in m/\o{{#}X/', | |
9ffc7554 KW |
100 | |
101 | '/[\o{X]/' => 'Missing right brace on \o{ in regex; marked by {#} in m/[\o{{#}X]/', | |
b8de99ca | 102 | '/[\o{7]/' => 'Missing right brace on \o{ in regex; marked by {#} in m/[\o{7{#}]/', |
9ffc7554 | 103 | |
7253e4e3 | 104 | '/[[:barf:]]/' => 'POSIX class [:barf:] unknown in regex; marked by {#} in m/[[:barf:]{#}]/', |
b45f050a | 105 | |
7253e4e3 | 106 | '/[[=barf=]]/' => 'POSIX syntax [= =] is reserved for future extensions in regex; marked by {#} in m/[[=barf=]{#}]/', |
b45f050a | 107 | |
7253e4e3 | 108 | '/[[.barf.]]/' => 'POSIX syntax [. .] is reserved for future extensions in regex; marked by {#} in m/[[.barf.]{#}]/', |
b42857f3 | 109 | |
7253e4e3 | 110 | '/[z-a]/' => 'Invalid [] range "z-a" in regex; marked by {#} in m/[z-a{#}]/', |
5528c7ba RGS |
111 | |
112 | '/\p/' => 'Empty \p{} in regex; marked by {#} in m/\p{#}/', | |
113 | ||
114 | '/\P{}/' => 'Empty \P{} in regex; marked by {#} in m/\P{{#}}/', | |
3f4fde43 KW |
115 | '/(?[[[:word]]])/' => "Unmatched ':' in POSIX class in regex; marked by {#} in m/(?[[[:word{#}]]])/", |
116 | '/(?[[:word]])/' => "Unmatched ':' in POSIX class in regex; marked by {#} in m/(?[[:word{#}]])/", | |
117 | '/(?[[[:digit: ])/' => "Unmatched '[' in POSIX class in regex; marked by {#} in m/(?[[[:digit:{#} ])/", | |
118 | '/(?[[:digit: ])/' => "Unmatched '[' in POSIX class in regex; marked by {#} in m/(?[[:digit:{#} ])/", | |
119 | '/(?[[[::]]])/' => "POSIX class [::] unknown in regex; marked by {#} in m/(?[[[::]{#}]])/", | |
120 | '/(?[[[:w:]]])/' => "POSIX class [:w:] unknown in regex; marked by {#} in m/(?[[[:w:]{#}]])/", | |
121 | '/(?[[:w:]])/' => "POSIX class [:w:] unknown in regex; marked by {#} in m/(?[[:w:]{#}])/", | |
122 | '/(?[a])/' => 'Unexpected character in regex; marked by {#} in m/(?[a{#}])/', | |
123 | '/(?[\t])/l' => '(?[...]) not valid in locale in regex; marked by {#} in m/(?[{#}\t])/', | |
124 | '/(?[ + \t ])/' => 'Unexpected binary operator \'+\' with no preceding operand in regex; marked by {#} in m/(?[ +{#} \t ])/', | |
125 | '/(?[ \cK - ( + \t ) ])/' => 'Unexpected binary operator \'+\' with no preceding operand in regex; marked by {#} in m/(?[ \cK - ( +{#} \t ) ])/', | |
126 | '/(?[ \cK ( \t ) ])/' => 'Unexpected \'(\' with no preceding operator in regex; marked by {#} in m/(?[ \cK ({#} \t ) ])/', | |
127 | '/(?[ \cK \t ])/' => 'Operand with no preceding operator in regex; marked by {#} in m/(?[ \cK \t{#} ])/', | |
128 | '/(?[ \0004 ])/' => 'Need exactly 3 octal digits in regex; marked by {#} in m/(?[ \0004 {#}])/', | |
129 | '/(?[ \05 ])/' => 'Need exactly 3 octal digits in regex; marked by {#} in m/(?[ \05 {#}])/', | |
130 | '/(?[ \o{1038} ])/' => 'Non-octal character in regex; marked by {#} in m/(?[ \o{1038{#}} ])/', | |
131 | '/(?[ \o{} ])/' => 'Number with no digits in regex; marked by {#} in m/(?[ \o{}{#} ])/', | |
132 | '/(?[ \x{defg} ])/' => 'Non-hex character in regex; marked by {#} in m/(?[ \x{defg{#}} ])/', | |
133 | '/(?[ \xabcdef ])/' => 'Use \\x{...} for more than two hex characters in regex; marked by {#} in m/(?[ \xabc{#}def ])/', | |
134 | '/(?[ \x{} ])/' => 'Number with no digits in regex; marked by {#} in m/(?[ \x{}{#} ])/', | |
135 | '/(?[ \cK + ) ])/' => 'Unexpected \')\' in regex; marked by {#} in m/(?[ \cK + ){#} ])/', | |
136 | '/(?[ \cK + ])/' => 'Incomplete expression within \'(?[ ])\' in regex; marked by {#} in m/(?[ \cK + {#}])/', | |
137 | '/(?[ \p{foo} ])/' => 'Property \'foo\' is unknown in regex; marked by {#} in m/(?[ \p{foo}{#} ])/', | |
138 | '/(?[ \p{ foo = bar } ])/' => 'Property \'foo = bar\' is unknown in regex; marked by {#} in m/(?[ \p{ foo = bar }{#} ])/', | |
139 | '/(?[ \8 ])/' => 'Unrecognized escape \8 in character class in regex; marked by {#} in m/(?[ \8{#} ])/', | |
140 | '/(?[ \t ]/' => 'Syntax error in (?[...]) in regex m/(?[ \t ]/', | |
141 | '/(?[ [ \t ]/' => 'Syntax error in (?[...]) in regex m/(?[ [ \t ]/', | |
142 | '/(?[ \t ] ]/' => 'Syntax error in (?[...]) in regex m/(?[ \t ] ]/', | |
143 | '/(?[ [ ] ]/' => 'Syntax error in (?[...]) in regex m/(?[ [ ] ]/', | |
144 | '/(?[ \t + \e # This was supposed to be a comment ])/' => 'Syntax error in (?[...]) in regex m/(?[ \t + \e # This was supposed to be a comment ])/', | |
145 | '/(?[ ])/' => 'Incomplete expression within \'(?[ ])\' in regex; marked by {#} in m/(?[ {#}])/', | |
146 | 'm/(?[[a-\d]])/' => 'False [] range "a-\d" in regex; marked by {#} in m/(?[[a-\d{#}]])/', | |
147 | 'm/(?[[\w-x]])/' => 'False [] range "\w-" in regex; marked by {#} in m/(?[[\w-{#}x]])/', | |
148 | 'm/(?[[a-\pM]])/' => 'False [] range "a-\pM" in regex; marked by {#} in m/(?[[a-\pM{#}]])/', | |
149 | 'm/(?[[\pM-x]])/' => 'False [] range "\pM-" in regex; marked by {#} in m/(?[[\pM-{#}x]])/', | |
902994e4 | 150 | 'm/(?[[\N{LATIN CAPITAL LETTER A WITH MACRON AND GRAVE}]])/' => '\N{} in character class restricted to one character in regex; marked by {#} in m/(?[[\N{U+100.300{#}}]])/', |
b45f050a | 151 | ); |
902994e4 | 152 | # Tests involving a user-defined charnames translator are in pat_advanced.t |
b45f050a JF |
153 | |
154 | ## | |
6fe2934b | 155 | ## Key-value pairs of code/error of code that should have non-fatal regexp warnings. |
b45f050a | 156 | ## |
cb79f740 | 157 | my @warning = ( |
7253e4e3 | 158 | 'm/\b*/' => '\b* matches null string many times in regex; marked by {#} in m/\b*{#}/', |
b45f050a | 159 | |
7253e4e3 | 160 | 'm/[:blank:]/' => 'POSIX syntax [: :] belongs inside character classes in regex; marked by {#} in m/[:blank:]{#}/', |
b45f050a | 161 | |
7253e4e3 | 162 | "m'[\\y]'" => 'Unrecognized escape \y in character class passed through in regex; marked by {#} in m/[\y{#}]/', |
b45f050a | 163 | |
7253e4e3 RK |
164 | 'm/[a-\d]/' => 'False [] range "a-\d" in regex; marked by {#} in m/[a-\d{#}]/', |
165 | 'm/[\w-x]/' => 'False [] range "\w-" in regex; marked by {#} in m/[\w-{#}x]/', | |
f81125e2 JP |
166 | 'm/[a-\pM]/' => 'False [] range "a-\pM" in regex; marked by {#} in m/[a-\pM{#}]/', |
167 | 'm/[\pM-x]/' => 'False [] range "\pM-" in regex; marked by {#} in m/[\pM-{#}x]/', | |
7253e4e3 | 168 | "m'\\y'" => 'Unrecognized escape \y passed through in regex; marked by {#} in m/\y{#}/', |
31c15ce5 | 169 | '/x{3,1}/' => 'Quantifier {n,m} with n > m can\'t match in regex; marked by {#} in m/x{3,1}{#}/', |
5e0a247b KW |
170 | '/\08/' => '\'\08\' resolved to \'\o{0}8\' in regex; marked by {#} in m/\08{#}/', |
171 | '/\018/' => '\'\018\' resolved to \'\o{1}8\' in regex; marked by {#} in m/\018{#}/', | |
172 | '/[\08]/' => '\'\08\' resolved to \'\o{0}8\' in regex; marked by {#} in m/[\08{#}]/', | |
173 | '/[\018]/' => '\'\018\' resolved to \'\o{1}8\' in regex; marked by {#} in m/[\018{#}]/', | |
6fe2934b KW |
174 | ); |
175 | ||
176 | my @experimental_regex_sets = ( | |
3f4fde43 | 177 | '/(?[ \t ])/' => 'The regex_sets feature is experimental in regex; marked by {#} in m/(?[{#} \t ])/', |
b45f050a JF |
178 | ); |
179 | ||
cb79f740 NC |
180 | while (my ($regex, $expect) = splice @death, 0, 2) { |
181 | my $expect = fixup_expect($expect); | |
3f4fde43 | 182 | no warnings 'experimental::regex_sets'; |
40809656 | 183 | # skip the utf8 test on EBCDIC since they do not die |
cb79f740 | 184 | next if $::IS_EBCDIC && $regex =~ /utf8/; |
b45f050a | 185 | |
cb79f740 NC |
186 | warning_is(sub { |
187 | $_ = "x"; | |
188 | eval $regex; | |
40e98def KW |
189 | like($@, qr/\Q$expect/, $regex); |
190 | }, undef, "... and died without any other warnings"); | |
b45f050a JF |
191 | } |
192 | ||
6fe2934b KW |
193 | foreach my $ref (\@warning, \@experimental_regex_sets) { |
194 | my $warning_type = ($ref == \@warning) | |
195 | ? 'regexp' | |
196 | : 'experimental::regex_sets'; | |
b42857f3 KW |
197 | while (my ($regex, $expect) = splice @$ref, 0, 2) { |
198 | my $expect = fixup_expect($expect); | |
199 | if (warning_like(sub { | |
200 | $_ = "x"; | |
201 | eval $regex; | |
202 | is($@, '', "$regex did not die"); | |
203 | }, qr/\Q$expect/, "... and gave expected warning") | |
204 | ) { | |
6fe2934b KW |
205 | |
206 | ok (capture_warnings(sub { | |
207 | eval "no warnings '$warning_type'; $regex;" } | |
208 | ) == 0, | |
209 | "... and turning off '$warning_type' warnings suppressed it"); | |
b42857f3 | 210 | } |
6fe2934b KW |
211 | } |
212 | } | |
b45f050a | 213 | |
cb79f740 | 214 | done_testing(); |