@@ -137,8 +137,16 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
137137}
138138
139139impl < Ctx : ScriptContext > Miniscript < bitcoin:: PublicKey , Ctx > {
140- /// Attempt to parse a script into a Miniscript representation
141- pub fn parse ( script : & script:: Script ) -> Result < Miniscript < bitcoin:: PublicKey , Ctx > , Error > {
140+ /// Attempt to parse an insane(scripts don't clear sanity checks)
141+ /// script into a Miniscript representation.
142+ /// Use this to parse scripts with repeated pubkeys, timelock mixing, malleable
143+ /// scripts without sig or scripts that can exceed resource limits.
144+ /// Some of the analysis gurantees of miniscript are lost when dealing with
145+ /// insane scripts. In general, in a multi-party setting users should only
146+ /// accept sane scripts.
147+ pub fn parse_insane (
148+ script : & script:: Script ,
149+ ) -> Result < Miniscript < bitcoin:: PublicKey , Ctx > , Error > {
142150 let tokens = lex ( script) ?;
143151 let mut iter = TokenIter :: new ( tokens) ;
144152
@@ -154,6 +162,16 @@ impl<Ctx: ScriptContext> Miniscript<bitcoin::PublicKey, Ctx> {
154162 Ok ( top)
155163 }
156164 }
165+
166+ /// Attempt to parse a Script into Miniscript representation.
167+ /// This function will fail parsing for scripts that do not clear
168+ /// the [fn.analyzable.sanity_check] checks. Use [fn.parse_insane] to
169+ /// parse such scripts.
170+ pub fn parse ( script : & script:: Script ) -> Result < Miniscript < bitcoin:: PublicKey , Ctx > , Error > {
171+ let ms = Self :: parse_insane ( script) ?;
172+ ms. sanity_check ( ) ?;
173+ Ok ( ms)
174+ }
157175}
158176
159177impl < Pk , Ctx > Miniscript < Pk , Ctx >
@@ -399,7 +417,8 @@ mod tests {
399417 if let Some ( expected) = expected_hex. into ( ) {
400418 assert_eq ! ( format!( "{:x}" , bitcoin_script) , expected) ;
401419 }
402- let roundtrip = Segwitv0Script :: parse ( & bitcoin_script) . expect ( "parse string serialization" ) ;
420+ let roundtrip =
421+ Segwitv0Script :: parse_insane ( & bitcoin_script) . expect ( "parse string serialization" ) ;
403422 assert_eq ! ( roundtrip, script) ;
404423 }
405424
@@ -408,7 +427,7 @@ mod tests {
408427 let ser = tree. encode ( NullCtx ) ;
409428 assert_eq ! ( ser. len( ) , tree. script_size( NullCtx ) ) ;
410429 assert_eq ! ( ser. to_string( ) , s) ;
411- let deser = Segwitv0Script :: parse ( & ser) . expect ( "deserialize result of serialize" ) ;
430+ let deser = Segwitv0Script :: parse_insane ( & ser) . expect ( "deserialize result of serialize" ) ;
412431 assert_eq ! ( * tree, deser) ;
413432 }
414433
@@ -573,19 +592,19 @@ mod tests {
573592 fn verify_parse ( ) {
574593 let ms = "and_v(v:hash160(20195b5a3d650c17f0f29f91c33f8f6335193d07),or_d(sha256(96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47),older(16)))" ;
575594 let ms: Segwitv0Script = Miniscript :: from_str ( ms) . unwrap ( ) ;
576- assert_eq ! ( ms, Miniscript :: parse ( & ms. encode( NullCtx ) ) . unwrap( ) ) ;
595+ assert_eq ! ( ms, Miniscript :: parse_insane ( & ms. encode( NullCtx ) ) . unwrap( ) ) ;
577596
578597 let ms = "and_v(v:sha256(96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47),or_d(sha256(96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47),older(16)))" ;
579598 let ms: Segwitv0Script = Miniscript :: from_str ( ms) . unwrap ( ) ;
580- assert_eq ! ( ms, Miniscript :: parse ( & ms. encode( NullCtx ) ) . unwrap( ) ) ;
599+ assert_eq ! ( ms, Miniscript :: parse_insane ( & ms. encode( NullCtx ) ) . unwrap( ) ) ;
581600
582601 let ms = "and_v(v:ripemd160(20195b5a3d650c17f0f29f91c33f8f6335193d07),or_d(sha256(96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47),older(16)))" ;
583602 let ms: Segwitv0Script = Miniscript :: from_str ( ms) . unwrap ( ) ;
584- assert_eq ! ( ms, Miniscript :: parse ( & ms. encode( NullCtx ) ) . unwrap( ) ) ;
603+ assert_eq ! ( ms, Miniscript :: parse_insane ( & ms. encode( NullCtx ) ) . unwrap( ) ) ;
585604
586605 let ms = "and_v(v:hash256(96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47),or_d(sha256(96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47),older(16)))" ;
587606 let ms: Segwitv0Script = Miniscript :: from_str ( ms) . unwrap ( ) ;
588- assert_eq ! ( ms, Miniscript :: parse ( & ms. encode( NullCtx ) ) . unwrap( ) ) ;
607+ assert_eq ! ( ms, Miniscript :: parse_insane ( & ms. encode( NullCtx ) ) . unwrap( ) ) ;
589608 }
590609
591610 #[ test]
@@ -778,21 +797,21 @@ mod tests {
778797 #[ test]
779798 fn deserialize ( ) {
780799 // Most of these came from fuzzing, hence the increasing lengths
781- assert ! ( Segwitv0Script :: parse ( & hex_script( "" ) ) . is_err( ) ) ; // empty
782- assert ! ( Segwitv0Script :: parse ( & hex_script( "00" ) ) . is_ok( ) ) ; // FALSE
783- assert ! ( Segwitv0Script :: parse ( & hex_script( "51" ) ) . is_ok( ) ) ; // TRUE
784- assert ! ( Segwitv0Script :: parse ( & hex_script( "69" ) ) . is_err( ) ) ; // VERIFY
785- assert ! ( Segwitv0Script :: parse ( & hex_script( "0000" ) ) . is_err( ) ) ; //and_v(FALSE,FALSE)
786- assert ! ( Segwitv0Script :: parse ( & hex_script( "1001" ) ) . is_err( ) ) ; // incomplete push
787- assert ! ( Segwitv0Script :: parse ( & hex_script( "03990300b2" ) ) . is_err( ) ) ; // non-minimal #
788- assert ! ( Segwitv0Script :: parse ( & hex_script( "8559b2" ) ) . is_err( ) ) ; // leading bytes
789- assert ! ( Segwitv0Script :: parse ( & hex_script( "4c0169b2" ) ) . is_err( ) ) ; // non-minimal push
790- assert ! ( Segwitv0Script :: parse ( & hex_script( "0000af0000ae85" ) ) . is_err( ) ) ; // OR not BOOLOR
800+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script( "" ) ) . is_err( ) ) ; // empty
801+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script( "00" ) ) . is_ok( ) ) ; // FALSE
802+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script( "51" ) ) . is_ok( ) ) ; // TRUE
803+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script( "69" ) ) . is_err( ) ) ; // VERIFY
804+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script( "0000" ) ) . is_err( ) ) ; //and_v(FALSE,FALSE)
805+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script( "1001" ) ) . is_err( ) ) ; // incomplete push
806+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script( "03990300b2" ) ) . is_err( ) ) ; // non-minimal #
807+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script( "8559b2" ) ) . is_err( ) ) ; // leading bytes
808+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script( "4c0169b2" ) ) . is_err( ) ) ; // non-minimal push
809+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script( "0000af0000ae85" ) ) . is_err( ) ) ; // OR not BOOLOR
791810
792811 // misc fuzzer problems
793- assert ! ( Segwitv0Script :: parse ( & hex_script( "0000000000af" ) ) . is_err( ) ) ;
794- assert ! ( Segwitv0Script :: parse ( & hex_script( "04009a2970af00" ) ) . is_err( ) ) ; // giant CMS key num
795- assert ! ( Segwitv0Script :: parse ( & hex_script(
812+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script( "0000000000af" ) ) . is_err( ) ) ;
813+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script( "04009a2970af00" ) ) . is_err( ) ) ; // giant CMS key num
814+ assert ! ( Segwitv0Script :: parse_insane ( & hex_script(
796815 "2102ffffffffffffffefefefefefefefefefefef394c0fe5b711179e124008584753ac6900"
797816 ) )
798817 . is_err( ) ) ;
0 commit comments