Repository navigation
Fix bugs from the third bug hunt: CSV, look-alike letters, ranks, old mappings, API - #92
Merged
Merged
Conversation
A fuzzer for tables and CSV, numbered lists, Latin look-alike letters, double first names and documents with dozens of people repeated in several cases, plus large-document runs (up to 8000 lines), found these. Each has a test in tests/test_fuzz_findings3.py. Left unmasked: - CSV cells: a ';' glued to the next word separates cells like '|'; a glued comma reads as ', '. - Latin look-alike letters inside names are read as Cyrillic when names and patronymics are analysed, so the mask is never the real name and the role of each word is found. - Ranks with 'запасу'/'резерву' and the dative in '-ові' (a new form, rank_data.RANK_DATIVE_OVI, with masks that have it too). - A multi-word rank right after another rank (lines joined for parsing) is the person's rank, not a surname. Unmasking: - Occurrences are numbered regardless of the mask's letter case; new mappings carry "instance_case": "insensitive", older ones are read as before. - The case of double names and surnames is restored part by part from the text. - A rank's mask skips every rank that stays open in the document, not only the neighbours two steps away; when none is free, the rank stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XT6iUWaQgahXDB9TWX9Bq7 Generated-With: Claude Code 2.1.42
Found by an audit of the extras API, the compatibility module and old mapping formats; each has a test in tests/test_api_findings.py. Older mappings: - Entries without instances (v2.0) restore every occurrence of their mask (ANY_INSTANCE); v2.0 ranks are restored; a mapping without "version" is classified by structure; v1 mappings are restored in one whole-word pass. Masks: - Case forms of one surname in a document share a synthetic stem: a form reuses the stem of another form already masked (surname.paradigm_mask), with endings matched to the new stem; -ин/-ін families cover the instrumental and dative; bare consonant-final surnames prefer consonant-final masks. - Surname masks use the ASCII apostrophe, so cp1251 documents save. API and CLI: - data_masking: MASK_NAMES/MASK_DATES/MASK_ORDERS also set the derived flags; apply_filter_to_globals on the shim's dict sets the engine flags. - tools: name and patronymic gender defaults to detection; empty name. - generate_password guarantees each class; length < 1 is an error. - MappingChain forward mapping, ChainUnmasker without "pass" numbers, passes setter and from_dict copying. - An empty --only/--exclude list is an error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XT6iUWaQgahXDB9TWX9Bq7 Generated-With: Claude Code 2.1.42
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.
Third bug hunt. It had two parts:
extrasAPI, the compatibility module and the old mapping formats.All entries are in
CHANGELOG.mdunder[Unreleased].Data left unmasked
;glued to the next word now separates cells like|. Before, the patronymic inПетренко Іван Петрович;сержант;1234567890stayed open. A comma glued to the next word reads as,.Ярoслав): the mask could be the real name, and a nearby surname stayed open. Names are now analysed with such letters read as Cyrillic.запасу/резервуand dative ranks in-ові(майорові,солдатові) are now recognised. The-овіform is a new rank form,rank_data.RANK_DATIVE_OVI, and the mask also has it.… капітаном/СТАРШИЙ ЛЕЙТЕНАНТ …on joined lines) had its first word masked as a surname.Unmasking did not restore the original
ГОРДІЇВНИ/Гордіївни) left an occurrence unrestored. New mappings carry"instance_case": "insensitive"; older ones are read as before.ДОРОШЕНКО-ҐУДЗЬcame back in capitals in ordinary lines, andАнна-Маріяcame back asАнна-марія.instancesnow restore every occurrence of their mask; before, they restored nothing.versionis classified by structure.Masks
Коваль/Коваля/Ковалем→Ковар/Коваря/Коварем, as CLAUDE.md promises. Before, each case form got a different stem.ʼmade the save fail.API and command line
data_masking: the general flags (MASK_NAMES,MASK_DATES,MASK_ORDERS) now also set the flags derived from them, andapply_filter_to_globalson the module's dict now works.tools: name and patronymic gender is detected from the value, not assumed male.generate_passwordnow guarantees every character class.MappingChain/ChainUnmasker:"pass"number now work;passessetter keeps the pass count;from_dictnow copies its input.--onlyor--excludelist is an error (exit code 2).Tests
tests/test_fuzz_findings3.py: 40 tests; it does not import onmain(new API).tests/test_api_findings.py: 35 tests; 33 fail on the previous commit.test_rank_data: a new case name;test_unmask: a v2.0 entry without instances now restores.--re-maskchains: 0 failures in 250.Generated by Claude Code