fix: bound the Duplicate Files minimum-size box so it cannot invert its filter - #1926
Merged
Merged
Conversation
…ts filter The scan keeps a file when `fi.Length >= minSizeBytes`, where minSizeBytes is the user's "minimum size (KB)" figure times 1024. The TextBox binds a long and imposes no bounds, so two typed values produced a NEGATIVE threshold: * a stray leading minus, and * any value above long.MaxValue / 1024, which overflows when scaled. Every file is larger than a negative size, so `fi.Length < minSizeBytes` skipped nothing: "only files above X" silently became "scan and hash every file in the folder" — the opposite of the request, and much slower. The KB→bytes conversion moved into a pure MinBytesFor(long) that clamps to [0, MaxMinSizeKb] before scaling, so the threshold can never go negative by either route. Not clamped in the setter on purpose: the box uses UpdateSourceTrigger=PropertyChanged, so rewriting on every keystroke would fight the caret; the bound belongs where the value is used. Found while triaging the pure-echo test MinSizeKb_CanBeChanged (batch 94), whose only "assertion" was a setter round-trip — it could never have caught this. Red proof: 4 mutations. Dropping the clamp reddens both the negative and the overflow test; a lower-bound-only and an upper-bound-only variant each redden exactly one, proving neither half is redundant; and pushing MaxMinSizeKb one past the real limit fails to COMPILE (CS0220 on the test's constant expression), so the boundary itself cannot drift silently.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What a user sees
Open Duplicate Files, type a stray
-(or a very large number) into "minimum size (KB)", andScan. Instead of finding only large duplicates it grinds through — and hashes — every file in the
folder. The one control meant to make the scan cheaper makes it maximally expensive, silently.
The defect
The scan keeps a file when it is at least the requested size:
and
minSizeByteswasMinSizeKb * 1024, straight from along-bound TextBox with no limits of itsown. Two typed values make that product negative:
-1→-1024;long.MaxValue / 1024— the multiply overflows and wraps negative.Every real file length is
≥ 0 > negative, so the skip never fires: "only files above X" becomes"every file in the folder". Nothing throws; the scan just does the opposite of what was asked, slowly.
The fix
The KB→bytes conversion moves into a pure, bounded helper:
so the threshold can never be negative by either route.
Deliberately not clamped in the setter. The box uses
UpdateSourceTrigger=PropertyChanged, sorewriting the value on every keystroke would fight the caret (type
-, then a digit, and the fieldwould jump out from under you). The bound belongs where the value is used, not where it is typed —
the same reasoning the codebase already applies to live-updating inputs.
Found while triaging the pure-echo test
MinSizeKb_CanBeChangedin batch 94, whose only "assertion"set the property and read it back — it could never have caught this.
Verification
Red proof: 4 mutations, the touched source file restored byte-for-byte.
Math.Max)Math.Min)MaxMinSizeKbone past the real limitMaxMinSizeKb * 1024, which overflows at compile time — so the boundary itself cannot drift silentlyThat last one is a stronger guard than a runtime assertion: an off-by-one in the limit is rejected by
the compiler, not merely by a failing test. The three runtime tests are
[Theory]rows coveringordinary values (unchanged behaviour), negatives (
-1,-5000,long.MinValue), and the exactoverflow boundary.
Other checks: all four projects build 0 errors / 0 warnings;
dotnet format --verify-no-changesexit 0on both; author headers intact; leak scan over all 32 terms gives 0 hits.
fix:→ patch release(1.65.19).