fix(ncm): tag 嵌入按实际容器拒绝 MP4/M4A(ID3v2 前缀会破坏 MP4 容器)

download 扩展名在 type 非 flac 时一律落 mp3;若服务端降级返回 MP4/M4A("....ftyp"),
给文件加 ID3v2 头会破坏容器。ncm_tag_embed_file 现读 12 字节 magic:fLaC → VORBIS_COMMENT,
"ftyp" → NCM_ERR_ARG 拒绝(调用方 commit 裸流),其余按 MP3 处理。
test_ncm_tag 增 2 条断言(拒绝 + 原文件不变)→ 53 PASS / 0 FAIL,0 warning。
This commit is contained in:
AskaEth committed 2026-11-04 20:49:25 +08:00
1 parent 39465ea1ef
commit a9c94c7221
2 files changed
+14 -3

No files matched your search

+7 -3
View File
@@ -561,9 +561,10 @@ int ncm_tag_embed_file(const char *path, const char *ext, const ncm_tag_meta_t *
{
char tmp[NCM_TAG_PATH_MAX];
struct stat st;
unsigned char magic[4];
unsigned char magic[12];
unsigned char *buf;
int in, out, rc, is_flac, n;
ssize_t mgot;
if (!path || !path[0] || !m) return NCM_ERR_ARG;
if (!m->title[0] && !m->artist[0] && !m->album[0]) return NCM_OK; /* 无元数据:不动文件 */
@@ -579,12 +580,15 @@ int ncm_tag_embed_file(const char *path, const char *ext, const ncm_tag_meta_t *
if (in < 0) return NCM_ERR_IO;
if (fstat(in, &st) != 0 || st.st_size <= 0) { close(in); return NCM_ERR_IO; }
if (read_full(in, magic, sizeof magic) != (ssize_t)sizeof magic) { close(in); return NCM_ERR_IO; }
mgot = read_full(in, magic, sizeof magic);
if (mgot < 4) { close(in); return NCM_ERR_IO; }
if (lseek(in, 0, SEEK_SET) < 0) { close(in); return NCM_ERR_IO; }
is_flac = (memcmp(magic, "fLaC", 4) == 0);
/* 声明 flac 却无 fLaC 魔数 = 残体/损坏:拒绝写(调用方 commit 裸流降级)。
* 声明 mp3 而内容实为 FLAC:按容器写 VORBIS_COMMENT(真机降级产物同理)。 */
* 声明 mp3 而内容实为 FLAC:按容器写 VORBIS_COMMENT(真机降级产物同理)。
* MP4/M4A(第 4..7 字节 "ftyp"):ID3v2 头会破坏 MP4 容器 → 拒绝(裸流降级)。 */
if (!is_flac && ext && strcasecmp(ext, "flac") == 0) { close(in); return NCM_ERR_ARG; }
if (!is_flac && mgot >= 8 && memcmp(magic + 4, "ftyp", 4) == 0) { close(in); return NCM_ERR_ARG; }
buf = (unsigned char *)malloc(NCM_TAG_CHUNK);
if (!buf) { close(in); return NCM_ERR_OOM; }