Files
AskaEth c730333776 fix(launcher): §310 追加两修——未冻结App锁屏输入穿透(独占触控) + 主界面应用名截断
真机 M6.3 反馈(bcef8e0 三连修复未好全,追加两问题):

P1 锁屏 PIN 输入穿透仍在(媒体保活 App 实时读 evdev)
  根因:媒体保活 App(播放中)从不 SIGSTOP(保 PCM),SDK 输入线程实时读 evdev,不走缓冲。
  bcef8e0 的「SIGCONT 排空」只作用于冻结 App;对未冻结 App,隔离全靠 /tmp/meow_notif_active
  让 SDK 排空——若 App 的 meow_ui.a 缺该排空(或节流窗内漏网),锁屏期触摸依旧抵达 App。
  修法:run_lock_screen() 与 lck_input_pin_modal() 打开 DEV_TOUCH 后 EVIOCGRAB 独占触控设备
  (真机 goodix 实测 EVIOCGRAB 返回 0)——抓取期事件只投递抓取者、不为其它 fd 缓冲/回放,
  故**任何**前台进程(冻结或未冻结)锁屏期都收不到触摸(真全模态)。失败时记日志降级
  (仍靠标记+SIGSTOP 隔离)。overlay_gate.h 增 overlay_keepalive_needs_grab 判据。

P2 主界面应用名只显示 5 字(「流媒体客户」式,半字残形)
  根因:app_launcher.c `strncpy(a->name, name, 16)` 仍把显示名硬截 16 字节——M6.3 只扩了
  name[49]+json_str 整序列,漏改此二处。UTF-8 下 16B = 5 汉字 + 「端」首字节 + 无 NUL,
  显示成「流媒体客户」+ 残形;main_menu.c menu_name_fit 按字节回退又停在半截字符、加 "..." 溢出。
  修法:新增 meow_utf8.h(meow_utf8_char_len / meow_utf8_copy_bounded,纯决策可单测)——
  app_launcher.c 两处 strncpy(16) 改 app_name_copy(=copy_bounded, 拷满 sizeof name=49);
  menu_name_fit 改整字符前进 + 预留省略号宽度(mfont 用「…」/点阵用 "..."),总宽 ≤ maxw,
  绝不劈开多字节字符。

新增 test_utf8_name.c(14 断言:整字符长/整序列有界拷贝,含 cap=16/17/12 边界不劈字)+
  test_overlay_gate.c 扩展(S1b 未冻结 App 靠 EVIOCGRAB 隔离 4 断言)。launcher 全量宿主回归
  + SDK 叠加/状态栏/输入回归全 PASS;mipsel 交叉 -Wall -Wextra 0 warning。
md5 56dac860841c3884b4322707246e22af(/usr/bin 只读,待固件打包 M6.4;fw_content.conf 未动)。
2026-09-02 08:13:55 +08:00

66 lines
3.6 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* test_utf8_name.c — 问题2(主界面应用名截断)宿主单测:UTF-8 整序列有界拷贝 / 字符步进。
*
* 背景(M6.3 真机):主界面应用名「流媒体客户端」被截成 5 字 + 半个字。真因 = app_launcher.c
* `strncpy(a->name, name, 16)` 仍把显示名硬截 16 字节(UTF-8 下 16B = 5 汉字 + 「端」首字节),且
* main_menu.c `menu_name_fit` 按字节回退停在半截字符、加 "..." 又溢出 maxw。本测试验证 meow_utf8.h
* 的整序列有界拷贝:绝不劈开多字节字符、给出完整汉字序列(修复 strncpy(16) 与 menu_name_fit)。
*
* 编译运行(在 patch_v2/meow_launcherd 下):
* gcc -Wall -Wextra -o test_utf8_name test_utf8_name.c && ./test_utf8_name
* 全 PASS -> exit 0。
*/
#include <stdio.h>
#include <string.h>
#include "meow_utf8.h"
static int g_pass = 0, g_fail = 0;
#define CHECK(cond, msg) do { \
if (cond) { g_pass++; printf("PASS %s\n", msg); } \
else { g_fail++; printf("FAIL %s\n", msg); } \
} while (0)
int main(void)
{
/* meow_utf8_char_len:由首字节求整字符长。 */
CHECK(meow_utf8_char_len('A') == 1, "char_len ASCII = 1");
CHECK(meow_utf8_char_len((unsigned char)0xC3) == 2, "char_len 2-byte lead = 2");
CHECK(meow_utf8_char_len((unsigned char)0xE6) == 3, "char_len 3-byte lead = 3");
CHECK(meow_utf8_char_len((unsigned char)0xF0) == 4, "char_len 4-byte lead = 4");
CHECK(meow_utf8_char_len((unsigned char)0x80) == 1, "char_len lone continuation = 1 (no merge)");
/* meow_utf8_copy_bounded:不劈多字节字符。 */
char buf[64];
/* 源「流媒体客户端」= 18B(6×3B)。cap=49 → 全量(修复 strncpy(16) 后的正确行为)。 */
meow_utf8_copy_bounded(buf, (int)sizeof buf, "流媒体客户端");
CHECK(strcmp(buf, "流媒体客户端") == 0, "copy cap=49 keeps full '流媒体客户端'");
CHECK(strlen(buf) == 18, "copy cap=49 len=18 (6 chars)");
/* cap=16(旧 bug 的容量):旧 strncpy(16) 给 5 汉字+半个字+无NUL;现应给 5 整汉字+ NUL。 */
meow_utf8_copy_bounded(buf, 16, "流媒体客户端");
CHECK(strcmp(buf, "流媒体客户") == 0, "copy cap=16 -> 5 whole chars '流媒体客户'");
CHECK(strlen(buf) == 15, "copy cap=16 -> 15 bytes (5 CJK, no partial 6th)");
/* cap=17:尾部「端」首字节越界 → 整字符去掉,仍 5 整汉字,绝不半字残形。 */
meow_utf8_copy_bounded(buf, 17, "流媒体客户端");
CHECK(strcmp(buf, "流媒体客户") == 0, "copy cap=17 -> still 5 whole chars (no partial)");
/* cap=12:缓冲区 12B 含 NUL → 内容上限 11B,4 整汉字(12B)放不下 → 截到 3 整汉字(绝非半字)。
* 注:snprintf 语义 = cap 字节含 NUL,故内容 ≤ cap-1(旧 strncpy(dst,src,12) 拷 12B 无 NUL,
* 有越界读风险;此处改为安全 NUL 结尾,代价是内容少 1B——正确取舍)。 */
meow_utf8_copy_bounded(buf, 12, "流媒体客户端");
CHECK(strcmp(buf, "流媒体") == 0, "copy cap=12 -> 3 whole chars '流媒体' (no partial 4th)");
/* ASCII / 混合:不劈 ASCII。 */
meow_utf8_copy_bounded(buf, (int)sizeof buf, "Hello App");
CHECK(strcmp(buf, "Hello App") == 0, "copy ASCII unchanged");
/* NULL/空源安全性。 */
meow_utf8_copy_bounded(buf, (int)sizeof buf, NULL);
CHECK(buf[0] == 0, "copy NULL src -> empty");
meow_utf8_copy_bounded(buf, 1, "流媒体客户端");
CHECK(buf[0] == 0, "copy cap=1 -> empty (no write overflow)");
printf("\n%s (%d passed, %d failed)\n", g_fail ? "SOME TESTS FAILED" : "ALL PASS", g_pass, g_fail);
return g_fail ? 1 : 0;
}