1# tests for heredocs besides what is tested in base/lex.t 2 3BEGIN { 4 chdir 't' if -d 't'; 5 require './test.pl'; 6 set_up_inc('../lib'); 7} 8 9use strict; 10plan(tests => 137); 11 12# heredoc without newline (#65838) 13{ 14 my $string = <<'HEREDOC'; 15testing for 65838 16HEREDOC 17 18 my $code = "<<'HEREDOC';\n${string}HEREDOC"; # HD w/o newline, in eval-string 19 my $hd = eval $code or warn "$@ ---"; 20 is($hd, $string, "no terminating newline in string-eval"); 21} 22 23 24# here-doc edge cases 25{ 26 my $string = "testing for 65838"; 27 28 fresh_perl_is( 29 "print <<'HEREDOC';\n${string}\nHEREDOC", 30 $string, 31 {}, 32 "heredoc at EOF without trailing newline" 33 ); 34 35 fresh_perl_is( 36 qq(print <<"";\n$string\n), 37 $string, 38 { switches => ['-X'] }, 39 "blank-terminated heredoc at EOF" 40 ); 41 fresh_perl_is( 42 qq(print <<""\n$string\n), 43 $string, 44 { switches => ['-X'] }, 45 "blank-terminated heredoc at EOF and no semicolon" 46 ); 47 fresh_perl_is( 48 "print <<foo\r\nick and queasy\r\nfoo\r\n", 49 'ick and queasy', 50 { switches => ['-X'] }, 51 "crlf-terminated heredoc" 52 ); 53 fresh_perl_is( 54 "print qq|\${\\<<foo}|\nick and queasy\nfoo\n", 55 'ick and queasy', 56 { switches => ['-w'], stderr => 1 }, 57 'no warning for qq|${\<<foo}| in file' 58 ); 59} 60 61 62# here-doc parse failures 63{ 64 fresh_perl_like( 65 "print <<HEREDOC;\nwibble\n HEREDOC", 66 qr/find string terminator/, 67 {}, 68 "string terminator must start at newline" 69 ); 70 71 # Loop over various lengths to try to force at least one to cause a 72 # reallocation in S_scan_heredoc() 73 # Timing on a modern machine suggests that this loop executes in less than 74 # 0.1s, so it's a very small cost for the default build. The benefit is 75 # that building with ASAN will reveal the bug and any related regressions. 76 for (1..31) { 77 fresh_perl_like( 78 qq(print <<"";\n) . "x" x $_, 79 qr/find string terminator/, 80 { switches => ['-X'] }, 81 "empty string terminator still needs a newline (length $_)" 82 ); 83 } 84 85 fresh_perl_like( 86 "print <<ThisTerminatorIsLongerThanTheData;\nno more newlines", 87 qr/find string terminator/, 88 {}, 89 "long terminator fails correctly" 90 ); 91 92 # this would read freed memory 93 fresh_perl_like( 94 qq(0<<<<""0\n\n), 95 # valgrind and asan reports an error between these two lines 96 qr/^Number found where operator expected at - line 1, near "<<""0"\s+\(Missing operator/, 97 {}, 98 "don't use an invalid oldoldbufptr" 99 ); 100 101 # also read freed memory, but got an invalid oldoldbufptr in a different way 102 fresh_perl_like( 103 qq(<<""\n\$ \n), 104 # valgrind and asan reports an error between these two lines 105 qr/^Final \$/, 106 {}, 107 "don't use an invalid oldoldbufptr (some more)" 108 ); 109 110 # [perl #125540] this asserted or crashed 111 fresh_perl_like( 112 q(map d<<<<""), 113 qr/Can't find string terminator "" anywhere before EOF at - line 1\./, 114 {}, 115 "Don't assert parsing a here-doc if we hit EOF early" 116 ); 117 118 # [perl #129064] heap-buffer-overflow S_scan_heredoc 119 fresh_perl_like( 120 qq(<<`\\), 121 # valgrind and asan reports an error between these two lines 122 qr/^Unterminated delimiter for here document/, 123 {}, 124 "delimcpy(): handle last char being backslash properly" 125 ); 126} 127 128 129# indented here-docs 130{ 131 my $string = 'some data'; 132 133 my %delimiters = ( 134 q{EOF} => "EOF", 135 q{'EOF'} => "EOF", 136 q{"EOF"} => "EOF", 137 q{\EOF} => "EOF", 138 q{' EOF'} => " EOF", 139 q{'EOF '} => "EOF ", 140 q{' EOF '} => " EOF ", 141 q{" EOF"} => " EOF", 142 q{"EOF "} => "EOF ", 143 q{" EOF "} => " EOF ", 144 q{''} => "", 145 q{""} => "", 146 ); 147 148 my @modifiers = ("~", "~ "); 149 150 my @script_ends = ("", "\n"); 151 152 my @tests; 153 154 for my $start_delim (sort keys %delimiters) { 155 my $end_delim = $delimiters{$start_delim}; 156 157 for my $modifier (@modifiers) { 158 # For now, "<<~ EOF" and "<<~ \EOF" aren't allowed 159 next if $modifier =~ /\s/ && $start_delim !~ /('|")/n; 160 161 for my $script_end (@script_ends) { 162 # Normal heredoc 163 my $test = "print <<$modifier$start_delim\n $string\n" 164 . " $end_delim$script_end"; 165 unshift @tests, [ 166 $test, 167 $string, 168 "Indented here-doc: <<$modifier$start_delim with end delim '$end_delim'" . ($script_end ? "\\n" : ""), 169 ]; 170 171 # Eval'd heredoc 172 my $safe_start_delim = $start_delim =~ s/'/\\'/gr; 173 my $eval = " 174 \$_ = ''; 175 eval 's//<<$modifier$safe_start_delim.\"\"/e; print 176 $string 177 $end_delim$script_end' 178 or die \$\@ 179 "; 180 push @tests, [ 181 $eval, 182 $string, 183 "Eval'd Indented here-doc: <<$modifier$start_delim with end delim '$end_delim'" . ($script_end ? "\\n" : ""), 184 185 ]; 186 } 187 } 188 } 189 190 push @tests, [ 191 "print <<~EOF;\n\t \t$string\n\t \tEOF\n", 192 $string, 193 "indented here-doc with tabs and spaces", 194 ]; 195 196 push @tests, [ 197 "print <<~EOF;\n\t \tx EOF\n\t \t$string\n\t \tEOF\n", 198 "x EOF\n$string", 199 "Embedded delimiter ignored", 200 ]; 201 202 push @tests, [ 203 "print <<~EOF;\n\t \t$string\n\t \tTEOF", 204 "Can't find string terminator \"EOF\" anywhere before EOF at - line 1.", 205 "indented here-doc missing terminator error is correct" 206 ]; 207 208 push @tests, [ 209 "print <<~EOF;\n $string\n$string\n $string\n $string\n EOF", 210 "Indentation on line 1 of here-doc doesn't match delimiter at - line 1.\n", 211 "indented here-doc with bad indentation" 212 ]; 213 214 push @tests, [ 215 "print <<~EOF;\n $string\n $string\n$string\n $string\n EOF", 216 "Indentation on line 3 of here-doc doesn't match delimiter at - line 1.\n", 217 "indented here-doc with bad indentation" 218 ]; 219 220 # If our delim is " EOF ", make sure other spaced version don't match 221 push @tests, [ 222 "print <<~' EOF ';\n $string\n EOF\nEOF \n EOF \n EOF \n", 223 " $string\n EOF\nEOF \n EOF \n", 224 "indented here-doc matches final delimiter correctly" 225 ]; 226 227 for my $test (@tests) { 228 fresh_perl_is( 229 $test->[0], 230 $test->[1], 231 { switches => ['-w'], stderr => 1 }, 232 $test->[2], 233 ); 234 } 235} 236