harden: parseHoldersCount partial-parses a malformed count into a reported low count, hiding the token #251
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Three findings from the independent review of #244, all non-blocking there and filed rather than dropped.
1. The parse contract is overstated, and the gap hides tokens
src/shared/holders.js:13-18says "Anything unparseable is unknown too".parseIntpartial-parses instead:"1,000"→1"0x10"→0"1e3"→1A malformed count that merely starts with a digit becomes a reported low count, which triggers exactly the hide that #230 exists to prevent — and it does so on the confident path, not the unknown path, so the new
holders !== nullprotection never sees it.Not a live bug today: this is the same
parseIntas before the change, and Blockscout emits plain decimal strings. It is a latent one, and the comment currently promises a guarantee the code does not provide. Either make the parse total (reject anything that is not wholly a decimal integer, yieldingnull) or correct the comment to state whatparseIntactually does. The first is better — "unparseable means unknown" is the rule the rest of the module is built on.2. An inert guard
src/shared/balances.js:87—holders !== null &&is dead.null >= 1000is alreadyfalse, so removing the clause survives all 388 tests. Either drop it or make it load-bearing; as written it reads as a protection that is doing nothing.3. Undocumented behaviour, same drift class as #239
README.md:1223-1263anddocs/README.md:344-347enumerate each filter's reach in detail and say nothing about how an unknown holder count is treated — even though the treatment now deliberately differs between the history filter, the Send selector and the balance-list spam gate. Not falsified (an unknown count is not "fewer than 1,000"), but this is precisely the documentation drift #239 was filed for.Also worth recording while in here: the review noted
src/popup/views/addressToken.js:189now omits the "Holders:" row rather than showing a false "Holders: 0". That is an improvement and was an undisclosed side effect of #244; it should be documented rather than reverted.Definition of done
holders_countthat is not wholly a decimal integer yieldsnull, not a partial parse. Tests cover"1,000","0x10","1e3"and a trailing-garbage case.src/shared/holders.jsmatches what the code does.src/shared/balances.js:87is either removed or made load-bearing, with a test either way.README.mdanddocs/README.mdstate how an unknown holder count is treated in each of the three filters.TODO.mdupdated in the same commit.make checkpasses.Add to the documentation item: the
README.mdsource-tree listing omitssrc/shared/holders.jsentirely. Found while landing #257, which added its own new module to that listing rather than fixing the neighbouring gap.