Skip to content

Place: text files in UTF-16 without a byte-order mark place as UTF-16 - #7554

Merged
bflatastic merged 3 commits into
storytold:mainfrom
dotCooCoo:fix/place-text-utf16-no-bom
Nov 14, 2026
Merged

bflatastic merged 3 commits into
storytold:mainfrom
dotCooCoo:fix/place-text-utf16-no-bom

Conversation

@dotCooCoo

Copy link
Copy Markdown
Contributor

Builds on #7522, which adds the shared byte-order helper; until it merges, this diff also shows its commit.

What and why

File › Place of a text file with the Unicode character set read UTF-16 only after a byte-order mark. A UTF-16 file without one was read as UTF-8 or the 8-bit set, so characters outside U+0001 to U+00FF came out as other characters and each CR LF placed as two paragraph breaks.

Place now reads such a file as UTF-16 by the rule Import Data Sets uses, through #7522's utf16_order_without_mark: an even length, at least half of the two-byte units holding a NUL byte, the byte order that reads a line break (for one line, the order its NUL bytes give), and valid UTF-16 with no NUL character in that order. Any other file is read as before, as UTF-8 or else the platform's 8-bit set. This is VectorCraft's own detection rule. Files with a byte-order mark and the ANSI character set are read as before.

Docs: the file.place params text, the Place text paragraph in docs/mcp.md, and a line in docs/target-app-parity.md.

How it was tested

  • New test tests::textimport::utf16_without_a_byte_order_mark_places_by_its_nul_bytes_and_line_breaks: both byte orders with CR LF, one-line files, a one-line file with NUL bytes in both positions, and the files that fall back (odd length, an unpaired surrogate, a NUL character, line breaks in both byte orders, too few NUL bytes in UTF-8 and in Windows-1252 text, and ANSI). It fails without the change, and it also fails with the NUL-character check removed.
  • cargo test -p vectorcraft-engine --lib -- textimport datasets_csv: 39 passed.
  • cargo test -p vectorcraft-engine: 21 test binaries, 7185 passed, 0 failed, 3 ignored.
  • cargo clippy -p vectorcraft-engine --all-targets -- -D warnings: clean.
  • cargo fmt --all -- --check: the only diff is in crates/svg/src/lib.rs, which this branch does not change. Graphs: Import Data reads UTF-16 text files without a byte-order mark #7522's base predates Fix CI formatting after craft-libs cutover #7454, which formats that file on main.
  • git merge-tree with main at edb228ac33: clean.

Checklist

  • cargo xtask ci passes (fmt, clippy, tests, assets, brands, layers, wasm).
  • No panics in shipped code: no unwrap(), expect(), panic!, unreachable!, todo! or
    unimplemented! outside tests, and no unchecked indexing on data from files, parameters or
    messages. Errors are returned as Result and shown to the user
    (why and how).
  • Clean-room: nothing copied from Adobe products or GPL/AGPL code (AGENTS.md).
  • Every new asset has a row in ASSETS.md.

The Graph Data window's Import Data read UTF-16 only after a byte-order
mark, so a UTF-16 file without one filled the cells with NUL characters.
It now reads such a file in the byte order Import Data Sets' rule (storytold#7348)
gives it: at least half of the two-byte units hold a NUL byte, and the
byte order is the one that reads the line breaks. The text is then read
as after a byte-order mark: an odd last byte is dropped and an unpaired
surrogate reads as U+FFFD. A file the rule refuses is read as UTF-8, as
before.

The rule now also gives a byte order to a one-line file, which reads a
line break in neither order: big-endian when more of its units start
with a NUL byte than end with one, else little-endian as before. Import
Data Sets still refuses a one-line file, which has no data rows; read in
the new order, such a file can be refused with a different error first.
File › Place of a text file with the Unicode character set read UTF-16
only after a byte-order mark. Without one, UTF-16 text was read as UTF-8
(or the 8-bit set): characters outside U+0001 to U+00FF came out as
other characters, and each CR LF placed as two paragraph breaks.

Place now reads a file without a byte-order mark as UTF-16 by the rule
Import Data Sets uses, through the shared byte-order helper: an even
length, at least half of the two-byte units holding a NUL byte, the
byte order that reads a line break (for one line, the order its NUL
bytes give), and valid UTF-16 with no NUL character in that order. Any
other file is read as before, as UTF-8 or else the platform's 8-bit set.

Docs: docs/mcp.md, file.place params text, docs/target-app-parity.md.
@coderabbitai

coderabbitai Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 15 seconds.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration

Commits

Reviewing files that changed from the base of the PR and between a47d7ee and bad6ee2.

Files selected for processing: 10

  • crates/engine/src/cmd.rs
  • crates/engine/src/cmd/place.rs
  • crates/engine/src/cmd/place/text.rs
  • crates/engine/src/cmd/variablecmds.rs
  • crates/engine/src/cmd/variablecmds/csv.rs
  • crates/engine/src/tests/textimport.rs
  • crates/engine/src/tests/variables.rs
  • crates/ui-egui/src/dialogs/graph_data.rs
  • docs/mcp.md
  • docs/target-app-parity.md
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@bflatastic
bflatastic merged commit 53cc597 into storytold:main Nov 14, 2026
7 checks passed
@bflatastic

Copy link
Copy Markdown
Member

Merged, thanks @dotCooCoo! It passed its CI checks.

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.

2 participants