@@ -460,3 +460,129 @@ pub fn evaluate_define(
460460 Ok ( DefineResult :: NoDefine )
461461 }
462462}
463+
464+ #[ cfg( test) ]
465+ mod test {
466+ use clarity_types:: errors:: CheckErrorKind ;
467+ use clarity_types:: representations:: SymbolicExpression ;
468+ use clarity_types:: types:: QualifiedContractIdentifier ;
469+ use clarity_types:: { Value , VmExecutionError } ;
470+ use stacks_common:: consts:: CHAIN_ID_TESTNET ;
471+ use stacks_common:: types:: StacksEpochId ;
472+
473+ use crate :: vm:: analysis:: type_checker:: v2_1:: MAX_FUNCTION_PARAMETERS ;
474+ use crate :: vm:: callables:: DefineType ;
475+ use crate :: vm:: contexts:: GlobalContext ;
476+ use crate :: vm:: costs:: LimitedCostTracker ;
477+ use crate :: vm:: database:: MemoryBackingStore ;
478+ use crate :: vm:: functions:: define:: { handle_define_function, handle_define_trait} ;
479+ use crate :: vm:: tests:: test_clarity_versions;
480+ use crate :: vm:: { CallStack , ClarityVersion , ContractContext , Environment , LocalContext } ;
481+
482+ #[ apply( test_clarity_versions) ]
483+ fn bad_syntax_binding_define_function (
484+ #[ case] version : ClarityVersion ,
485+ #[ case] epoch : StacksEpochId ,
486+ ) {
487+ // ---- BAD SIGNATURE ----
488+ // Instead of ((x uint)), we pass (x)
489+ let bad_signature = vec ! [
490+ SymbolicExpression :: atom( "f" . into( ) ) ,
491+ SymbolicExpression :: atom( "x" . into( ) ) , // NOT a (name type) list
492+ ] ;
493+
494+ let body = SymbolicExpression :: atom_value ( Value :: UInt ( 1 ) ) ;
495+
496+ let mut marf = MemoryBackingStore :: new ( ) ;
497+ let mut global_context = GlobalContext :: new (
498+ false ,
499+ CHAIN_ID_TESTNET ,
500+ marf. as_clarity_db ( ) ,
501+ LimitedCostTracker :: new_free ( ) ,
502+ epoch,
503+ ) ;
504+
505+ let contract_context =
506+ ContractContext :: new ( QualifiedContractIdentifier :: transient ( ) , version) ;
507+
508+ let context = LocalContext :: new ( ) ;
509+ let mut call_stack = CallStack :: new ( ) ;
510+
511+ let mut env = Environment :: new (
512+ & mut global_context,
513+ & contract_context,
514+ & mut call_stack,
515+ None ,
516+ None ,
517+ None ,
518+ ) ;
519+
520+ let result = handle_define_function ( & bad_signature, & body, & mut env, DefineType :: Public ) ;
521+
522+ assert ! ( matches!(
523+ result,
524+ Err ( VmExecutionError :: Unchecked (
525+ CheckErrorKind :: BadSyntaxBinding ( _)
526+ ) )
527+ ) ) ;
528+ }
529+
530+ #[ apply( test_clarity_versions) ]
531+ fn handle_define_trait_too_many_function_parameters (
532+ #[ case] version : ClarityVersion ,
533+ #[ case] epoch : StacksEpochId ,
534+ ) {
535+ if epoch < StacksEpochId :: Epoch33 {
536+ return ;
537+ }
538+ // Build a trait method with MORE than MAX_FUNCTION_PARAMETERS arguments
539+ // (f (uint uint uint ... ) (response uint uint))
540+ let too_many_args =
541+ vec ! [ SymbolicExpression :: atom( "uint" . into( ) ) ; MAX_FUNCTION_PARAMETERS + 1 ] ;
542+
543+ let method = SymbolicExpression :: list ( vec ! [
544+ SymbolicExpression :: atom( "f" . into( ) ) ,
545+ SymbolicExpression :: list( too_many_args) ,
546+ SymbolicExpression :: list( vec![
547+ SymbolicExpression :: atom( "response" . into( ) ) ,
548+ SymbolicExpression :: atom( "uint" . into( ) ) ,
549+ SymbolicExpression :: atom( "uint" . into( ) ) ,
550+ ] ) ,
551+ ] ) ;
552+
553+ // This is the `( (f (...) (response ...)) )` wrapper
554+ let trait_body = vec ! [ SymbolicExpression :: list( vec![ method] ) ] ;
555+
556+ let mut marf = MemoryBackingStore :: new ( ) ;
557+ let mut global_context = GlobalContext :: new (
558+ false ,
559+ CHAIN_ID_TESTNET ,
560+ marf. as_clarity_db ( ) ,
561+ LimitedCostTracker :: new_free ( ) ,
562+ epoch,
563+ ) ;
564+
565+ let contract_context =
566+ ContractContext :: new ( QualifiedContractIdentifier :: transient ( ) , version) ;
567+
568+ let mut call_stack = CallStack :: new ( ) ;
569+
570+ let mut env = Environment :: new (
571+ & mut global_context,
572+ & contract_context,
573+ & mut call_stack,
574+ None ,
575+ None ,
576+ None ,
577+ ) ;
578+
579+ let result = handle_define_trait ( & "bad-trait" . into ( ) , & trait_body, & mut env) ;
580+
581+ assert ! ( matches!(
582+ result,
583+ Err ( VmExecutionError :: Unchecked (
584+ CheckErrorKind :: TooManyFunctionParameters ( found, max)
585+ ) )
586+ ) ) ;
587+ }
588+ }
0 commit comments