From a550048cf058ac7a20e2c4ac07c962de74474e30 Mon Sep 17 00:00:00 2001 From: Marenz Date: Thu, 20 Jan 2022 14:53:18 +0100 Subject: [PATCH] Fix too strict assert for calldata string -> bytes conversions --- Changelog.md | 3 ++- libsolidity/codegen/CompilerUtils.cpp | 5 ++++- libsolidity/codegen/YulUtilFunctions.cpp | 5 ++++- .../explicit_string_bytes_calldata_cast.sol | 11 +++++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 test/libsolidity/semanticTests/viaYul/conversion/explicit_string_bytes_calldata_cast.sol diff --git a/Changelog.md b/Changelog.md index 0f7c3f29e..93b940839 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,12 +12,13 @@ Compiler Features: Bugfixes: * Antlr Grammar: Allow builtin names in ``yulPath`` to support ``.address`` in function pointers. + * Code Generator: Fix ICE when accessing the members of external functions occupying more than two stack slots. + * Code Generator: Fix ICE when doing an explicit conversion from ``string calldata`` to ``bytes``. * Control Flow Graph: Perform proper virtual lookup for modifiers for uninitialized variable and unreachable code analysis. * Immutables: Fix wrong error when the constructor of a base contract uses ``return`` and the parent contract contains immutable variables. * IR Generator: Fix IR syntax error when copying storage arrays of structs containing functions. * Natspec: Fix ICE when overriding a struct getter with a Natspec-documented return value and the name in the struct is different. * TypeChecker: Fix ICE when a constant variable declaration forward references a struct. - * Code Generator: Fix ICE when accessing the members of external functions occupying more than two stack slots. Solc-Js: diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 5e49868a3..a9a9118df 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -1140,7 +1140,10 @@ void CompilerUtils::convertType( solAssert(_targetType.category() == Type::Category::Array, ""); auto const& targetArrayType = dynamic_cast(_targetType); - solAssert(typeOnStack.arrayType().isImplicitlyConvertibleTo(targetArrayType), ""); + solAssert( + typeOnStack.arrayType().isImplicitlyConvertibleTo(targetArrayType) || + (typeOnStack.arrayType().isByteArray() && targetArrayType.isByteArray()) + ); solAssert( typeOnStack.arrayType().dataStoredIn(DataLocation::CallData) && typeOnStack.arrayType().isDynamicallySized() && diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index f8d4630ca..cb4bd3553 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -3222,7 +3222,10 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to) solAssert(_to.category() == Type::Category::Array, ""); auto const& targetType = dynamic_cast(_to); - solAssert(fromType.arrayType().isImplicitlyConvertibleTo(targetType), ""); + solAssert( + fromType.arrayType().isImplicitlyConvertibleTo(targetType) || + (fromType.arrayType().isByteArray() && targetType.isByteArray()) + ); solAssert( fromType.arrayType().dataStoredIn(DataLocation::CallData) && fromType.arrayType().isDynamicallySized() && diff --git a/test/libsolidity/semanticTests/viaYul/conversion/explicit_string_bytes_calldata_cast.sol b/test/libsolidity/semanticTests/viaYul/conversion/explicit_string_bytes_calldata_cast.sol new file mode 100644 index 000000000..4a5b01d39 --- /dev/null +++ b/test/libsolidity/semanticTests/viaYul/conversion/explicit_string_bytes_calldata_cast.sol @@ -0,0 +1,11 @@ +// Triggered ICE before +contract C { + function f(string calldata data) external pure returns(string memory) { + bytes calldata test = bytes(data[:3]); + return string(test); + } +} +// ==== +// compileViaYul: also +// ---- +// f(string): 0x20, 3, "123" -> 0x20, 3, "123"