Эх сурвалжийг харах

Check parameters and returns fit into memory

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 4 жил өмнө
parent
commit
5be7007c40

+ 16 - 0
src/sema/functions.rs

@@ -840,6 +840,14 @@ pub fn resolve_params(
                         success = false;
                     }
 
+                    if !ty.fits_in_memory(ns) {
+                        diagnostics.push(Diagnostic::error(
+                            p.ty.loc(),
+                            String::from("type is too large to fit into memory"),
+                        ));
+                        success = false;
+                    }
+
                     ty
                 };
 
@@ -946,6 +954,14 @@ pub fn resolve_returns(
                                 success = false;
                             }
 
+                            if !ty.fits_in_memory(ns) {
+                                diagnostics.push(Diagnostic::error(
+                                    r.ty.loc(),
+                                    String::from("type is too large to fit into memory"),
+                                ));
+                                success = false;
+                            }
+
                             ty
                         }
                     }

+ 2 - 3
src/sema/statements.rs

@@ -6,7 +6,6 @@ use super::expression::{
 };
 use super::symtable::{LoopScopes, Symtable};
 use crate::parser::pt;
-use num_bigint::BigInt;
 use std::collections::HashMap;
 
 pub fn resolve_function_body(
@@ -1395,10 +1394,10 @@ fn resolve_var_decl_ty(
         return Err(());
     }
 
-    if !var_ty.is_contract_storage() && var_ty.size_of(ns) > BigInt::from(1024 * 1024) {
+    if !var_ty.is_contract_storage() && !var_ty.fits_in_memory(ns) {
         diagnostics.push(Diagnostic::error(
             ty.loc(),
-            "type to large to fit into memory".to_string(),
+            "type is too large to fit into memory".to_string(),
         ));
         return Err(());
     }

+ 5 - 0
src/sema/types.rs

@@ -893,6 +893,11 @@ impl Type {
         }
     }
 
+    /// Does this type fit into memory
+    pub fn fits_in_memory(&self, ns: &Namespace) -> bool {
+        self.size_of(ns) < BigInt::from(u16::MAX)
+    }
+
     /// Calculate the alignment
     pub fn align_of(&self, ns: &Namespace) -> usize {
         match self {

+ 44 - 0
tests/substrate_tests/variables.rs

@@ -1,6 +1,50 @@
 use crate::{build_solidity, first_error, parse_and_resolve};
 use solang::Target;
 
+#[test]
+fn variable_size() {
+    let ns = parse_and_resolve(
+        "contract x {
+            function foo(int[12131231313213] memory y) public {}
+        }
+        ",
+        Target::Substrate,
+    );
+
+    assert_eq!(
+        first_error(ns.diagnostics),
+        "type is too large to fit into memory"
+    );
+
+    let ns = parse_and_resolve(
+        "contract x {
+            function foo() public returns (int[12131231313213] memory y) {}
+        }
+        ",
+        Target::Substrate,
+    );
+
+    assert_eq!(
+        first_error(ns.diagnostics),
+        "type is too large to fit into memory"
+    );
+
+    let ns = parse_and_resolve(
+        "contract x {
+            function foo() public {
+                int[64*1024] memory y;
+            }
+        }
+        ",
+        Target::Substrate,
+    );
+
+    assert_eq!(
+        first_error(ns.diagnostics),
+        "type is too large to fit into memory"
+    );
+}
+
 #[test]
 fn test_variable_errors() {
     let ns = parse_and_resolve(