diff --git a/CHANGELOG/0.3.9.md b/CHANGELOG/0.3.9.md new file mode 100644 index 0000000..2ecde07 --- /dev/null +++ b/CHANGELOG/0.3.9.md @@ -0,0 +1,11 @@ +# PMM v0.3.9 + +## 修复 +- **`.pdm` 自安装 / `pmm install pmm==` 报"校验不匹配"并失败**: + GNU `sha256sum` 对二进制成员(`.tar.gz` 含 NUL 字节)会在文件名前输出 `*`(如 ` *control.tar.gz`), + 而 `pdm_install_file` 解析时把这个 `*` 一起当成了文件名,导致找 `installed/.stage/*control.tar.gz` + 失败、误判 `checksum-mismatch`。现在解析时**去掉文件名开头的 `*`**,校验恢复正常。 + (此前 0.3.7/0.3.8 的 amd64 `.pdm` 与 CI 产物 aarch64 `.pdm` 均受影响:整包 sha256 正确,但内部成员校验被误伤。) + +## 说明 +- 该问题不影响下载阶段的整包 sha256 校验(那一条是对的),只影响解包后的成员校验。 diff --git a/src/pdm.c b/src/pdm.c index 8b7b38b..2d3ce1e 100644 --- a/src/pdm.c +++ b/src/pdm.c @@ -502,6 +502,10 @@ int pdm_install_file(const char *pdmfile) { char line[256], fname[128], expect[128]; while (fgets(line, sizeof(line), sf)) { if (sscanf(line, "%127s %127s", expect, fname) != 2) continue; + /* GNU sha256sum marks binary members (the .tar.gz contain NULs) with + * a '*' before the name, e.g. " *control.tar.gz". Strip it so + * the filename resolves; otherwise the check always "mismatches". */ + if (fname[0] == '*') memmove(fname, fname + 1, strlen(fname)); char mp[1200]; snprintf(mp, sizeof(mp), "installed/.stage/%s", fname); if (pmm_sha256_file(mp, hex) != 0 || strcasecmp(hex, expect) != 0) {