From 8588a6b453a7867aa3193c126b808efcdc9d16e1 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Wed, 2 Sep 2026 02:15:19 +0800 Subject: [PATCH] =?UTF-8?q?fix(amsd):=20app=20=E6=98=BE=E7=A4=BA=E5=90=8D?= =?UTF-8?q?=20name[17]=E2=86=92[49]=20+=20UTF-8=20=E6=95=B4=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E6=88=AA=E6=96=AD=EF=BC=88utf8=5Ftrim=5Fincomplete?= =?UTF-8?q?=EF=BC=89=E2=80=94=E2=80=94=E4=BF=AE=E3=80=8C=E6=B5=81=E5=AA=92?= =?UTF-8?q?=E4=BD=93=E5=AE=A2=E6=88=B7=E7=AB=AF=E3=80=8D18=20=E5=AD=97?= =?UTF-8?q?=E8=8A=82=E8=A2=AB=E7=A0=8D=E6=88=90=2016=20=E8=87=B4=20am=20li?= =?UTF-8?q?st=20=E8=BE=93=E5=87=BA=E9=9D=9E=E6=B3=95=20UTF-8=E3=80=81?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF=20/api/overview=20=E8=A2=AB=E6=B5=8F?= =?UTF-8?q?=E8=A7=88=E5=99=A8=20JSON.parse=20=E6=8B=92=E6=94=B6=EF=BC=88?= =?UTF-8?q?=E9=9D=9E=20JSON=20=E5=93=8D=E5=BA=94=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- patch_v2/meow_amsd/meow_amsd.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/patch_v2/meow_amsd/meow_amsd.c b/patch_v2/meow_amsd/meow_amsd.c index 12e05bf..db74c9a 100644 --- a/patch_v2/meow_amsd/meow_amsd.c +++ b/patch_v2/meow_amsd/meow_amsd.c @@ -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.=(或 JSON "route.":"")到 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, "?")) {