Skip to content

FIX: preserve content and word boundaries in NatoConverter - #2399

Merged
Roman Lutz (romanlutz) merged 3 commits into
microsoft:mainfrom
feiiiiii5:fix/nato-preserve-unmapped-chars
Aug 14, 2026
Merged

FIX: preserve content and word boundaries in NatoConverter#2399
Roman Lutz (romanlutz) merged 3 commits into
microsoft:mainfrom
feiiiiii5:fix/nato-preserve-unmapped-chars

Conversation

@feiiiiii5

@feiiiiii5 fei (feiiiiii5) commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Root Cause

NatoConverter uppercased the entire prompt and retained only characters present in its A-Z map. This silently deleted digits, punctuation, Unicode, and spaces. As a result:

  • "123!@#" became an empty prompt.
  • "HI THERE" and "HITHERE" produced identical output because word boundaries disappeared.
  • A passthrough implementation based on text.upper() would also mutate or expand unmapped Unicode such as é, ß, and ı.

That changes prompt semantics and is inconsistent with the prompt-fidelity behavior of sibling converters.

Fix

Refactor NatoConverter to inherit from the existing WordLevelConverter abstraction:

  • Implement NATO encoding in convert_word_async.
  • Convert only ASCII letters; preserve digits, punctuation, and unmapped Unicode with their original value and casing.
  • Join source words with an explicit <space> token so word boundaries remain distinguishable from the spaces between NATO code words.
  • Reuse shared input validation and word-selection strategies.

Examples:

  • "Hello, world!""Hotel Echo Lima Lima Oscar , <space> Whiskey Oscar Romeo Lima Delta !"
  • "123!@#""1 2 3 ! @ #"
  • "HI THERE""Hotel India <space> Tango Hotel Echo Romeo Echo", distinct from "HITHERE"
  • Unmapped Unicode such as é, ß, ı, and ñ remains unchanged.

Tests

Coverage includes letters and casing, digits, punctuation, empty and space-only prompts, Unicode passthrough, explicit word boundaries, word-selection strategies, and unsupported input types.

Targeted converter suites pass: 32 tests. Ruff formatting/linting and repository commit hooks also pass.

Diff Scope

Two files: pyrit/converter/nato_converter.py and tests/unit/converter/test_nato_converter.py.

AI Disclosure

The bug analysis and implementation were AI-assisted, then reviewed and validated against the converter contracts and targeted test suites.

Closes #2398

Non-alphabetic characters (digits, punctuation) are now passed through
unchanged instead of being silently erased, so an encoded prompt keeps
its full content and non-empty input never converts to an empty string.
Matches the passthrough behavior of Arabizi/Atbash and the fidelity fix
for BrailleConverter (microsoft#2309). Regression tests updated for digits,
punctuation, and no-letters input.

Signed-off-by: fei <204683769+feiiiiii5@users.noreply.github.com>
Refactor NatoConverter onto WordLevelConverter, represent source spaces explicitly, and preserve unmapped Unicode without case expansion.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: c9450170-29e5-4918-b1bc-71f6d9f46402
@romanlutz Roman Lutz (romanlutz) changed the title FIX: preserve unmapped characters in NatoConverter FIX: preserve content and word boundaries in NatoConverter Aug 14, 2026
@romanlutz
Roman Lutz (romanlutz) added this pull request to the merge queue Aug 14, 2026
Merged via the queue into microsoft:main with commit 3b068a4 Aug 14, 2026
54 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: NatoConverter silently erases non-alphabetic characters, altering prompt semantics

3 participants