-
-
Notifications
You must be signed in to change notification settings - Fork 0
fix(ci): the invisible-character gate never matched anything #321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d9d0c67
510c4c7
11682f1
165c09c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -133,7 +133,7 @@ jobs: | |
| # Checks for: zero-width spaces, zero-width joiners, BOM, soft hyphens, | ||
| # non-breaking spaces, null bytes, and other invisible Unicode in source files. | ||
| set +e | ||
| PATTERNS='\xc2\xa0|\xe2\x80\x8b|\xe2\x80\x8c|\xe2\x80\x8d|\xef\xbb\xbf|\xc2\xad|\xe2\x80\x8e|\xe2\x80\x8f|\xe2\x80\xaa|\xe2\x80\xab|\xe2\x80\xac|\xe2\x80\xad|\xe2\x80\xae|\x00' | ||
| PATTERNS='\x00|[\x01-\x08\x0B\x0C\x0E-\x1F]|\x{a0}|\x{ad}|\x{200b}|\x{200c}|\x{200d}|\x{200e}|\x{200f}|\x{202a}|\x{202b}|\x{202c}|\x{202d}|\x{202e}|\x{2060}|\x{feff}' | ||
| find "$GITHUB_WORKSPACE" \ | ||
| -not -path '*/.git/*' -not -path '*/node_modules/*' \ | ||
| -not -path '*/.deno/*' -not -path '*/target/*' \ | ||
|
|
@@ -144,7 +144,7 @@ jobs: | |
| -o -name '*.yml' -o -name '*.yaml' -o -name '*.md' -o -name '*.adoc' \ | ||
| -o -name '*.idr' -o -name '*.zig' -o -name '*.v' -o -name '*.jl' \ | ||
| -o -name '*.gleam' -o -name '*.hs' -o -name '*.ml' -o -name '*.sh' \) \ | ||
| -exec grep -Prl "$PATTERNS" {} \; > /tmp/empty-lint-results.txt 2>/dev/null | ||
| -exec grep -aPl "$PATTERNS" {} + > /tmp/empty-lint-results.txt | ||
| EL_EXIT=$? | ||
| set -e | ||
|
|
||
|
|
@@ -153,13 +153,41 @@ jobs: | |
| echo "exit_code=$EL_EXIT" >> "$GITHUB_OUTPUT" | ||
| echo "ready=true" >> "$GITHUB_OUTPUT" | ||
|
|
||
| # Blocking subset: C0 controls and NUL only (owner ruling 2026-08-28). | ||
| # Invisible Unicode (NBSP/BOM/zero-width) stays ADVISORY - about 2,100 | ||
| # estate files carry it as legitimate typography in prose. | ||
| blocking=0 | ||
| while IFS= read -r bf; do | ||
| [ -z "$bf" ] && continue | ||
| if grep -qaP '\x00|[\x01-\x08\x0B\x0C\x0E-\x1F]' "$bf"; then | ||
| blocking=$((blocking+1)) | ||
| echo "::error file=${bf#$GITHUB_WORKSPACE/}::C0 control characters or NUL bytes - file corruption, blocks the gate" | ||
| fi | ||
| done < /tmp/empty-lint-results.txt | ||
|
Comment on lines
+162
to
+166
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -eu
file=.github/workflows/dogfood-gate.yml
printf '%s\n' '--- workflow lines 130-195 ---'
sed -n '130,195p' "$file"
printf '%s\n' '--- relevant symbols and result-file references ---'
rg -n -C 3 'EL_EXIT|empty-lint-results|blocking=|grep -qaP|read .*bf|grep .*P' "$file"Repository: hyperpolymath/boj-server Length of output: 6790 🏁 Script executed: #!/bin/bash
set -u
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
printf 'plain text\n' > "$tmp/plain"
printf '\001\n' > "$tmp/control"
printf '%s\n' '--- grep statuses ---'
grep -qaP '\x00|[\x01-\x08\x0B\x0C\x0E-\x1F]' "$tmp/plain"; printf 'plain_status=%s\n' "$?"
grep -qaP '\x00|[\x01-\x08\x0B\x0C\x0E-\x1F]' "$tmp/control"; printf 'control_status=%s\n' "$?"
grep -qaP '\x00|[\x01-\x08\x0B\x0C\x0E-\x1F]' "$tmp"; printf 'directory_error_status=%s\n' "$?"
printf '%s\n' '--- find -exec producer status when grep receives a directory ---'
find "$tmp" -maxdepth 1 -type d -exec grep -aPrl 'x' {} \; >/dev/null 2>/dev/null
printf 'find_exec_grep_error_status=%s\n' "$?"
printf '%s\n' '--- grep version ---'
grep --version | head -1Repository: hyperpolymath/boj-server Length of output: 420 Fail closed when the scan reports an error.
🤖 Prompt for AI AgentsSource: MCP tools |
||
| echo "blocking=$blocking" >> "$GITHUB_OUTPUT" | ||
|
|
||
| # Emit annotations for each file with invisible chars | ||
| while IFS= read -r filepath; do | ||
| [ -z "$filepath" ] && continue | ||
| REL_PATH="${filepath#$GITHUB_WORKSPACE/}" | ||
| echo "::warning file=${REL_PATH}::Invisible Unicode characters detected (zero-width space, BOM, NBSP, etc.)" | ||
| done < /tmp/empty-lint-results.txt | ||
|
|
||
| # Enforce (owner ruling 2026-08-28): C0/NUL corruption BLOCKS; other | ||
| # invisible Unicode stays advisory. Enforcement lives inside this step | ||
| # so a crash above fails the job directly - counts can never arrive | ||
| # empty into a separate check that then passes silently. | ||
| if [ "$EL_EXIT" -ne 0 ]; then | ||
| echo "::warning::invisible-character scan exited $EL_EXIT - results may be incomplete" | ||
| fi | ||
| if [ "${blocking:-0}" -gt 0 ]; then | ||
| echo "## Empty-linter: BLOCKED - $blocking file(s) with C0/NUL corruption" >> "$GITHUB_STEP_SUMMARY" | ||
| echo "::error::$blocking file(s) contain C0 control characters or NUL bytes - corruption, not typography. See file annotations." | ||
| exit 1 | ||
| elif [ "${FINDINGS:-0}" -gt 0 ]; then | ||
| echo "::notice::$FINDINGS file(s) carry invisible Unicode (NBSP/BOM/zero-width) - advisory only" | ||
| fi | ||
|
|
||
| - name: Check shebang placement | ||
| run: bash scripts/check-shebang-first.sh | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: hyperpolymath/boj-server
Length of output: 3707
🌐 Web query:
GNU grep -P PCRE2 \x{...} LC_CTYPE C POSIX UTF-8 locale matching documentation💡 Result:
In GNU grep, when using the Perl-compatible regular expression engine (enabled via the -P or --perl-regexp option), the syntax \x{...} is supported as a standard way to specify Unicode character code points [1][2]. Key points regarding this functionality include: 1. Syntax Support: The \x{...} sequence is part of the PCRE2 library's syntax, which GNU grep uses when -P is invoked [1][2]. Within the curly braces, you provide the hexadecimal representation of the Unicode code point (e.g., \x{20AC} for the Euro sign) [1][3]. This provides an unambiguous way to specify characters, as opposed to \xHH which is limited to two hexadecimal digits [1][4]. 2. Locale and Unicode Interaction: - When using -P, PCRE2 typically handles character matching based on the UTF-8 encoding if the environment's locale is set to a UTF-8 locale (e.g., en_US.UTF-8). - Unlike basic (BRE) or extended (ERE) regular expressions in GNU grep, which rely on the system's locale settings (LC_CTYPE) to define character classes and behavior, PCRE2 in GNU grep maintains its own internal handling of Unicode [2]. - It is important to note that PCRE2 behavior can sometimes diverge from traditional POSIX grep behavior. For instance, while POSIX grep interprets patterns based on the LC_CTYPE locale setting, -P patterns are treated as PCREs, which are generally Unicode-aware by default when the input is UTF-8 [2]. 3. POSIX Considerations: The POSIX standard for grep does not define PCRE2 or the \x{...} syntax [5]. The use of -P is a non-standard extension in GNU grep [2]. For maximum portability across different systems, standard POSIX BRE/ERE expressions should be used, though these lack the advanced Unicode escape syntax provided by PCRE2 [2][5]. 4. Documentation: For detailed technical specifications, refer to the official PCRE2 documentation (specifically the pcre2pattern and pcre2syntax manual pages), as GNU grep's behavior when using -P is governed by the underlying PCRE2 library [1][4][6][2]. Note that while GNU grep supports -P, it labels it as experimental and warns that certain features may be unimplemented or behave differently than in a standalone Perl environment [2].
Citations:
🌐 Web query:
site:gnu.org/software/grep/manual grep -P UTF-8 locale \x{...} LC_CTYPE💡 Result:
GNU
grepuses theLC_CTYPElocale to determine the character encoding of both the pattern and input. In a UTF-8 locale,grep -Ptreats input as UTF-8; in theC/POSIXlocale, it treats characters as single bytes. (gnu.org)For matching a Unicode code point with PCRE syntax:
LC_ALL=en_US.UTF-8 grep -P '\x{1F600}' file\x{...}is interpreted by PCRE as a Unicode code-point escape, but it requires an appropriate UTF-8/Unicode PCRE mode and locale. GNU’s manual specifically recommends-Pfor matching non-ASCII characters. (gnu.org)To make behavior deterministic, set
LC_ALLrather than onlyLC_CTYPE:LC_ALL=C.UTF-8 grep -P '\x{03BB}' fileCheck available locales with:
The locale precedence is
LC_ALL, then the relevantLC_*variable, thenLANG. (gnu.org)Citations:
Pin the locale for Unicode matching.
The
grep -aPrlcommand has no explicit locale. Under theCorPOSIXlocale, it may treat UTF-8 input as single bytes and miss the\x{...}patterns. SetLC_ALL=C.UTF-8for this command.🤖 Prompt for AI Agents
Source: MCP tools