Skip to content

CExtKey::Unserialize and CExtPubKey::Unserialize throw std::runtime_error instead of the expected std::ios_base::failure #17130

@practicalswift

Description

@practicalswift

CExtKey::Unserialize(...) and CExtPubKey::Unserialize(...) throw std::runtime_error instead of the expected std::ios_base::failure.

Context (taken from an e-mail):

When fuzzing some deserialization code I noticed that CExtKey::Unserialize(...) and CExtPubKey::Unserialize(...) throw std::runtime_error instead of the std::ios_base::failure I expected in case of deserialization errors.

I saw that this code was written by you originally: do you remember if there was a particular reason to go with std::runtime_error instead of std::ios_base::failure? If not, do you think it would be safe to change it? :)

Code:

bitcoin/src/key.h

Lines 174 to 183 in 376638a

template <typename Stream>
void Unserialize(Stream& s)
{
unsigned int len = ::ReadCompactSize(s);
unsigned char code[BIP32_EXTKEY_SIZE];
if (len != BIP32_EXTKEY_SIZE)
throw std::runtime_error("Invalid extended key size\n");
s.read((char *)&code[0], len);
Decode(code);
}

bitcoin/src/pubkey.h

Lines 240 to 249 in 78dae8c

template <typename Stream>
void Unserialize(Stream& s)
{
unsigned int len = ::ReadCompactSize(s);
unsigned char code[BIP32_EXTKEY_SIZE];
if (len != BIP32_EXTKEY_SIZE)
throw std::runtime_error("Invalid extended key size\n");
s.read((char *)&code[0], len);
Decode(code);
}

FWIW the code paths in question are reachable by the fuzzers added in PR #17051 ("tests: Add deserialization fuzzing harnesses").

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions