fix(amsd): app 显示名 name[17]→[49] + UTF-8 整序列截断(utf8_trim_incomplete)——修「流媒体客户端」18 字节被砍成 16 致 am list 输出非法 UTF-8、面板 /api/overview 被浏览器 JSON.parse 拒收(非 JSON 响应)
This commit is contained in:
1 parent
9d54cf89c5
commit
8588a6b453
1 file changed
+19
-1
@@ -91,7 +91,7 @@ struct ams_route {
|
||||
|
||||
struct ams_app {
|
||||
char pkg[MEOW_APP_ID_MAX]; /* app_id=package */
|
||||
char name[17];
|
||||
char name[49]; /* 显示名(UTF-8;截断必须整序列,见 utf8_trim_incomplete) */
|
||||
char exec[129];
|
||||
int known; /* 注册表(app.json 扫描)命中 */
|
||||
int state; /* AMS_* */
|
||||
@@ -374,6 +374,22 @@ static void poll_card(void)
|
||||
}
|
||||
|
||||
/* ---- 注册表扫描(app.json 迷你解析:package/name/exec) ---- */
|
||||
/* 把字符串末尾不完整的 UTF-8 序列砍掉(截断到最后一个完整码点边界)。
|
||||
* 根因记录:name 截断若落在多字节序列中间,下游 JSON 嵌进面板会被浏览器
|
||||
* JSON.parse 以非法 UTF-8 拒收(「非 JSON 响应」事故 2026-09-02)。 */
|
||||
static void utf8_trim_incomplete(char *s)
|
||||
{
|
||||
size_t n = strlen(s), i = 0, last_good = 0;
|
||||
while (i < n) {
|
||||
unsigned char c = (unsigned char)s[i];
|
||||
int len = (c < 0x80) ? 1 : (c >= 0xF0) ? 4 : (c >= 0xE0) ? 3 : (c >= 0xC0) ? 2 : 1;
|
||||
if (i + (size_t)len > n) break; /* 不完整序列 */
|
||||
i += (size_t)len;
|
||||
last_good = i;
|
||||
}
|
||||
s[last_good] = '\0';
|
||||
}
|
||||
|
||||
static void appjson_get(const char *content, const char *key, char *out, size_t n)
|
||||
{
|
||||
out[0] = '\0';
|
||||
@@ -394,6 +410,7 @@ static void appjson_get(const char *content, const char *key, char *out, size_t
|
||||
if (l >= n) l = n - 1;
|
||||
memcpy(out, c, l);
|
||||
out[l] = '\0';
|
||||
utf8_trim_incomplete(out);
|
||||
}
|
||||
|
||||
/* §6.2 二期:在 content 二分/扁平解析 route.<id>=<chain>(或 JSON "route.<id>":"<chain>")到 app。
|
||||
@@ -540,6 +557,7 @@ static void registry_scan(int verbose)
|
||||
appjson_get(content, "name", tmp, sizeof tmp);
|
||||
if (!tmp[0]) scopy(tmp, sizeof tmp, nm);
|
||||
scopy(a->name, sizeof a->name, tmp);
|
||||
utf8_trim_incomplete(a->name); /* scopy 截断同样走整序列边界 */
|
||||
appjson_get(content, "exec", tmp, sizeof tmp);
|
||||
if (tmp[0]) scopy(a->exec, sizeof a->exec, tmp);
|
||||
else if (!a->exec[0] || !strcmp(a->exec, "?")) {
|
||||
|
||||
Reference in new issue
Block a user