Escape codes \x80 through \xFF get encoded as two bytes #989
Open
opened 2026-01-29 15:44:49 +09:00 by spivee
·
1 comment
No Branch/Tag Specified
master
uw-aci
prh-docs-fix
uw-mldsa-crypto
uw-rename-fix-deps
bump_gmserialization
zomp
ceres
gh-pages
gh-485
dependabot/pip/dot-github/workflows/pygments-2.15.0
old_ceres
ghallak/split-typechecker
gh-400
new_ceres
loop-op
type-env
ghallak/229
option-force-msg
6.0.2
lima
call-fee
fix-ets
mergesort
lima-master-merge
optionally_generate_aci
changelog-update
make-return-reserved-word
radrow-patch-2
aens-subdomains
aens-at-full-node-ver
pt-166866806-claim-with-name-fee
extend-aci-interface
generalized_accounts_no_abi_move
roma
quickcheck-ci
v7.5.0
v7.4.0
v7.3.0
v7.2.1
v7.2.0
v7.1.0
v7.0.1
v7.0.0
v6.1.0
v6.0.2
v6.0.1
v6.0.0
v5.0.0
v4.3.0
v4.2.0
v4.1.0
v4.1.0-rc1
v4.0.0
v4.0.0-rc5
v4.0.0-rc4
v4.0.0-rc3
v4.0.0-rc1
v3.2.0
v3.1.0
v3.0.0
v2.1.0
v2.0.0
roma-v1
v2
Labels
Clear labels
WIP
bug
consensus-breaking
dependencies
documentation
duplicate
effort: high
effort: low
effort: medium
effort: trivial
enhancement
good first issue
help wanted
invalid
maintenance
question
task/feature
todo-in-rewrite
wontfix
bug
duplicate
enhancement
help wanted
invalid
pig lipstick
question
wontfix
Something is not working
This issue or pull request already exists
New feature
Need some help
Something is wrong
Muggle-facing enhancements
More information is needed
This won't be fixed
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: QPQ-AG/sophia#989
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The compiler supports escape codes like "\x40", turning two arbitrary hexadecimal digits into one byte in the resulting string. This is useful for inserting non-printable characters, like "\x00" for a null character, but it behaves strangely when given 'extended ASCII' values, from 128 through to 255, or \x80 to \xFF.
The expectation would be that other non-printable character values would be inserted faithfully, and if the user wanted to escape a complex UTF-8 sequences, the user could simply enter each byte of the UTF-8 encoding directly. Instead, the compiler takes this extended ASCII value, interprets it as a unicode code point between 128 and 256, and encodes that in UTF-8, which then takes two bytes instead of one. This is nonsense, as the \x escape character only accepts two hex digits, so clearly isn't meant to represent unicode, but is meant to represent a single byte. Consider the unicode code point U+0100, which in UTF-8 is represented as
<<16#C4, 16#80>>. If we try to enter this into a string literal as "\x0100", then that is interpreted as U+0001, U+0030, U+0030, i.e. <<1, $0, $0>>. Whereas if we try to enter the UTF-8 ourselves, manually, as "\xC4\x80", then that is interpreted as U+00C4, U+0080, producing <<16#C3, 16#84, 16#C2, 16#80>>, ad infinitum!Instead these hex escape codes should not be passed to any unicode functions at all, and should just be dumped faithfully into the resulting binary/immediate.
It seems the design is that U+0100 is written as "\x{0100}", with curly braces included explicitly in the string literal. That doesn't work in this compiler, though, so maybe there should be a separate issue for that??