check_no_cstr.sh (1768B)
1 #!/usr/bin/env bash 2 # Phase 6 gate: assert the NUL-terminated-string functions and printf %s have 3 # been eliminated from the first-party tree (src/, lang/, driver/). rt/ is the 4 # freestanding runtime/libc and is intentionally exempt. Test code is exempt. 5 # 6 # Allowed exceptions: 7 # - slice_from_cstr / kit_slice_cstr : the sanctioned boundary scan helpers 8 # - driver_strlen / driver_streq / driver_strneq : driver host-shim wrappers 9 # - reloc_kind_name / *_name returning canonical literals (not string ops) 10 # - ordering compares left intentionally (marked with a nearby comment) 11 # 12 # Usage: scripts/check_no_cstr.sh (exit 1 on any disallowed hit) 13 set -u 14 cd "$(dirname "$0")/.." 15 16 dirs="src lang driver" 17 # Forbidden: bare libc string functions. We match the call form `name(`. 18 banned='\b(strlen|strcmp|strncmp|strcpy|strncpy|strcat|strncat|strstr|strchr|strrchr|strdup)\s*\(' 19 # printf-family bare %s (not %.*s, not %%s, not width-padded %-Ns / %*s). 20 pct_s='%[^%."*0-9-]*s|"[^"]*%s' 21 22 fail=0 23 24 echo "== banned string functions ==" 25 # src/core/slice.c is the one sanctioned home of a NUL scan (slice_from_cstr). 26 hits=$(rg -n --pcre2 "$banned" $dirs -g '!*/tests/*' -g '!src/core/slice.c' 2>/dev/null \ 27 | rg -v 'slice_from_cstr|kit_slice_cstr|driver_strlen|driver_streq|driver_strneq|driver_strchr|driver_strdup' \ 28 | rg -v 'ordering|sort|/\* *TODO slice' ) 29 if [ -n "$hits" ]; then echo "$hits"; fail=1; else echo " clean"; fi 30 31 echo "== bare printf %s ==" 32 # Heuristic: lines containing "%s" inside a string literal, excluding the 33 # allowed width/precision/.* forms. Manual review still recommended. 34 shits=$(rg -n '"[^"]*%s' $dirs 2>/dev/null | rg -v '%\.\*s|%-[0-9]+s|%\*s|%%s') 35 if [ -n "$shits" ]; then echo "$shits"; fail=1; else echo " clean"; fi 36 37 exit $fail