From 66ee3ec533bada1836f09c626bb7209f08252ed6 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 25 Nov 2020 15:29:40 +0000 Subject: [PATCH] Remove the \b, \f, \v escape sequences from the Scanner --- Changelog.md | 1 + docs/080-breaking-changes.rst | 3 +++ docs/grammar/SolidityLexer.g4 | 2 +- liblangutil/Scanner.cpp | 9 -------- test/liblangutil/Scanner.cpp | 23 +++++++++++++++++-- .../semanticTests/strings/string_escapes.sol | 10 ++++++++ .../string/invalid_legacy_escape.sol | 8 +++++++ .../syntaxTests/string/string_escapes.sol | 2 +- 8 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 test/libsolidity/semanticTests/strings/string_escapes.sol create mode 100644 test/libsolidity/syntaxTests/string/invalid_legacy_escape.sol diff --git a/Changelog.md b/Changelog.md index 07c09998d..f8c9b5380 100644 --- a/Changelog.md +++ b/Changelog.md @@ -20,6 +20,7 @@ Breaking Changes: * Type System: Declarations with the name ``this``, ``super`` and ``_`` are disallowed, with the exception of public functions and events. * Type System: Disallow ``type(super)``. * Command Line Interface: JSON fields `abi`, `devdoc`, `userdoc` and `storage-layout` are now sub-objects rather than strings. + * Scanner: Remove support for the ``\b``, ``\f``, and ``\v`` escape sequences. Language Features: * Super constructors can now be called using the member notation e.g. ``M.C(123)``. diff --git a/docs/080-breaking-changes.rst b/docs/080-breaking-changes.rst index e9c206701..af81f1c4b 100644 --- a/docs/080-breaking-changes.rst +++ b/docs/080-breaking-changes.rst @@ -88,6 +88,9 @@ New Restrictions * Declarations with the name ``this``, ``super`` and ``_`` are disallowed, with the exception of public functions and events. +* Remove support for the ``\b``, ``\f``, and ``\v`` escape sequences in code. + They can still be inserted via hexadecimal escapes, e.g. ``\x08``, ``\x0c``, and ``\x0b``, respectively. + Interface Changes ================= diff --git a/docs/grammar/SolidityLexer.g4 b/docs/grammar/SolidityLexer.g4 index 6bb4f3809..284b9500b 100644 --- a/docs/grammar/SolidityLexer.g4 +++ b/docs/grammar/SolidityLexer.g4 @@ -184,7 +184,7 @@ fragment DoubleQuotedPrintable: [\u0020-\u0021\u0023-\u005B\u005D-\u007E]; */ fragment EscapeSequence: '\\' ( - ['"\\bfnrtv\n\r] + ['"\\nrt\n\r] | 'u' HexCharacter HexCharacter HexCharacter HexCharacter | 'x' HexCharacter HexCharacter ); diff --git a/liblangutil/Scanner.cpp b/liblangutil/Scanner.cpp index 1a3903d5c..234f2461a 100644 --- a/liblangutil/Scanner.cpp +++ b/liblangutil/Scanner.cpp @@ -728,12 +728,6 @@ bool Scanner::scanEscape() case '"': // fall through case '\\': break; - case 'b': - c = '\b'; - break; - case 'f': - c = '\f'; - break; case 'n': c = '\n'; break; @@ -743,9 +737,6 @@ bool Scanner::scanEscape() case 't': c = '\t'; break; - case 'v': - c = '\v'; - break; case 'u': { if (auto const codepoint = scanUnicode(); codepoint.has_value()) diff --git a/test/liblangutil/Scanner.cpp b/test/liblangutil/Scanner.cpp index 2110cb2b6..b8d51aca5 100644 --- a/test/liblangutil/Scanner.cpp +++ b/test/liblangutil/Scanner.cpp @@ -131,10 +131,29 @@ BOOST_AUTO_TEST_CASE(string_escapes) BOOST_AUTO_TEST_CASE(string_escapes_all) { - Scanner scanner(CharStream(" { \"a\\x61\\b\\f\\n\\r\\t\\v\"", "")); + Scanner scanner(CharStream(" { \"a\\x61\\n\\r\\t\"", "")); BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace); BOOST_CHECK_EQUAL(scanner.next(), Token::StringLiteral); - BOOST_CHECK_EQUAL(scanner.currentLiteral(), "aa\b\f\n\r\t\v"); + BOOST_CHECK_EQUAL(scanner.currentLiteral(), "aa\n\r\t"); +} + +BOOST_AUTO_TEST_CASE(string_escapes_legal_before_080) +{ + Scanner scanner(CharStream(" { \"a\\b", "")); + BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace); + BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal); + BOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalEscapeSequence); + BOOST_CHECK_EQUAL(scanner.currentLiteral(), ""); + scanner.reset(CharStream(" { \"a\\f", "")); + BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace); + BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal); + BOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalEscapeSequence); + BOOST_CHECK_EQUAL(scanner.currentLiteral(), ""); + scanner.reset(CharStream(" { \"a\\v", "")); + BOOST_CHECK_EQUAL(scanner.currentToken(), Token::LBrace); + BOOST_CHECK_EQUAL(scanner.next(), Token::Illegal); + BOOST_CHECK_EQUAL(scanner.currentError(), ScannerError::IllegalEscapeSequence); + BOOST_CHECK_EQUAL(scanner.currentLiteral(), ""); } BOOST_AUTO_TEST_CASE(string_escapes_with_zero) diff --git a/test/libsolidity/semanticTests/strings/string_escapes.sol b/test/libsolidity/semanticTests/strings/string_escapes.sol new file mode 100644 index 000000000..66a8b1ea3 --- /dev/null +++ b/test/libsolidity/semanticTests/strings/string_escapes.sol @@ -0,0 +1,10 @@ +contract test { + function f() public pure returns (bytes32) { + bytes32 escapeCharacters = "\t\n\r\'\"\\"; + return escapeCharacters; + } +} +// ==== +// compileViaYul: also +// ---- +// f() -> 0x090a0d27225c0000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/syntaxTests/string/invalid_legacy_escape.sol b/test/libsolidity/syntaxTests/string/invalid_legacy_escape.sol new file mode 100644 index 000000000..1972990ef --- /dev/null +++ b/test/libsolidity/syntaxTests/string/invalid_legacy_escape.sol @@ -0,0 +1,8 @@ +contract test { + function f() public pure returns (bytes32) { + bytes32 escapeCharacters = "\t\b\f"; + return escapeCharacters; + } +} +// ---- +// ParserError 8936: (100-105): Invalid escape sequence. diff --git a/test/libsolidity/syntaxTests/string/string_escapes.sol b/test/libsolidity/syntaxTests/string/string_escapes.sol index 51b90d735..95739062b 100644 --- a/test/libsolidity/syntaxTests/string/string_escapes.sol +++ b/test/libsolidity/syntaxTests/string/string_escapes.sol @@ -1,6 +1,6 @@ contract test { function f() public pure returns (bytes32) { - bytes32 escapeCharacters = "\t\b\n\r\f\'\"\\\b"; + bytes32 escapeCharacters = "\n\r\'\"\\"; return escapeCharacters; } }