Jelajahi Sumber

AccountInfo data field is not readonly (#1492)

Fixes #1489

Signed-off-by: Lucas Steuernagel <lucas.tnagel@gmail.com>
Lucas Steuernagel 2 tahun lalu
induk
melakukan
19de71a5bf

+ 6 - 2
src/sema/builtin.rs

@@ -1350,9 +1350,10 @@ pub(super) fn resolve_method_call(
     diagnostics: &mut Diagnostics,
 ) -> Result<Option<Expression>, ()> {
     let expr_ty = expr.ty();
+    let deref_ty = expr_ty.deref_memory();
     let funcs: Vec<_> = BUILTIN_METHODS
         .iter()
-        .filter(|func| func.name == id.name && func.method.contains(&expr_ty))
+        .filter(|func| func.name == id.name && func.method.contains(deref_ty))
         .collect();
     let mut errors = Diagnostics::default();
 
@@ -1421,7 +1422,10 @@ pub(super) fn resolve_method_call(
                 return Err(());
             }
         } else {
-            cast_args.insert(0, expr.clone());
+            cast_args.insert(
+                0,
+                expr.cast(&id.loc, deref_ty, true, ns, diagnostics).unwrap(),
+            );
 
             let returns = if func.ret.is_empty() {
                 vec![Type::Void]

+ 1 - 1
src/sema/builtin_structs.rs

@@ -49,7 +49,7 @@ static BUILTIN_STRUCTS: Lazy<[StructDecl; 3]> = Lazy::new(|| {
                     ty: Type::Slice(Box::new(Type::Bytes(1))),
                     ty_loc: None,
                     indexed: false,
-                    readonly: true,
+                    readonly: false,
                     infinite_size: false,
                     recursive: false,
                     annotation: None,

+ 1 - 1
src/sema/expression/member_access.rs

@@ -196,7 +196,7 @@ pub(super) fn member_access(
         (
             Expression::Load {
                 loc: *loc,
-                ty: expr_ty.clone(),
+                ty: *ty.clone(),
                 expr: Box::new(expr),
             },
             ty.as_ref().clone(),

+ 47 - 0
tests/solana_tests/account_info.rs

@@ -280,3 +280,50 @@ contract starter {
     assert_eq!(vm.account_data.get(&acc2).unwrap().lamports, 7);
     assert_eq!(vm.account_data.get(&acc3).unwrap().lamports, 11);
 }
+
+#[test]
+fn account_data() {
+    let mut vm = build_solidity(
+        r#"
+import 'solana';
+
+contract C {
+	function test() external {
+		AccountInfo ai = tx.accounts[1];
+		ai.data[0] = 0xca;
+		ai.data[1] = 0xff;
+		ai.data[2] = 0xee;
+	}
+}
+        "#,
+    );
+
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    let program_id = vm.stack[0].id;
+    let other_account = account_new();
+    vm.account_data.insert(
+        other_account,
+        AccountState {
+            lamports: 0,
+            owner: Some(program_id),
+            data: vec![0; 3],
+        },
+    );
+
+    vm.function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(other_account),
+            is_writable: true,
+            is_signer: false,
+        }])
+        .call();
+
+    assert_eq!(vm.account_data[&other_account].data[0], 0xca);
+    assert_eq!(vm.account_data[&other_account].data[1], 0xff);
+    assert_eq!(vm.account_data[&other_account].data[2], 0xee);
+}