From fa3696878bdabbced2ffe383b81c360e850784f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Fri, 25 Jun 2021 20:48:34 +0200 Subject: [PATCH] Fix crash when passing empty strings to bytes.concat() --- Changelog.md | 1 + libsolidity/codegen/ExpressionCompiler.cpp | 2 +- libsolidity/codegen/YulUtilFunctions.cpp | 2 +- ...l => bytes_concat_empty_argument_list.sol} | 0 .../concat/bytes_concat_empty_strings.sol | 27 +++++++++++++++++++ ...concat_wrong_type_empty_string_literal.sol | 6 +++++ 6 files changed, 36 insertions(+), 2 deletions(-) rename test/libsolidity/semanticTests/array/concat/{bytes_concat_empty.sol => bytes_concat_empty_argument_list.sol} (100%) create mode 100644 test/libsolidity/semanticTests/array/concat/bytes_concat_empty_strings.sol create mode 100644 test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol diff --git a/Changelog.md b/Changelog.md index d59e1f777..f5de44491 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,7 @@ Compiler Features: Bugfixes: + * Code Generator: Fix crash when passing an empty string literal to ``bytes.concat()``. * Code Generator: Fix internal compiler error when calling functions bound to calldata structs and arrays. * Code Generator: Fix internal compiler error when passing zero to ``bytes.concat()``. * Type Checker: Fix internal error and prevent static calls to unimplemented modifiers. diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index cdd608c29..89f9090a4 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1083,7 +1083,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) targetTypes.emplace_back(argument->annotation().type); else if ( auto const* literalType = dynamic_cast(argument->annotation().type); - literalType && literalType->value().size() <= 32 + literalType && !literalType->value().empty() && literalType->value().size() <= 32 ) targetTypes.emplace_back(TypeProvider::fixedBytes(static_cast(literalType->value().size()))); else if (auto const* literalType = dynamic_cast(argument->annotation().type)) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index a887c33da..edc1c4ad2 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -2473,7 +2473,7 @@ string YulUtilFunctions::bytesConcatFunction(vector const& _argumen targetTypes.emplace_back(argumentType); else if ( auto const* literalType = dynamic_cast(argumentType); - literalType && literalType->value().size() <= 32 + literalType && !literalType->value().empty() && literalType->value().size() <= 32 ) targetTypes.emplace_back(TypeProvider::fixedBytes(static_cast(literalType->value().size()))); else if (auto const* literalType = dynamic_cast(argumentType)) diff --git a/test/libsolidity/semanticTests/array/concat/bytes_concat_empty.sol b/test/libsolidity/semanticTests/array/concat/bytes_concat_empty_argument_list.sol similarity index 100% rename from test/libsolidity/semanticTests/array/concat/bytes_concat_empty.sol rename to test/libsolidity/semanticTests/array/concat/bytes_concat_empty_argument_list.sol diff --git a/test/libsolidity/semanticTests/array/concat/bytes_concat_empty_strings.sol b/test/libsolidity/semanticTests/array/concat/bytes_concat_empty_strings.sol new file mode 100644 index 000000000..0dc856262 --- /dev/null +++ b/test/libsolidity/semanticTests/array/concat/bytes_concat_empty_strings.sol @@ -0,0 +1,27 @@ +contract C { + function f() public returns (bytes memory) { + bytes memory b = ""; + return bytes.concat( + bytes.concat(b), + bytes.concat(b, b), + bytes.concat("", b), + bytes.concat(b, "") + ); + } + + function g() public returns (bytes memory) { + return bytes.concat("", "abc", hex"", "abc", unicode""); + } + + function h() public returns (bytes memory) { + bytes memory b = ""; + return bytes.concat(b, "abc", b, "abc", b); + } +} +// ==== +// compileToEwasm: also +// compileViaYul: also +// ---- +// f() -> 0x20, 0 +// g() -> 0x20, 6, "abcabc" +// h() -> 0x20, 6, "abcabc" diff --git a/test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol b/test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol new file mode 100644 index 000000000..afba249f8 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/concat/bytes_concat_wrong_type_empty_string_literal.sol @@ -0,0 +1,6 @@ +contract C { + function f() public pure { + bytes.concat(hex"", unicode"", ""); + } +} +// ----