Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions src/prism.c
Original file line number Diff line number Diff line change
Expand Up @@ -9580,28 +9580,6 @@ escape_write_byte_encoded(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t byte
pm_buffer_append_byte(buffer, byte);
}

/**
* Write each byte of the given escaped character into the buffer.
*/
static inline void
escape_write_escape_encoded(pm_parser_t *parser, pm_buffer_t *buffer) {
size_t width;
if (parser->encoding_changed) {
width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end);
} else {
width = pm_encoding_utf_8_char_width(parser->current.end, parser->end - parser->current.end);
}

// TODO: If the character is invalid in the given encoding, then we'll just
// push one byte into the buffer. This should actually be an error.
width = (width == 0) ? 1 : width;

for (size_t index = 0; index < width; index++) {
escape_write_byte_encoded(parser, buffer, *parser->current.end);
parser->current.end++;
}
}

/**
* The regular expression engine doesn't support the same escape sequences as
* Ruby does. So first we have to read the escape sequence, and then we have to
Expand All @@ -9626,6 +9604,28 @@ escape_write_byte(pm_parser_t *parser, pm_buffer_t *buffer, pm_buffer_t *regular
escape_write_byte_encoded(parser, buffer, byte);
}

/**
* Write each byte of the given escaped character into the buffer.
*/
static inline void
escape_write_escape_encoded(pm_parser_t *parser, pm_buffer_t *buffer, pm_buffer_t *regular_expression_buffer, uint8_t flags) {
size_t width;
if (parser->encoding_changed) {
width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end);
} else {
width = pm_encoding_utf_8_char_width(parser->current.end, parser->end - parser->current.end);
}

if (width == 1) {
escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(*parser->current.end++, flags));
} else {
// Assume the next character wasn't meant to be part of this escape
// sequence since it is invalid. Add an error and move on.
parser->current.end += width;
pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL);
}
}

/**
* Warn about using a space or a tab character in an escape, as opposed to using
* \\s or \\t. Note that we can quite copy the source because the warning
Expand Down Expand Up @@ -10050,7 +10050,7 @@ escape_read(pm_parser_t *parser, pm_buffer_t *buffer, pm_buffer_t *regular_expre
}
default: {
if (parser->current.end < parser->end) {
escape_write_escape_encoded(parser, buffer);
escape_write_escape_encoded(parser, buffer, regular_expression_buffer, flags);
} else {
pm_parser_err_current(parser, PM_ERR_INVALID_ESCAPE_CHARACTER);
}
Expand Down
3 changes: 3 additions & 0 deletions test/prism/unescape_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,23 +110,23 @@
end
end

def test_char; assert_context(Context::String.new("?", "")); end

Check failure on line 113 in test/prism/unescape_test.rb

View workflow job for this annotation

GitHub Actions / gem-install (head, windows-latest, 3.4)

Failure

Expected ? to unescape "C-\\ " to " ", but got "\x00". <[32]> expected but was <[0]>.
def test_sqte; assert_context(Context::String.new("'", "'")); end
def test_dqte; assert_context(Context::String.new("\"", "\"")); end

Check failure on line 115 in test/prism/unescape_test.rb

View workflow job for this annotation

GitHub Actions / gem-install (head, windows-latest, 3.4)

Failure

Expected "" to unescape "C-\\ " to " ", but got "\x00". <[32]> expected but was <[0]>.
def test_lwrq; assert_context(Context::String.new("%q[", "]")); end
def test_uprq; assert_context(Context::String.new("%Q[", "]")); end
def test_dstr; assert_context(Context::String.new("%[", "]")); end

Check failure on line 118 in test/prism/unescape_test.rb

View workflow job for this annotation

GitHub Actions / gem-install (head, windows-latest, 3.4)

Failure

Expected %[] to unescape "C-\\ " to " ", but got "\x00". <[32]> expected but was <[0]>.
def test_xstr; assert_context(Context::String.new("`", "`")); end
def test_lwrx; assert_context(Context::String.new("%x[", "]")); end
def test_h0_1; assert_context(Context::String.new("<<H\n", "\nH")); end

Check failure on line 121 in test/prism/unescape_test.rb

View workflow job for this annotation

GitHub Actions / gem-install (head, windows-latest, 3.4)

Failure

Expected <<HH to unescape "C-\\ " to " \n", but got "\x00\n". <[32, 10]> expected but was <[0, 10]>. diff: - [32, 10] ? ^^ + [0, 10] ? ^
def test_h0_2; assert_context(Context::String.new("<<'H'\n", "\nH")); end
def test_h0_3; assert_context(Context::String.new("<<\"H\"\n", "\nH")); end

Check failure on line 123 in test/prism/unescape_test.rb

View workflow job for this annotation

GitHub Actions / gem-install (head, windows-latest, 3.4)

Failure

Expected <<"H"H to unescape "C-\\ " to " \n", but got "\x00\n". <[32, 10]> expected but was <[0, 10]>. diff: - [32, 10] ? ^^ + [0, 10] ? ^
def test_h0_4; assert_context(Context::String.new("<<`H`\n", "\nH")); end

Check failure on line 124 in test/prism/unescape_test.rb

View workflow job for this annotation

GitHub Actions / gem-install (head, windows-latest, 3.4)

Failure

Expected <<`H`H to unescape "C-\\ " to " \n", but got "\x00\n". <[32, 10]> expected but was <[0, 10]>. diff: - [32, 10] ? ^^ + [0, 10] ? ^
def test_hd_1; assert_context(Context::String.new("<<-H\n", "\nH")); end

Check failure on line 125 in test/prism/unescape_test.rb

View workflow job for this annotation

GitHub Actions / gem-install (head, windows-latest, 3.4)

Failure

Expected <<-HH to unescape "C-\\ " to " \n", but got "\x00\n". <[32, 10]> expected but was <[0, 10]>. diff: - [32, 10] ? ^^ + [0, 10] ? ^
def test_hd_2; assert_context(Context::String.new("<<-'H'\n", "\nH")); end
def test_hd_3; assert_context(Context::String.new("<<-\"H\"\n", "\nH")); end

Check failure on line 127 in test/prism/unescape_test.rb

View workflow job for this annotation

GitHub Actions / gem-install (head, windows-latest, 3.4)

Failure

Expected <<-"H"H to unescape "C-\\ " to " \n", but got "\x00\n". <[32, 10]> expected but was <[0, 10]>. diff: - [32, 10] ? ^^ + [0, 10] ? ^
def test_hd_4; assert_context(Context::String.new("<<-`H`\n", "\nH")); end

Check failure on line 128 in test/prism/unescape_test.rb

View workflow job for this annotation

GitHub Actions / gem-install (head, windows-latest, 3.4)

Failure

Expected <<-`H`H to unescape "C-\\ " to " \n", but got "\x00\n". <[32, 10]> expected but was <[0, 10]>. diff: - [32, 10] ? ^^ + [0, 10] ? ^
def test_ht_1; assert_context(Context::Heredoc.new("<<~H\n", "\nH")); end

Check failure on line 129 in test/prism/unescape_test.rb

View workflow job for this annotation

GitHub Actions / gem-install (head, windows-latest, 3.4)

Failure

Expected <<~HH to unescape "C-\\ " to " \n", but got "\x00\n". <[32, 10]> expected but was <[0, 10]>. diff: - [32, 10] ? ^^ + [0, 10] ? ^
def test_ht_2; assert_context(Context::Heredoc.new("<<~'H'\n", "\nH")); end
def test_ht_3; assert_context(Context::Heredoc.new("<<~\"H\"\n", "\nH")); end
def test_ht_4; assert_context(Context::Heredoc.new("<<~`H`\n", "\nH")); end
Expand Down Expand Up @@ -204,6 +204,9 @@
# \C-a \C-b \C-c ...
assert_unescape(context, "C-#{chr}")

# \C-\a \C-\b \C-\c ...
assert_unescape(context, "C-\\#{chr}")

# \ca \cb \cc ...
assert_unescape(context, "c#{chr}")

Expand Down
Loading