diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index e19e22f29..cd2b3805c 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -3157,5 +3157,5 @@ bool IRGeneratorForStatements::visit(TryCatchClause const& _clause) string IRGeneratorForStatements::linkerSymbol(ContractDefinition const& _library) const { solAssert(_library.isLibrary(), ""); - return "linkersymbol(" + util::escapeAndQuoteString(_library.fullyQualifiedName()) + ")"; + return "linkersymbol(" + util::escapeAndQuoteYulString(_library.fullyQualifiedName()) + ")"; } diff --git a/libsolutil/CommonData.cpp b/libsolutil/CommonData.cpp index 1dc616836..c6688fee8 100644 --- a/libsolutil/CommonData.cpp +++ b/libsolutil/CommonData.cpp @@ -192,11 +192,13 @@ string solidity::util::formatAsStringOrNumber(string const& _value) if (c <= 0x1f || c >= 0x7f || c == '"') return "0x" + h256(_value, h256::AlignLeft).hex(); - return escapeAndQuoteString(_value); + // The difference in escaping is only in characters below 0x1f and the string does not have them + // so this will work for Solidity strings too. + return escapeAndQuoteYulString(_value); } -string solidity::util::escapeAndQuoteString(string const& _input) +string solidity::util::escapeAndQuoteYulString(string const& _input) { string out; @@ -205,18 +207,12 @@ string solidity::util::escapeAndQuoteString(string const& _input) out += "\\\\"; else if (c == '"') out += "\\\""; - else if (c == '\b') - out += "\\b"; - else if (c == '\f') - out += "\\f"; else if (c == '\n') out += "\\n"; else if (c == '\r') out += "\\r"; else if (c == '\t') out += "\\t"; - else if (c == '\v') - out += "\\v"; else if (!isprint(c, locale::classic())) { ostringstream o; diff --git a/libsolutil/CommonData.h b/libsolutil/CommonData.h index b33231a32..3c8b2d80c 100644 --- a/libsolutil/CommonData.h +++ b/libsolutil/CommonData.h @@ -554,7 +554,7 @@ std::string formatAsStringOrNumber(std::string const& _value); /// @returns a string with the usual backslash-escapes for non-ASCII /// characters and surrounded by '"'-characters. -std::string escapeAndQuoteString(std::string const& _input); +std::string escapeAndQuoteYulString(std::string const& _input); template bool containerEqual(Container const& _lhs, Container const& _rhs, Compare&& _compare) diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index 8c5f26178..e91208feb 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -57,7 +57,7 @@ string AsmPrinter::operator()(Literal const& _literal) const break; } - return escapeAndQuoteString(_literal.value.str()) + appendTypeName(_literal.type); + return escapeAndQuoteYulString(_literal.value.str()) + appendTypeName(_literal.type); } string AsmPrinter::operator()(Identifier const& _identifier) const diff --git a/test/libsolidity/semanticTests/literals/hex_string_with_non_printable_characters.sol b/test/libsolidity/semanticTests/literals/hex_string_with_non_printable_characters.sol new file mode 100644 index 000000000..5b703b614 --- /dev/null +++ b/test/libsolidity/semanticTests/literals/hex_string_with_non_printable_characters.sol @@ -0,0 +1,12 @@ +contract C { + function f() public pure returns (bytes32 result) { + assembly { + result := hex"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + } + } +} +// ==== +// compileToEwasm: also +// compileViaYul: also +// ---- +// f() -> 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f diff --git a/test/libyul/yulSyntaxTests/hex_string_literal_non_printable_characters.yul b/test/libyul/yulSyntaxTests/hex_string_literal_non_printable_characters.yul new file mode 100644 index 000000000..4a28c44a7 --- /dev/null +++ b/test/libyul/yulSyntaxTests/hex_string_literal_non_printable_characters.yul @@ -0,0 +1,6 @@ +{ + let name := hex"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" +} +// ==== +// dialect: evm +// ----