@@ -700,7 +700,10 @@ NODISCARD bool ParseKeyPath(const std::vector<Span<const char>>& split, KeyPath&
700
700
hardened = true ;
701
701
}
702
702
uint32_t p;
703
- if (!ParseUInt32 (std::string (elem.begin (), elem.end ()), &p) || p > 0x7FFFFFFFUL ) {
703
+ if (!ParseUInt32 (std::string (elem.begin (), elem.end ()), &p)) {
704
+ error = strprintf (" Key path value '%s' is not a valid uint32" , std::string (elem.begin (), elem.end ()).c_str ());
705
+ return false ;
706
+ } else if (p > 0x7FFFFFFFUL ) {
704
707
error = strprintf (" Key path value %u is out of range" , p);
705
708
return false ;
706
709
}
@@ -714,17 +717,35 @@ std::unique_ptr<PubkeyProvider> ParsePubkeyInner(const Span<const char>& sp, boo
714
717
{
715
718
auto split = Split (sp, ' /' );
716
719
std::string str (split[0 ].begin (), split[0 ].end ());
720
+ if (str.size () == 0 ) {
721
+ error = " No key provided" ;
722
+ return nullptr ;
723
+ }
717
724
if (split.size () == 1 ) {
718
725
if (IsHex (str)) {
719
726
std::vector<unsigned char > data = ParseHex (str);
720
727
CPubKey pubkey (data);
721
- if (pubkey.IsFullyValid () && (permit_uncompressed || pubkey.IsCompressed ())) return MakeUnique<ConstPubkeyProvider>(pubkey);
728
+ if (pubkey.IsFullyValid ()) {
729
+ if (permit_uncompressed || pubkey.IsCompressed ()) {
730
+ return MakeUnique<ConstPubkeyProvider>(pubkey);
731
+ } else {
732
+ error = " Uncompressed keys are not allowed" ;
733
+ return nullptr ;
734
+ }
735
+ }
736
+ error = strprintf (" Pubkey '%s' is invalid" , str);
737
+ return nullptr ;
722
738
}
723
739
CKey key = DecodeSecret (str);
724
- if (key.IsValid () && (permit_uncompressed || key.IsCompressed ())) {
725
- CPubKey pubkey = key.GetPubKey ();
726
- out.keys .emplace (pubkey.GetID (), key);
727
- return MakeUnique<ConstPubkeyProvider>(pubkey);
740
+ if (key.IsValid ()) {
741
+ if (permit_uncompressed || key.IsCompressed ()) {
742
+ CPubKey pubkey = key.GetPubKey ();
743
+ out.keys .emplace (pubkey.GetID (), key);
744
+ return MakeUnique<ConstPubkeyProvider>(pubkey);
745
+ } else {
746
+ error = " Uncompressed keys are not allowed" ;
747
+ return nullptr ;
748
+ }
728
749
}
729
750
}
730
751
CExtKey extkey = DecodeExtKey (str);
@@ -760,7 +781,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkey(const Span<const char>& sp, bool per
760
781
}
761
782
if (origin_split.size () == 1 ) return ParsePubkeyInner (origin_split[0 ], permit_uncompressed, out, error);
762
783
if (origin_split[0 ].size () < 1 || origin_split[0 ][0 ] != ' [' ) {
763
- error = strprintf (" Key origin expected but not found, got '%s ' instead" , std::string ( origin_split[0 ]. begin (), origin_split [0 ]. end ()) );
784
+ error = strprintf (" Key origin start '[ character expected but not found, got '%c ' instead" , origin_split[0 ][0 ]);
764
785
return nullptr ;
765
786
}
766
787
auto slash_split = Split (origin_split[0 ].subspan (1 ), ' /' );
@@ -802,19 +823,22 @@ std::unique_ptr<DescriptorImpl> ParseScript(Span<const char>& sp, ParseScriptCon
802
823
auto pubkey = ParsePubkey (expr, true , out, error);
803
824
if (!pubkey) return nullptr ;
804
825
return MakeUnique<ComboDescriptor>(std::move (pubkey));
826
+ } else if (ctx != ParseScriptContext::TOP && Func (" combo" , expr)) {
827
+ error = " Cannot have combo in non-top level" ;
828
+ return nullptr ;
805
829
}
806
830
if (Func (" multi" , expr)) {
807
831
auto threshold = Expr (expr);
808
832
uint32_t thres;
809
833
std::vector<std::unique_ptr<PubkeyProvider>> providers;
810
834
if (!ParseUInt32 (std::string (threshold.begin (), threshold.end ()), &thres)) {
811
- error = strprintf (" multi threshold %u out of range " , thres );
835
+ error = strprintf (" Multi threshold '%s' is not valid " , std::string (threshold. begin (), threshold. end ()). c_str () );
812
836
return nullptr ;
813
837
}
814
838
size_t script_size = 0 ;
815
839
while (expr.size ()) {
816
840
if (!Const (" ," , expr)) {
817
- error = strprintf (" multi : expected ',', got '%c'" , expr[0 ]);
841
+ error = strprintf (" Multi : expected ',', got '%c'" , expr[0 ]);
818
842
return nullptr ;
819
843
}
820
844
auto arg = Expr (expr);
@@ -823,10 +847,19 @@ std::unique_ptr<DescriptorImpl> ParseScript(Span<const char>& sp, ParseScriptCon
823
847
script_size += pk->GetSize () + 1 ;
824
848
providers.emplace_back (std::move (pk));
825
849
}
826
- if (providers.size () < 1 || providers.size () > 16 || thres < 1 || thres > providers.size ()) return nullptr ;
850
+ if (providers.size () < 1 || providers.size () > 16 ) {
851
+ error = strprintf (" Cannot have %u keys in multisig; must have between 1 and 16 keys, inclusive" , providers.size ());
852
+ return nullptr ;
853
+ } else if (thres < 1 ) {
854
+ error = strprintf (" Multisig threshold cannot be %d, must be at least 1" , thres);
855
+ return nullptr ;
856
+ } else if (thres > providers.size ()) {
857
+ error = strprintf (" Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified" , thres, providers.size ());
858
+ return nullptr ;
859
+ }
827
860
if (ctx == ParseScriptContext::TOP) {
828
861
if (providers.size () > 3 ) {
829
- error = strprintf (" Cannot %u pubkeys in bare multisig; only at most 3 pubkeys" , providers.size ());
862
+ error = strprintf (" Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys" , providers.size ());
830
863
return nullptr ;
831
864
}
832
865
}
@@ -842,16 +875,25 @@ std::unique_ptr<DescriptorImpl> ParseScript(Span<const char>& sp, ParseScriptCon
842
875
auto pubkey = ParsePubkey (expr, false , out, error);
843
876
if (!pubkey) return nullptr ;
844
877
return MakeUnique<WPKHDescriptor>(std::move (pubkey));
878
+ } else if (ctx == ParseScriptContext::P2WSH && Func (" wpkh" , expr)) {
879
+ error = " Cannot have wpkh within wsh" ;
880
+ return nullptr ;
845
881
}
846
882
if (ctx == ParseScriptContext::TOP && Func (" sh" , expr)) {
847
883
auto desc = ParseScript (expr, ParseScriptContext::P2SH, out, error);
848
884
if (!desc || expr.size ()) return nullptr ;
849
885
return MakeUnique<SHDescriptor>(std::move (desc));
886
+ } else if (ctx != ParseScriptContext::TOP && Func (" sh" , expr)) {
887
+ error = " Cannot have sh in non-top level" ;
888
+ return nullptr ;
850
889
}
851
890
if (ctx != ParseScriptContext::P2WSH && Func (" wsh" , expr)) {
852
891
auto desc = ParseScript (expr, ParseScriptContext::P2WSH, out, error);
853
892
if (!desc || expr.size ()) return nullptr ;
854
893
return MakeUnique<WSHDescriptor>(std::move (desc));
894
+ } else if (ctx == ParseScriptContext::P2WSH && Func (" wsh" , expr)) {
895
+ error = " Cannot have wsh within wsh" ;
896
+ return nullptr ;
855
897
}
856
898
if (ctx == ParseScriptContext::TOP && Func (" addr" , expr)) {
857
899
CTxDestination dest = DecodeDestination (std::string (expr.begin (), expr.end ()));
@@ -870,6 +912,13 @@ std::unique_ptr<DescriptorImpl> ParseScript(Span<const char>& sp, ParseScriptCon
870
912
auto bytes = ParseHex (str);
871
913
return MakeUnique<RawDescriptor>(CScript (bytes.begin (), bytes.end ()));
872
914
}
915
+ if (ctx == ParseScriptContext::P2SH) {
916
+ error = " A function is needed within P2SH" ;
917
+ return nullptr ;
918
+ } else if (ctx == ParseScriptContext::P2WSH) {
919
+ error = " A function is needed within P2WSH" ;
920
+ return nullptr ;
921
+ }
873
922
error = strprintf (" %s is not a valid descriptor function" , std::string (expr.begin (), expr.end ()));
874
923
return nullptr ;
875
924
}
0 commit comments