fix(blocking): resolve LID/PN before is_blocked compares, fixing PN-query false negatives - #707
Conversation
block()/unblock() store blocks keyed by LID, so GetBlocklist returns LID-keyed entries. is_blocked compared the raw input .user with no resolution, so a PN-input query never matched a LID-keyed block and returned a false negative. Resolve the queried JID to its LID/PN pair (same mapping block() uses) and match each entry against the raw user plus the resolved LID and PN, via a pure blocklist_contains() helper so the resolution is unit-testable.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe blocklist matching logic now resolves phone-number→LID mappings and builds multiple candidate user identifiers from the queried JID before checking blocklist membership; a new blocklist_contains helper matches entries against those candidates. Tests cover PN→LID resolution, direct LID matching, and non-matches. ChangesBlocklist Resolution Enhancement
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6b7b11c5eb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Benchmark Results67 unchanged benchmark(s)
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/features/blocking.rs`:
- Around line 93-97: The candidate users Vec is built with possible duplicates
because bare.user can equal mapping.as_ref().lid or .phone_number; update the
logic around where users is constructed (the block that currently pushes
entry.lid and entry.phone_number) to only push each resolved value if it is not
equal to bare.user and not already present in users (or replace the push logic
with a small dedup step like building users then calling dedup or using a
HashSet). Specifically modify the code that references mapping and entry
(entry.lid, entry.phone_number) so you skip adding duplicate strings before the
blocklist check.
- Line 92: Replace the .ok().flatten() swallow with proper error propagation:
call self.client.get_lid_pn_entry(&bare).await and use the ? operator to
propagate Err variants (so infrastructure/back-end errors return Err from the
current function), then handle the returned Option normally (None is acceptable
and means "no mapping"). In short, change the mapping resolution at the call
site (self.client.get_lid_pn_entry) to propagate errors instead of ignoring them
and only treat the resulting Option::None as a non-error fallback.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 20fbbccd-e382-4b58-b615-b713a62aa46c
📒 Files selected for processing (1)
src/features/blocking.rs
Swallowing the resolution error with .ok().flatten() would fall back to the raw user and re-introduce the false negative this PR fixes when the backend is failing. Propagate Err; only Ok(None) (genuine absence) falls back to the raw user.
Problem
block()/unblock()always resolve the input JID to a LID before sending (resolve_lid_pn), so modern WhatsApp stores blocks keyed by LID andGetBlocklistreturns<item jid=...@lid>entries whose.useris the LID number. Butis_blockedcomparedentry.jid.user == jid.useragainst the caller's JID verbatim, with no LID/PN resolution. If the caller passes a PN JID (the natural input for a phone-number contact),jid.useris the phone number, which never equals the stored LID's user, sois_blockedreturnsfalseeven when the contact is blocked: a silent false negative.WA Web keeps the blocklist keyed by LID (
WAWebBlocklistCollection, membership byid) and normalizes membership tests to LID first.Fix
Resolve the queried JID to its LID/PN pair (the same
get_lid_pn_entrymappingblock()/unblock()use) and match each blocklist entry against the raw user plus the resolved LID and PN. Falls back to the raw user alone when no mapping exists, so a LID query keeps working and the behavior only improves for PN input.The match itself is a small pure helper
blocklist_contains(&[BlocklistEntry], &[&str]), so the LID/PN-resolution semantics are unit-testable without a server.Tests
New
pn_query_matches_lid_keyed_block_only_when_resolved: a LID-keyed block is found when the candidate set includes the resolved LID, missed when only the raw PN is given (the old bug), matched directly for a LID query, and an unrelated contact is not blocked.Breaking
None.
is_blockedkeeps its signature; PN-input queries now resolve correctly, LID-input queries are unchanged.