Skip to content

Windows 解压包含 UTF-8 路径的归档时因多字节代码页转换失败 #516

Description

@yizhinailong

环境

  • mcpp:2026.8.10.3
  • 操作系统:Microsoft Windows Server 2025,10.0.26100
  • GitHub Runner:windows-2025-vs2026
  • mcpp 选择的工具链:LLVM/Clang 20.1.7
  • MCPP_INDEX_MIRROR=GLOBAL
  • 复现仓库:mcpplibs/mcpp-index PR 留言版 | 使用mcpp工具构建的项目(库/工具/应用) #260
  • CI merge SHA:d98961cbdc2ba9de8298f5dc474370f9d5ba128c

归档信息

下载地址:

https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.53.1.tar.gz

SHA-256:

185af9587e270de9a3bfee234c6740f02e82265da33c7a41f97e02ee42f979d2

归档中包含以下非 ASCII 路径:

cpp-httplib-0.53.1/test/www/日本語Dir/
cpp-httplib-0.53.1/test/www/日本語Dir/meson.build
cpp-httplib-0.53.1/test/www/日本語Dir/日本語File.txt

复现步骤

在 mcpp-index PR #260 的代码中执行:

mcpp index update
mcpp test -p httplib-brotli

以下测试也会发生相同错误:

mcpp test -p httplib-tls
mcpp test -p httplib-zstd

实际结果

三个测试均在下载 compat.httplib 后立即失败:

Downloading compat.httplib v0.53.1
error: internal: unhandled exception: No mapping for the Unicode character exists in the target multi-byte code page.

错误发生在 feature 依赖下载和源码编译之前。

预期结果

mcpp 应当能够在 Windows 上正确解压包含 UTF-8 文件名的归档,并继续构建包。

如果确实无法解压,至少应当报告失败的归档条目,而不是抛出未处理的内部异常。

排查证据

  • 同一个包在 Linux 和 macOS 上可以通过下载和解压阶段。
  • Brotli、TLS 和 Zstd 三个测试都在相同位置失败。
  • 同一个 Windows CI job 后续能够成功下载和构建 compat.openssl、compat.zstd,因此不是可选依赖导致的问题。
  • cpp-httplib 归档中只有上述三个路径包含非 ASCII 字符。
  • 错误发生在 Downloading compat.httplib 之后、编译开始之前,符合归档解压阶段失败的特征。

综合以上信息,问题很可能是 Windows 解压逻辑将 UTF-8 归档路径通过当前 ANSI/多字节代码页进行转换,导致无法表示日文路径。

建议修复方向

Windows 归档解压过程应完整使用 Unicode 路径:

  1. 将归档中的 UTF-8 文件名明确转换为 UTF-16。
  2. 使用宽字符 Windows 文件系统 API。
  3. 避免通过当前系统 ANSI 代码页转换路径。
  4. 解压失败时输出归档 URL、目标路径和具体失败条目。

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions