bip158: reject malformed filter counts
What changed, and why it matters
This change fixes how a Bitcoin-related Rust library reads compact-size numbers in BIP158 compact block filters. Previously, if the encoded element count was malformed, the code silently treated it as zero, making the filter look empty. Now it returns an error instead. This could have let an attacker or buggy peer make a node believe a filter contained no matches when in fact the data was just corrupt.
Upgrade to a version containing this commit if your application processes untrusted BIP158 compact block filters. Verify downstream code handles Error::InvalidCompactSize correctly, since previously silent empty-filter behavior now raises errors.
Security signals we found
silent error handling replaced with explicit error propagation
malformed input previously treated as empty data set
BIP158 GCS filter parsing change
network-facing deserialization logic
Evidence from the diff
In bitcoin/src/bip158.rs, two GcsFilterReader methods (match_any and match_all) previously called reader.read_compact_size().unwrap_or(0). A malformed or truncated CompactSize was therefore swallowed and interpreted as an empty filter (n_elements = 0), causing both mapping and matching loops to short-circuit. The patch propagates the decode error via map_err(Error::InvalidCompactSize), so callers can distinguish empty filters from malformed input.
Changed components
bitcoin/src/bip158.rsGcsFilterReader::match_anyGcsFilterReader::match_allCompactSize decoding in BIP158 filter readerInspect captured patch +2 / −2
diff --git a/bitcoin/src/bip158.rs b/bitcoin/src/bip158.rs
index 67ef3340..6c855945 100644
--- a/bitcoin/src/bip158.rs
+++ b/bitcoin/src/bip158.rs
@@ -222,7 +222,7 @@ impl GcsFilterReader {
I::Item: Borrow<[u8]>,
R: BufRead + ?Sized,
{
- let n_elements = reader.read_compact_size().unwrap_or(0);
+ let n_elements = reader.read_compact_size().map_err(Error::InvalidCompactSize)?;
// map hashes to [0, n_elements << grp]
let nm = n_elements * self.m;
let mut mapped =
@@ -265,7 +265,7 @@ impl GcsFilterReader {
I::Item: Borrow<[u8]>,
R: BufRead + ?Sized,
{
- let n_elements = reader.read_compact_size().unwrap_or(0);
+ let n_elements = reader.read_compact_size().map_err(Error::InvalidCompactSize)?;
// map hashes to [0, n_elements << grp]
let nm = n_elements * self.m;
let mut mapped =
Why this scored 48/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.