From d8a39c4459682e60a3c6dbd18b301678cb520caf Mon Sep 17 00:00:00 2001 From: Ferdinando Ametrano Date: Mon, 7 Sep 2026 20:42:48 +0200 Subject: [PATCH] descriptor: fix two parse-error messages and cover them with tests The bare-multisig error prints a literal "{}" because its .format() call is missing. The wpkh branch reports "More than one pubkey in pkh descriptor", copied from the pkh branch. Add unit tests for both error paths: a wpkh() with two pubkeys, and a top-level bare multisig with four pubkeys whose message must report the count. --- hwilib/descriptor.py | 4 ++-- test/test_descriptor.py | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/hwilib/descriptor.py b/hwilib/descriptor.py index 1373ad2d2..04aa7e4a7 100644 --- a/hwilib/descriptor.py +++ b/hwilib/descriptor.py @@ -673,14 +673,14 @@ def _parse_descriptor(desc: str, ctx: '_ParseDescriptorContext', key_expr_index: elif thresh > len(pubkeys): raise ValueError("Multisig threshold cannot be larger than the number of keys; threshold is {} but only {} keys specified".format(thresh, len(pubkeys))) if ctx == _ParseDescriptorContext.TOP and len(pubkeys) > 3: - raise ValueError("Cannot have {} pubkeys in bare multisig: only at most 3 pubkeys") + raise ValueError("Cannot have {} pubkeys in bare multisig: only at most 3 pubkeys".format(len(pubkeys))) return MultisigDescriptor(pubkeys, thresh, is_sorted), key_expr_index if func == "wpkh": if not (ctx == _ParseDescriptorContext.TOP or ctx == _ParseDescriptorContext.P2SH): raise ValueError("Can only have wpkh() at top level or inside sh()") pubkey, expr, key_expr_index = parse_pubkey(expr, key_expr_index) if expr: - raise ValueError("More than one pubkey in pkh descriptor") + raise ValueError("More than one pubkey in wpkh descriptor") return WPKHDescriptor(pubkey), key_expr_index if func == "sh": if ctx != _ParseDescriptorContext.TOP: diff --git a/test/test_descriptor.py b/test/test_descriptor.py index dca4fbe80..a57111742 100755 --- a/test/test_descriptor.py +++ b/test/test_descriptor.py @@ -294,6 +294,20 @@ def test_invalid_multipath_descriptors(self): with self.assertRaisesRegex(ValueError, "invalid literal for int()"): parse_descriptor("wpkh(xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/<0;>/*)") + def test_wpkh_rejects_multiple_pubkeys(self): + pk1 = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" + pk2 = "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5" + with self.assertRaisesRegex(ValueError, "More than one pubkey in wpkh descriptor"): + parse_descriptor("wpkh({},{})".format(pk1, pk2)) + + def test_bare_multisig_too_many_pubkeys_reports_count(self): + pk1 = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" + pk2 = "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5" + pk3 = "02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9" + pk4 = "02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13" + with self.assertRaisesRegex(ValueError, "Cannot have 4 pubkeys in bare multisig: only at most 3 pubkeys"): + parse_descriptor("multi(1,{},{},{},{})".format(pk1, pk2, pk3, pk4)) + def test_valid_bip388_conversion(self): def check(descriptor, keys, template): d = parse_descriptor(descriptor)