-
Notifications
You must be signed in to change notification settings - Fork 154
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix percent delimiter strings with crlfs
parse.y treats CRLF as a LF and basically "normalizes" them before parsing. That means a string like `%\nfoo\r\n` is actually treated as `%\nfoo\n` for the purposes of parsing. This happens on both the opening side of the percent string as well as on the closing side. So for example `%\r\nfoo\n` must be treated as `%\nfoo\n`. To handle this in Prism, when we start a % string, we check if it starts with `\r\n`, and then consider the terminator to actually be `\n`. Then we check if there are `\r\n` as we lex the string and treat those as `\n`, but only in the case the start was a `\n`. Fixes: #3230 [Bug #20938] Co-authored-by: John Hawthorn <[email protected]> Co-authored-by: eileencodes <[email protected]> Co-authored-by: Kevin Newton <[email protected]>
- Loading branch information
1 parent
75a6171
commit e573cea
Showing
2 changed files
with
86 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative "test_helper" | ||
|
||
module Prism | ||
class PercentDelimiterStringTest < TestCase | ||
def test_newline_terminator_with_lf_crlf | ||
str = "%\n123456\r\n" | ||
assert_parse "123456", str | ||
end | ||
|
||
def test_newline_terminator_with_lf_crlf_with_extra_cr | ||
str = "%\n123456\r\r\n" | ||
assert_parse "123456\r", str | ||
end | ||
|
||
def test_newline_terminator_with_crlf_pair | ||
str = "%\r\n123456\r\n" | ||
assert_parse "123456", str | ||
end | ||
|
||
def test_newline_terminator_with_crlf_crlf_with_extra_cr | ||
str = "%\r\n123456\r\r\n" | ||
assert_parse "123456\r", str | ||
end | ||
|
||
def test_newline_terminator_with_cr_cr | ||
str = "%\r123456\r;\n" | ||
assert_parse "123456", str | ||
end | ||
|
||
def test_newline_terminator_with_crlf_lf | ||
str = "%\r\n123456\n;\n" | ||
assert_parse "123456", str | ||
end | ||
|
||
def test_cr_crlf | ||
str = "%\r1\r\n \r" | ||
assert_parse "1\n ", str | ||
end | ||
|
||
def test_lf_crlf | ||
str = "%\n1\r\n \n" | ||
assert_parse "1", str | ||
end | ||
|
||
def test_lf_lf | ||
str = "%\n1\n \n" | ||
assert_parse "1", str | ||
end | ||
|
||
def assert_parse(expected, str) | ||
tree = Prism.parse str | ||
node = tree.value.breadth_first_search { |x| Prism::StringNode === x } | ||
assert_equal expected, node.unescaped | ||
end | ||
end | ||
end |