Parcourir la source

Fix bytes() cast from fixed length and vice versa (#1075)

Signed-off-by: Sean Young <sean@mess.org>
Sean Young il y a 3 ans
Parent
commit
18d3af319c

+ 2 - 2
src/emit/expression.rs

@@ -985,7 +985,7 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
 
             runtime_cast(bin, function, &from, to, e, ns)
         }
-        Expression::BytesCast(_, Type::Bytes(_), Type::DynamicBytes, e) => {
+        Expression::BytesCast(_, Type::DynamicBytes, Type::Bytes(_), e) => {
             let e = expression(target, bin, e, vartab, function, ns).into_int_value();
 
             let size = e.get_type().get_bit_width() / 8;
@@ -1021,7 +1021,7 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
                 .left()
                 .unwrap()
         }
-        Expression::BytesCast(_, Type::DynamicBytes, Type::Bytes(n), e) => {
+        Expression::BytesCast(_, Type::Bytes(n), Type::DynamicBytes, e) => {
             let array = expression(target, bin, e, vartab, function, ns);
 
             let len = bin.vector_len(array);

+ 1 - 1
src/sema/dotgraphviz.rs

@@ -641,7 +641,7 @@ impl Dot {
 
                 self.add_expression(expr, func, ns, node, String::from("expr"));
             }
-            Expression::BytesCast(loc, from, to, expr) => {
+            Expression::BytesCast(loc, to, from, expr) => {
                 let node = self.add_node(
                     Node::new(
                         "bytes_cast",

+ 2 - 2
src/sema/expression.rs

@@ -75,7 +75,7 @@ impl RetrieveType for Expression {
             | Expression::Trunc(_, ty, _)
             | Expression::CheckingTrunc(_, ty, _)
             | Expression::Cast(_, ty, _)
-            | Expression::BytesCast(_, _, ty, _)
+            | Expression::BytesCast(_, ty, ..)
             | Expression::Complement(_, ty, _)
             | Expression::UnaryMinus(_, ty, _)
             | Expression::ConditionalOperator(_, ty, ..)
@@ -839,7 +839,7 @@ impl Expression {
                 Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
             }
             (Type::Bytes(_), Type::DynamicBytes) | (Type::DynamicBytes, Type::Bytes(_)) => Ok(
-                Expression::BytesCast(*loc, from.clone(), to.clone(), Box::new(self.clone())),
+                Expression::BytesCast(*loc, to.clone(), from.clone(), Box::new(self.clone())),
             ),
             // Explicit conversion from bytesN to int/uint only allowed with expliciy
             // cast and if it is the same size (i.e. no conversion required)

+ 1 - 1
tests/codegen_testcases/solidity/common_subexpression_elimination.sol

@@ -435,7 +435,7 @@ contract c1 {
         b3 = bytes("d");
         for(int p=0; p<a; ++p) {
             doNothing(b1);
-            // CHECK: ty:bytes32 %b2.155 = bytes from:bytes32 (%b3)
+            // CHECK: ty:bytes32 %b2.155 = bytes32 from:bytes (%b3)
             bytes32 b2 = bytes32(b3);
             doNothing(b2);
         }

+ 37 - 0
tests/solana_tests/primitives.rs

@@ -1566,3 +1566,40 @@ fn truncate_bigint(n: &mut BigInt, width: usize) {
     }
     *n = BigInt::from_signed_bytes_le(&bytes_le);
 }
+
+#[test]
+fn bytes_cast() {
+    let mut vm = build_solidity(
+        r#"
+        contract foo {
+            function to_bytes(bytes4 b) public returns (bytes) {
+                return b;
+            }
+
+            function to_bytes5(bytes b) public returns (bytes5) {
+                return b;
+            }
+        }
+        "#,
+    );
+
+    vm.constructor("foo", &[]);
+
+    let returns = vm.function(
+        "to_bytes",
+        &[BorshToken::FixedBytes(b"abcd".to_vec())],
+        &[],
+        None,
+    );
+
+    assert_eq!(returns, vec![BorshToken::Bytes(b"abcd".to_vec())]);
+
+    let returns = vm.function(
+        "to_bytes5",
+        &[BorshToken::Bytes(b"abcde".to_vec())],
+        &[],
+        None,
+    );
+
+    assert_eq!(returns, vec![BorshToken::FixedBytes(b"abcde".to_vec())]);
+}