You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#610 converted nine assertion lines in src/qt/forms/tests/tst_i18n.qml from raw
U+061C / U+200E / U+200F to \uXXXX escapes, and explicitly deferred the lint
that would keep them that way:
Optionally, a lint could keep it that way: a repo-wide scan rejecting raw
U+061C / U+200E / U+200F / U+202A–U+202E / U+2066–U+2069 outside comments would
also catch the "trojan source" shape in first-party code generally. That is a
bigger decision than this issue and should not block the mechanical fix.
Filing it, because while implementing #610 and #591 I hit the hazard the lint
would catch — twice, in the same session, in the opposite direction from the one #610 describes.
Verification status
Reproduced, on myself, during PR #630. Not a hypothetical and not inferred
from reading.
Writing new source through a tool whose payload is JSON, I typed the six
characters intending them to land in the file as six characters. JSON
decoded the escape before the file was written, so what landed was the single
invisible character U+061C. It happened in two separate files before I checked:
$ grep -nP '[^\x00-\x7F]' include/morph/render/locale_format.hpp | cat -A
109: /// The locale's negative-sign string, e.g. `"M-bM-^HM-^R"`. Empty is read as the$
112: /// The locale's positive-sign string, e.g. `"M-XM-^\+"`. Entry-edge only:$
116: /// The locale's DIGIT ZERO, e.g. `"M-YM- "`. The ten digits are the ten$
...
$ grep -nP '[^\x00-\x7F]' tests/test_render_locale_format.cpp
799: // Before morph#591 this edge emitted "-1٬050٫25" -- the
856: // A decision, not a consequence: "٥5" is rejected rather than read as
(M-XM-^\ is D8 9C, U+061C. The same measurement the #610 triage comment
used.) Baseline for comparison: the same header at 0e3b8823 had 2
non-ASCII lines, both pre-existing em-dashes in prose.
I caught it by grepping, fixed it, and both files are ASCII-clean in #630 apart
from the pre-existing em-dashes and box-drawing characters. But nothing in the
repository would have caught it if I had not thought to look, and in these two
cases the characters were inside comments, where the consequence is only
unreadability. In a string literal it is a silently wrong test, which is
precisely cost #2 of #610.
What I did not verify
I did not write the lint, so I have not measured its false-positive rate
against the tree. docs/ prose and the ladder fixtures are the obvious places
where a legitimate non-ASCII character might live.
I did not check whether any tool in CI or in a pre-commit hook already
normalises or rejects these; .pre-commit-config.yaml has trailing-whitespace, end-of-file-fixer, check-yaml, check-json, mixed-line-ending, clang-format and codespell, none of which look at
this.
I did not establish that a human contributor hits this. My evidence is about
a machine-authored edit path. That is a real and now-common authoring path for
this repository, but it is one path, and the finding should be priced as such.
Why it matters
The failure is silent in both directions:
→ U+061C (what happened to me): the source stops saying what it
means, and a reviewer reading the diff cannot tell.
The tree-wide scan is known to be cheap and currently clean — the #610 triage
comment measured it over the full trojan-source class and found exactly one
file, which #630 has now fixed:
$ grep -rlP '[\x{061C}\x{200E}\x{200F}\x{202A}-\x{202E}\x{2066}-\x{2069}]' src/ tests/ examples/
(no output on this branch)
So the lint would go in green, which is the cheapest moment to add one.
What is actually being decided
Not "should we scan" but three narrower things, which is why this is its own
issue and not a line in #610:
Which code points. The bidi controls alone, or the full trojan-source
class (adding U+202A–U+202E and U+2066–U+2069), or every non-ASCII character
in src/, tests/ and include/ with an allowlist.
Where. First-party sources only, or docs/ too — docs/spec/ prose
legitimately contains em-dashes and box drawing, so a naive scan over the
whole tree fails on day one.
Close as fixed when a CI step fails on a first-party file containing a raw
character from the agreed class, and a deliberately-introduced one is shown to
fail it (a check that passes over a clean tree proves nothing on its own).
#610 converted nine assertion lines in
src/qt/forms/tests/tst_i18n.qmlfrom rawU+061C / U+200E / U+200F to
\uXXXXescapes, and explicitly deferred the lintthat would keep them that way:
Filing it, because while implementing #610 and #591 I hit the hazard the lint
would catch — twice, in the same session, in the opposite direction from the one
#610 describes.
Verification status
Reproduced, on myself, during PR #630. Not a hypothetical and not inferred
from reading.
Writing new source through a tool whose payload is JSON, I typed the six
characters
intending them to land in the file as six characters. JSONdecoded the escape before the file was written, so what landed was the single
invisible character U+061C. It happened in two separate files before I checked:
(
M-XM-^\isD8 9C, U+061C. The same measurement the #610 triage commentused.) Baseline for comparison: the same header at
0e3b8823had 2non-ASCII lines, both pre-existing em-dashes in prose.
I caught it by grepping, fixed it, and both files are ASCII-clean in #630 apart
from the pre-existing em-dashes and box-drawing characters. But nothing in the
repository would have caught it if I had not thought to look, and in these two
cases the characters were inside comments, where the consequence is only
unreadability. In a string literal it is a silently wrong test, which is
precisely cost #2 of #610.
What I did not verify
against the tree.
docs/prose and the ladder fixtures are the obvious placeswhere a legitimate non-ASCII character might live.
normalises or rejects these;
.pre-commit-config.yamlhastrailing-whitespace,end-of-file-fixer,check-yaml,check-json,mixed-line-ending,clang-formatandcodespell, none of which look atthis.
a machine-authored edit path. That is a real and now-common authoring path for
this repository, but it is one path, and the finding should be priced as such.
Why it matters
The failure is silent in both directions:
→ U+061C (what happened to me): the source stops saying what itmeans, and a reviewer reading the diff cannot tell.
'+'and'-'are accepted in every locale by design (morph#596), so amangled assertion measures the wrong thing and still reports success.
The tree-wide scan is known to be cheap and currently clean — the #610 triage
comment measured it over the full trojan-source class and found exactly one
file, which #630 has now fixed:
So the lint would go in green, which is the cheapest moment to add one.
What is actually being decided
Not "should we scan" but three narrower things, which is why this is its own
issue and not a line in #610:
class (adding U+202A–U+202E and U+2066–U+2069), or every non-ASCII character
in
src/,tests/andinclude/with an allowlist.docs/too —docs/spec/proselegitimately contains em-dashes and box drawing, so a naive scan over the
whole tree fails on day one.
to implement than it sounds for QML and C++, and the two cases above were
in comments, where the cost is real but smaller. A simpler rule that
covers comments too may be the better trade.
What would change the verdict
character from the agreed class, and a deliberately-introduced one is shown to
fail it (a check that passes over a clean tree proves nothing on its own).
criterion is enough, in which case that decision should be written where a
reader of
tst_i18n.qmlortests/test_render_locale_format.cppwill findit, since both files currently maintain the convention by hand.