fix(scanner): prune .mcpp from glob walks; never throw on unnarrowable names (#230) - #231
Merged
Conversation
…e names (#230) Root cause of the windows-latest 'exit 127' (really 0xC0000409): 0.0.95's scanner walks globs with follow_directory_symlink, and the project-local `.mcpp/.xlings/data/<index>` entry is a symlink back to the index root — so the walk escapes into the entire index checkout. In mcpp-index CI that tree contains a vendored xim-pkgindex whose issue template has a CJK filename; path_matches_glob spelled it narrow via generic_string(), which on MSVC under a non-CJK ANSI codepage throws std::system_error. The exception escaped main uncaught -> std::terminate -> __fastfail (0xC0000409), which git-bash reports as a bare exit 127. Three layers, all fixed: - expand_glob/expand_dir_glob prune directories named .mcpp — mcpp's own metadata dir is never a source dir, and pruning it severs the symlink escape at its origin (also stops walking the whole index per member). - path_matches_glob treats a name with no narrow spelling as 'no match' instead of letting the conversion tear down the build. - main() gains a last-resort catch: an escaped exception now names itself and exits 70 instead of a silent fastfail. Evidence: full-memory WER dump from the CI runner shows the throw chain scan_one_into -> expand_glob -> path_matches_glob -> _Convert_wide_to_narrow with the wide string '.mcpp\.xlings\data\compat\mcpp-0.0.95-windows-x86_64\registry\data\ xim-pkgindex\.github\ISSUE_TEMPLATE\bug-report---<CJK>.md'. Behavioral control on linux: release 0.0.95 compiles an out-of-tree extra.cpp through the .mcpp symlink (duplicate main at link); the fixed binary prunes it and builds clean. e2e 113 encodes both assertions. 35/35 unit tests pass.
Version bump + CHANGELOG entry for the release notes extractor; also backfill a pointer entry for 0.0.95 (released without one).
…se once 0.0.96 is indexed)
Sunrisepeak
added a commit
that referenced
this pull request
Aug 27, 2026
…nd the build (2026.8.27.2) (#517) Closes #516. #230 的同一处漏网:#231 加固了三个窄化站点,漏掉了同一个 walk 循环里 早一行执行的 `is_excluded_walk_dir`。 抛异常的不是解压,是 mcpp 自己 —— MSVC 的 `path::string()` 走 `WideCharToMultiByte(ACP)`,遇到当前代码页拼不出的字符就抛 `std::system_error`。 `include_dirs = { "*" }` 会从解压根无界递归遍历整棵上游源码树,cpp-httplib 带了 `test/www/<CJK>Dir/`,于是三个 httplib 测试在 Windows 上一起挂,Linux/macOS 全绿。 收敛成按用途分三档的一条规则:与 ASCII 字面量比较 → 按 path 比,不窄化; 稳定身份(hash/digest)→ u8string();交给编译器/ninja/CDB → try_narrow() 并处理 nullopt。跳过不再静默:按目录报告一次,走 mcpp.diag 的 degraded 通道。 顺带修掉 interface_set_digest 的一个真实跨平台不一致(Linux 打包 / Windows 校验 对非 ASCII 名字给出不同摘要)。加 .github/tools/check_narrow_conversions.sh 硬门。 红→绿闭环(同一 runner、同一测试、同一 ACP): ce86b41 不含修复 → ci-windows FAILED,报的是 #516 逐字相同的那句话; ci-linux 停在新门,点名 scanner.cppm:238 fade10f 含修复 → [ OK ] Scanner.GlobWalkSurvivesNamesTheCodePageCannotSpell 0059033 自审 6 处修正 → 36/36 checks success 内部依赖 xlings pin 2026.8.17.2 → 2026.8.27.4(17 个 pin 点)。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
修复 #230:windows
mcpp test --workspace静默 exit 127根因(三层,全部修复)
真实退出码是 0xC0000409(fastfail),git-bash 把它显示成 127。通过在 CI runner 上开启 WER 全内存 dump 并解析崩溃栈,拿到了被转换的字符串本体:
链条:
follow_directory_symlink(feat(manifest): 声明式清单能力 — features.sources / generated_files / cfg 条件 sources / per-glob flags #223),而项目本地.mcpp/.xlings/data/<index>是指回索引根的符号链接(config.cppm 创建)→ glob walk 逃逸出成员目录,走遍整个索引 checkout(CI 里含解压的 mcpp 发行版及其 vendored xim-pkgindex)。path_matches_glob用generic_string()把宽路径拼成窄串;MSVC 在非 CJK ANSI 代码页(runner ACP=1252)下遇到中文文件名抛std::system_error(linux/macos 无此转换,所以只有 windows 崩)。main未被捕获 →std::terminate→__fastfail→ 0xC0000409,无任何错误输出。0.0.94 绿是因为它不跟随目录符号链接,从未走进该树。
修复
expand_glob/expand_dir_glob:按名剪枝.mcpp目录——它是 mcpp 自己的元数据目录,永远不是源码目录;从源头切断符号链接逃逸(顺带避免每个成员都把整个索引树白走一遍)。path_matches_glob:名字无法窄化 → 视为"不匹配"并跳过,而不是让转换异常摧毁整次构建。main()增加最后防线 catch:逃逸异常现在会打印真实错误并以 70 退出,不再是静默 fastfail/127。验证
.mcpp符号链接把项目外的extra.cpp编进来(链接期 duplicatemain);修复版剪枝后构建干净。113_scanner_mcpp_dir_prune.sh固化两条断言(符号链接逃逸剪枝 + CJK 文件名不致命)。debug/mcpp230-windows-repro(五轮插桩:原始退出码 → minidump → cdb 栈 → 全内存 dump 字符串取证)。发布 0.0.96 后,mcpp-index 即可撤掉 windows 钉回 0.0.94 的临时补丁,全平台统一到最新(mcpp-index#74 正在等待)。