Skip to content

Commit

Permalink
css2: Handle escape sequences more correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
robinlinden committed Jan 23, 2025
1 parent 95c49f2 commit bb7ff0c
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 0 deletions.
11 changes: 11 additions & 0 deletions css2/tokenizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ std::string_view to_string(ParseError e) {
return "EofInEscapeSequence";
case ParseError::EofInString:
return "EofInString";
case ParseError::InvalidEscapeSequence:
return "InvalidEscapeSequence";
case ParseError::NewlineInString:
return "NewlineInString";
}
Expand Down Expand Up @@ -177,6 +179,15 @@ void Tokenizer::run() {
case '[':
emit(OpenSquareToken{});
continue;
case '\\':
if (is_valid_escape_sequence('\\', peek_input(0))) {
reconsume_in(State::IdentLike);
continue;
}

emit(ParseError::InvalidEscapeSequence);
emit(DelimToken{'\\'});
continue;
case ']':
emit(CloseSquareToken{});
continue;
Expand Down
1 change: 1 addition & 0 deletions css2/tokenizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum class ParseError : std::uint8_t {
EofInComment,
EofInEscapeSequence,
EofInString,
InvalidEscapeSequence,
NewlineInString,
};

Expand Down
14 changes: 14 additions & 0 deletions css2/tokenizer_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ int main() {
s.add_test("at keyword start, but with bad escape", [](etest::IActions &a) {
auto output = run_tokenizer(a, "@\\\n");
expect_token(output, DelimToken{'@'});
expect_error(output, ParseError::InvalidEscapeSequence);
expect_token(output, DelimToken{'\\'});
expect_token(output, WhitespaceToken{});
});
Expand Down Expand Up @@ -638,6 +639,19 @@ int main() {
s.add_test("hash token: invalid escape", [](etest::IActions &a) {
auto output = run_tokenizer(a, "#\\\n");
expect_token(output, DelimToken{'#'});
expect_error(output, ParseError::InvalidEscapeSequence);
expect_token(output, DelimToken{'\\'});
expect_token(output, WhitespaceToken{});
});

s.add_test("\\: ident-like", [](etest::IActions &a) {
auto output = run_tokenizer(a, "\\Hallo");
expect_token(output, IdentToken{"Hallo"});
});

s.add_test("\\: invalid escape", [](etest::IActions &a) {
auto output = run_tokenizer(a, "\\\n");
expect_error(output, ParseError::InvalidEscapeSequence);
expect_token(output, DelimToken{'\\'});
expect_token(output, WhitespaceToken{});
});
Expand Down

0 comments on commit bb7ff0c

Please sign in to comment.