fix: keep the concrete type in the set-members fingerprint marker

The 6d370a4 determinism rewrite collapsed the set-value marker from
f'{type(value).__name__}:members' to a bare '\x00set:members', so a set value and a
frozenset value with the same members fingerprinted identically - a fix-introduced
collision that contradicts the same commit's collision-resistance claim. Restore the
concrete type in the marker (keeping the \x00 prefix so it stays uncollidable with a
user string key). Determinism across processes is unaffected.

Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
2026-07-06 20:10:32 -04:00
parent 6d370a45e1
commit 4b9820b18e
+3 -1
View File
@@ -681,7 +681,9 @@ def _fingerprint_normalize(value: Any) -> Any:
if isinstance(value, (set, frozenset)): if isinstance(value, (set, frozenset)):
members = [_fingerprint_normalize(item) for item in value] members = [_fingerprint_normalize(item) for item in value]
members.sort(key=lambda item: json.dumps(item, sort_keys=True, default=_fingerprint_default)) members.sort(key=lambda item: json.dumps(item, sort_keys=True, default=_fingerprint_default))
return {"\x00set:members": members} # keep the concrete type in the marker so a set value and a frozenset value with the
# same members stay distinct; the \x00 prefix keeps it uncollidable with a user str key
return {f"\x00{type(value).__name__}:members": members}
if isinstance(value, (list, tuple)): if isinstance(value, (list, tuple)):
return [_fingerprint_normalize(item) for item in value] return [_fingerprint_normalize(item) for item in value]
return value return value