fix(launcher): app 显示名缓冲 name[17]→[49] + json_str 截断 UTF-8 整序列保护(同 amsd 修复,M6.2 备料 launcher 03dfcf76)

This commit is contained in:
AskaEth committed 2026-09-02 02:20:06 +08:00
1 parent 8588a6b453
commit 54a6e828b7
3 files changed
+33 -6

No files matched your search

+11 -2
View File
@@ -629,7 +629,7 @@ void ensure_wifi(void)
void meow_parse_app_json(FILE *f, struct app *a) void meow_parse_app_json(FILE *f, struct app *a)
{ {
char buf[256]; char buf[256];
char name[17] = "", exec[129] = "", icon[129] = ""; char name[49] = "", exec[129] = "", icon[129] = "";
char package[MEOW_APP_ID_MAX] = ""; char package[MEOW_APP_ID_MAX] = "";
int fram = 0, immersive = 0; int fram = 0, immersive = 0;
int fullscreen = 0; /* app.json fullscreen=<true|1>(注入 MEOW_FULLSCREEN env,SDK 预先设全屏) */ int fullscreen = 0; /* app.json fullscreen=<true|1>(注入 MEOW_FULLSCREEN env,SDK 预先设全屏) */
@@ -1993,7 +1993,14 @@ static int launch_app_chain(struct app *a, const char *chain)
} }
app_seq_hits++; app_seq_hits++;
app_seq_last = nw; app_seq_last = nw;
if (app_seq_hits >= 3) { /* REPORT §30(真机四连症状④):VOL_DOWN x3 是「应用内强杀」快捷键,但和普通
* 调音量(连按音量减几档)冲突——用户连按音量下键会误触发 SIGTERM→SIGKILL,
* 前台 App 闪退(ams 日志 `EXIT dev.player.ncm sig=9`)。框架 App(framework=1,
* 如 dev.player.ncm)有 SDK 级左缘横扫返回退出(D10 默认,app.c 根页
* meow_ui_request_exit),无需此强杀快捷键 → 门控到裸 App(framework=0)才触发,
* 框架 App 连按音量键只调音量不再被杀。裸 App 仍保留 VOL_DOWN x3 强杀出口
* (无框架返回手势),挂死 App 另可 `meow_ctl am kill <pkg>`。 */
if (app_seq_hits >= 3 && !a->framework) {
logmsg("kill seq: VOL_DOWN x3 -> SIGTERM app"); logmsg("kill seq: VOL_DOWN x3 -> SIGTERM app");
vol_restore(app_vol0); vol_restore(app_vol0);
kill(pid, SIGTERM); kill(pid, SIGTERM);
@@ -2002,6 +2009,8 @@ static int launch_app_chain(struct app *a, const char *chain)
reap_wait(pid, &status); /* 有界,防 D-state 挂死 */ reap_wait(pid, &status); /* 有界,防 D-state 挂死 */
ams_status_valid = 1; ams_status_valid = 1;
break; break;
} else if (app_seq_hits >= 3) {
logmsg("VOL_DOWN x3 ignored: framework app (swipe-back exits, §30)");
} }
} }
app_prev_vold = vold; app_prev_vold = vold;
@@ -309,7 +309,7 @@ struct meow_dep {
struct app { struct app {
char id[MEOW_APP_ID_MAX]; /* M2.52:app_id=app.json 的 package(权威,缺省回退卡上目录名 de->d_name),供 MEOW_LOG_APP 注入 */ char id[MEOW_APP_ID_MAX]; /* M2.52:app_id=app.json 的 package(权威,缺省回退卡上目录名 de->d_name),供 MEOW_LOG_APP 注入 */
char package[MEOW_APP_ID_MAX]; /* 安卓化:app.json 的 package 字段(反域名权威标识;目录名=package),scan_apps 据此定 app_id */ char package[MEOW_APP_ID_MAX]; /* 安卓化:app.json 的 package 字段(反域名权威标识;目录名=package),scan_apps 据此定 app_id */
char name[17]; /* ASCII display name */ char name[49]; /* display name(UTF-8,截断走 json_str 整序列保护) */
char exec[129]; /* absolute path */ char exec[129]; /* absolute path */
int ok; /* exec exists and X_OK */ int ok; /* exec exists and X_OK */
/* ---- 阶段 D · M1:app.json 路由/框架/服务/图标(scan_apps 解析)---- */ /* ---- 阶段 D · M1:app.json 路由/框架/服务/图标(scan_apps 解析)---- */
@@ -333,7 +333,7 @@ struct app {
* 与 MSG_ACT_DECLARE/HELLO(运行时)并集填充;单一写者=主循环,无需锁。 */ * 与 MSG_ACT_DECLARE/HELLO(运行时)并集填充;单一写者=主循环,无需锁。 */
struct meow_acct { struct meow_acct {
char app_id[MEOW_APP_ID_MAX]; char app_id[MEOW_APP_ID_MAX];
char name[17]; char name[49];
char exec[129]; char exec[129];
int ok; int ok;
char framework; char framework;
+20 -2
View File
@@ -515,9 +515,26 @@ static int ident_ch(char c)
} }
/* 把字符串末尾不完整的 UTF-8 序列砍掉(截断到最后一个完整码点边界)。
* 根因记录:显示名按字节截断若落在多字节序列中间,下游(面板 JSON/绘制)
* 会拿到非法 UTF-8(amsd「流媒体客户端」事故 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';
}
/* 极简 JSON/扁平值提取:在一行里找 key,读取其值(跳过 ':'/'=' 与可选引号)。 /* 极简 JSON/扁平值提取:在一行里找 key,读取其值(跳过 ':'/'=' 与可选引号)。
* 支持 JSON `"name": "Hello"` 与扁平 `framework=true`。返回拷贝到 out 的字符数。 * 支持 JSON `"name": "Hello"` 与扁平 `framework=true`。返回拷贝到 out 的字符数。
* 返回 0=未命中/空。 */ * 返回 0=未命中/空。截断做 UTF-8 整序列保护。 */
int json_str(const char *buf, const char *key, char *out, int olen) int json_str(const char *buf, const char *key, char *out, int olen)
{ {
out[0] = 0; out[0] = 0;
@@ -535,7 +552,8 @@ int json_str(const char *buf, const char *key, char *out, int olen)
out[i++] = *p++; out[i++] = *p++;
out[i] = 0; out[i] = 0;
while (i > 0 && (out[i - 1] == ' ' || out[i - 1] == '\t')) out[--i] = 0; while (i > 0 && (out[i - 1] == ' ' || out[i - 1] == '\t')) out[--i] = 0;
return i; utf8_trim_incomplete(out);
return (int)strlen(out);
} }