Prepare 3.6.0: new APIs, small fixes, compacted changelog, version bump#12
Merged
Conversation
…hrowing
`isEqual` decodes a `String` argument as hexadecimal via `fromHex`, which throws
a `FormatException` on malformed input. The dartdoc promises `false` for
unsupported input and the method is meant to be safe for comparing digests and
MACs against untrusted data, so `isEqual("zz")` throwing was a contract
violation. Catch the `FormatException` and return `false`.
Adds a regression test covering non-hex, odd-length, and trailing-non-hex
strings.
Rename the unreleased section to `3.6.0` (a minor: it adds the exported `ByteEncoder`/`ByteDecoder`/`AlphabetEncoder`/`AlphabetDecoder` base classes) and flag the two incompatible changes under `**Breaking Changes**`: the `CipherlibConverter` -> `BitConverter` rename and the `BigIntDecoder` typedef narrowing. Drop internal/tooling-only bullets (benchmark files, harness tweak, test additions, file moves, dartdoc, param-type tightening) that do not belong in a user-facing changelog. Bump `pubspec.yaml` to 3.6.0 to match the heading.
dipu-bd
force-pushed
the
claude/isequal-and-docs
branch
from
July 22, 2026 16:18
51d6c85 to
d10e11b
Compare
Add `toHexBytes`, `toBinaryBytes`, `toOctalBytes`, `toBase32Bytes`, and `toBase64Bytes` returning the encoded ASCII output as a `Uint8List` without the intermediate `String`; the existing `to<X>` functions now delegate to them so output is unchanged. Add `tryFromHex`, `tryFromBinary`, `tryFromOctal`, `tryFromBase32`, `tryFromBase64`, `tryFromUtf8`, and `tryFromBigInt`, which return `null` instead of throwing a `FormatException` on invalid input.
- `CryptData ==` now treats a null and an empty `params` map as equal (both encode to the same string and already share a hashCode). - Clarify the crypt decoder dartdoc on how bcrypt / Modular Crypt Format strings map onto the PHC salt/hash fields. - Reword the decode `FormatException` from `Invalid length` to `Invalid length or non-zero trailing bits`, which also covers a valid-length input whose trailing padding bits are non-zero. - Document that the generic `BitEncoder`/`BitDecoder` require `target <= 8` because the regrouped words are returned in a byte list.
dipu-bd
commented
Jul 22, 2026
dipu-bd
commented
Jul 22, 2026
dipu-bd
commented
Jul 22, 2026
dipu-bd
commented
Jul 22, 2026
dipu-bd
commented
Jul 22, 2026
dipu-bd
commented
Jul 22, 2026
dipu-bd
commented
Jul 22, 2026
dipu-bd
commented
Jul 22, 2026
Per review: an extra function call on the hot encode path is costly in Dart. The `to<X>Bytes` variants keep their own implementation; output is unchanged.
Per review: the String branch now decodes via `tryFromHex` (null on invalid), and the `Iterable<int>` branch delegates to `constantTimeEquals`. Also drop the `identical` shortcut in `constantTimeEquals` so the length check is its only early return, which branches on the public length, not the contents.
dipu-bd
commented
Jul 22, 2026
Codecov Report✅ All modified and coverable lines are covered by tests.
|
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.
Completes the
3.6.0release on top ofmaster(after #11 merged). Verified:dart analyze --fatal-infosclean (incl.public_member_api_docs→ 100% dartdoc),dart testgreen on vm and node (663 / 658), integration smoke test OK, 100% line coverage onlib/(943/943).New API (additive)
constantTimeEquals(a, b)— top-level constant-time byte compare, sohashlib/cipherlibcan verify MACs on rawList<int>without wrapping in aByteCollector.toHexBytes/toBinaryBytes/toOctalBytes/toBase32Bytes/toBase64Bytes— return the encoded ASCII output as aUint8List, skipping theString. Theto<X>functions delegate to these, so their output is unchanged.tryFromHex/tryFromBinary/tryFromOctal/tryFromBase32/tryFromBase64/tryFromUtf8/tryFromBigInt— non-throwing decoders returningnullon invalid input.Fixes
ByteCollector.isEqualreturnsfalsefor an invalid-hexStringinstead of throwing (contract violation on a security-sensitive path).CryptData ==treats a null and an emptyparamsmap as equal (they encode identically and already shared a hashCode).Invalid length→Invalid length or non-zero trailing bits(also covers valid-length input with non-zero padding bits).target <= 8limit on the exportedBitEncoder/BitDecoder.Release prep
3.6.0(minor: adds exported base classes).pubspec.yamlbumped to match the changelog heading.**Breaking Changes**:CipherlibConverter→BitConverterand theBigIntDecodertypedef narrowing.AGENTS.md: PR bodies omit the "Generated with Claude Code" footer.Not done here (your call): tagging
v3.6.0and publishing. Merge this, then tag master.API-hygiene note (unchanged)
CipherlibConverter/BitConverterhas now been renamed twice while exported — decide whether these converter base classes are public API or should stop being exported.