MeowPanel: 字体库 tar.gz 导入/导出 + 文件管理自然排序修复 + multipart 二进制边界修复
- 字体库导入/导出(用户 2026-08-31 定案):放弃 zip,与 .mpk 同构走 busybox 'gzip -dc | tar' 管道 (设备必带 tar/gzip,零新增依赖)。导入 POST /api/fonts/import(multipart file=<.tar.gz>,上限32MB, ?force=1 覆盖):tar -t 成员预校验(sanitize_member 拒绝对/../shell 危险字符,恰为三件套平铺)→ 解压到临时目录 → opendir/lstat 锁(拒软链/目录/设备/多出条目/解压后超大)→ font.json 解析 family/weight (safe_dir_segment 消毒)→ 覆盖冲突 409 → sha256_png/idx 仅 WARN → rename 到 MeowOS/fonts/<family>/<weight>/。 导出 GET /api/fonts/export?family=&weight=:tar -cf - | gzip -c 打包 <family>-<weight>.font.tar.gz 流式下载。 列表 GET /api/fonts:扫描三件套齐。前端设置页加「字体库」卡(导入 zip/tar.gz + 409 confirm 后 force=1 重试 + 导出按钮)。 - 文件管理排序修复:/api/files 排序改为目录优先 + 名称自然排序(数字感知 track2<track10,中文按无符号 字节序),替换原 strcasecmp 词法排序(用户报「很离谱」)。 - multipart 二进制边界修复(latent bug):strstr 遇数据内 NUL 提前停止 → memmem 语义 mem_find 字节安全查找, 修复字体 tar.gz/.mpk/二进制上传可能误吞后段的问题。 - 文档同步:docs/MEOWOS_SPEC_REF.md §5.2/§5.7.6、patch_v2/meowpanel/README.md 改 tar.gz 定案; FONT_SYSTEM.md 无 zip 表述无需改。meow_font_import_zip/export_zip 语义注为 tar.gz(_tgz 可更名)。 - 宿主编译 0 warning(-Werror 亦过);宿主端到端:导入→导出→逐字节比对、损坏/缺件/坏json/穿越/软链/非gzip全拒、 自然排序样本全过;真机已部署(meowpanel md5 51ffc183,服务 running)并 curl 验证 font 端点 + 排序。
This commit is contained in:
1 parent
4e3f41a5a3
commit
d8b95c0aab
7 files changed
+580
-23
No files matched your search
@@ -28,12 +28,14 @@ cd /home/Aska/Project/R3ProII/patch_v2/meowpanel
|
||||
- 两分支均以 `-Os -Wall -Wextra` 复核,**0 warning**(`-Werror` 亦通过)。
|
||||
- 产出(本次构建实测):
|
||||
- `meowpanel`:mipsel 静态,`ELF 32-bit LSB executable, MIPS, MIPS32 rel2, statically linked, stripped`,
|
||||
体积约 **206 KB**(固件阈值内)。md5:`24f53b40fd556f758e5eba3417a52c3c`(本次含通知 IPC 实时化 + 增量帧)。
|
||||
- `meowpanel_host`:aarch64 动态链接(宿主编译,仅供调试),体积约 **146 KB**。
|
||||
体积约 **218 KB**(固件阈值内)。md5:`be74e2ac0423718073a5a27fc7bbf96a`(本次含字体库 tar.gz 导入/导出 + 排序修复)。
|
||||
- `meowpanel_host`:aarch64 动态链接(宿主编译,仅供调试),体积约 **148 KB**。
|
||||
- 依赖:仅 libc + Linux 内核头(`linux/input.h`),零第三方库(设备无 python3/lua)。鉴权用**内联 SHA-256**(拷贝自
|
||||
`meow_verify/sha256.c` 公有领域参考写法,前缀 `mp_sha256_*` 避免符号冲突;**未改 `meow_verify/` 目录**)。
|
||||
阶段 C 实时画面用**自研最小 baseline JPEG 编码器** `mp_jpeg.c`(顺序 DCT + 4:2:0 + 标准 Huffman 表 Annex K;
|
||||
无 libm、零依赖,仅 malloc/realloc),质量 70 下 480×720 帧约 41 KB。
|
||||
**字体库导入/导出(用户 2026-08-31 定案)**:与 `.mpk` 同构、**放弃 zip,改走 busybox `gzip -dc | tar` 管道**
|
||||
(设备必带 tar/gzip,零新增依赖、不引入 zlib/miniz/自研 zip,见 §5.11)。
|
||||
**性能**:设备为 mipsel muslsf **无 FPU**,初版逐块 `double` 矩阵 DCT 编码 480×720 一帧约 **3.96 s**(掉帧到 5-6 s/帧的根因)。
|
||||
已改为**整数定点 DCT + 整数 YCbCr**(FSCALE=13,BT.601 256 系数,纯整型乘加),
|
||||
实测编码降至约 **0.19 s(≈20×)**,单请求端到端(本机 localhost)约 0.20 s、LAN 约 0.22-0.31 s,
|
||||
@@ -107,6 +109,9 @@ http://<host>.local:8080/
|
||||
| POST | `/api/files/mkdir` | 新建目录(已存在→409) | ✅ |
|
||||
| POST | `/api/files/rename` | 重命名 | ✅ |
|
||||
| DELETE | `/api/files?path=` | 删除(可 recursive=1;非空未 recursive→409) | ✅ |
|
||||
| GET | `/api/fonts` | 字体库列表(扫描 `MeowOS/fonts/<family>/<weight>/` 三件套齐) | ✅(无卡→503) |
|
||||
| POST | `/api/fonts/import` | 上传字体库 `.tar.gz`(multipart `file`,可带 `?force=1` 覆盖) | ✅(缺件/坏json/穿越→400,冲突→409,超限→413) |
|
||||
| GET | `/api/fonts/export` | 导出 `<family>/<weight>/` 三件套为 `.tar.gz`(`?family=&weight=`) | ✅(缺件→404) |
|
||||
| GET | `/api/apps` | 扫描 `MeowAPPs/` 读 `app.json` | ✅ |
|
||||
| GET | `/api/apps/:pkg` | 应用详情 | ✅ |
|
||||
| POST | `/api/apps/install` | 经 `nyai install`(multipart 或 path) | ✅ |
|
||||
@@ -274,6 +279,33 @@ http://<host>.local:8080/
|
||||
防重叠 + 旧 URL 回收;后端不可达提示「后端未连接」);默认 **1fps**,滑条 **0.2–2fps**(存 `screen.fps`,页面隐藏/切走即停刷,
|
||||
`visibilitychange` 回前台续刷);点击画面按 480×720 比例换算坐标 → `POST /api/input/tap`,`dispatched:false` 时 toast「本机触摸中」。
|
||||
|
||||
### 5.11 字体库 tar.gz 导入 / 导出(`/api/fonts*`,新增)
|
||||
- **定位**(MEOWOS_SPEC_REF §5.7.6 / FONT_SYSTEM.md,**2026-08-31 用户定案:放弃 zip,与 .mpk 同构走 tar.gz**):
|
||||
系统字库按 `MeowOS/fonts/<family>/<weight>/` 三件套存放(schema 见 SPEC_REF §5.2:family/weight/name/
|
||||
glyph_count/charset/tier/size_list/bit_depth/sha256_png/sha256_idx…)。**设备 busybox tar/gzip 必定存在**,
|
||||
后端全部走 `gzip -dc | tar` 管道(nyai .mpk 同款),**零新增依赖、不引入 zlib/miniz/自研 zip**。
|
||||
- **导入 `POST /api/fonts/import`**(multipart `file`=<.tar.gz>,上限 **`MAX_FONT_UPLOAD`=32MB**,可带 `?force=1`):
|
||||
1. multipart `file` 落临时 `<TF_CARD>/tmp/mp_font_...tar.gz`(`multipart_extract_file`,二进制安全 `mem_find`)。
|
||||
2. **成员预校验**:`gzip -dc '<tmp>' | tar -t`,每成员经 `sanitize_member`(去前导 `/`/`./`,拒 `..` 组件与
|
||||
shell 危险字符)且**恰为三件套平铺**(多出条目/子目录/绝对/`..` → 400)。
|
||||
3. **解压到临时目录**:`gzip -dc | tar -x -C stg` → opendir/lstat 锁:**恰为 3 个普通文件**
|
||||
(拒软链/目录/设备;总大小 ≤ `FONT_EXTRACT_MAX`=32MB 防 gzip 炸弹)→ 缺件/坏 json 400。
|
||||
4. `font.json` 手写 JSON 解析 → `family`(缺省回退 `name`)/`weight`(缺省 `regular`),`safe_dir_segment`
|
||||
消毒(拒 `/`、`\`、控制符、`.`/`..`)→ 非法 422。
|
||||
5. **覆盖冲突**:目标目录任一文件已存在且非 `force=1` → **409 `CONFLICT`**(前端 confirm 后带 `force=1` 重试)。
|
||||
6. **sha256 仅 WARN**(对齐 font.json 约定):流式重算 `sha256_png`/`sha256_idx` 与声明比对,不符写 `warning`
|
||||
字段、仍导入成功(**不硬失败**);响应含 `family`/`weight`/`imported`/`hint`(提示进设备「设置→字体」页
|
||||
列表自动重扫生效——**后端不触发 launcher 重扫**,扫描时机=启动/进设置页,勿加热路径)。
|
||||
7. `mkdir`(系统调用,**不用 `system()`**,防注入)→ `rename` 三件套到目标目录(原子替换)。
|
||||
- **导出 `GET /api/fonts/export?family=&weight=`**:校验 family/weight 段 → 目标目录三件套须齐(缺件 404)→
|
||||
`tar -cf - -C <font_dir> font.png font.idx font.json | gzip -c > <tmp>` 落临时文件(求 `Content-Length`)→
|
||||
`Content-Disposition: attachment; filename="<family>-<weight>.font.tar.gz"` + `application/gzip` → 流式下发。
|
||||
- **列表 `GET /api/fonts`**:扫描 `MeowOS/fonts/<family>/<weight>/`,三件套齐才列出,读 `font.json` 取
|
||||
name/tier/glyph_count(容错)。无卡 → 503。
|
||||
- **往返验证**(宿主):Python tarfile 生成的平铺三件套 `.tar.gz` 导入→导出→逐字节比对源文件一致;本后端导出
|
||||
再导入→逐字节一致;GNU tar/`tarfile` 均能读;目录穿越 `../`/绝对路径/软链成员/缺件/坏 font.json/多出条目/
|
||||
子目录包裹/非 gzip——全部拒绝;打包文件名 `<family>-<weight>.font.tar.gz`。见 §7 宿主测试备注。
|
||||
|
||||
---
|
||||
|
||||
## 6. 与协议的出入(「实现为准 + 原因」,供回改 MEOWPANEL_PROTOCOL.md)
|
||||
@@ -304,12 +336,25 @@ http://<host>.local:8080/
|
||||
11. **实时画面/触摸注入(阶段 C)**:协议 §6 待定案项称「实时画面(`/api/frame` 等,本文件暂未定义)」。本面板落地为
|
||||
**`GET /api/screen.jpeg` + `POST /api/input/tap`**(命名自定:`.jpeg` 表达二进制帧 + `input/tap` 表达触摸注入),
|
||||
见 §5.10。回改协议时可补这两端点(以及 `frames` 语义、`/api/input/tap` 的 `dispatched:false/reason` 软失败约定)。
|
||||
12. **multipart 二进制查找修正(strstr→memmem,本次修复,属 bug 修复非出入变更)**:`parse_multipart`/`multipart_extract_file`
|
||||
均用 `strstr(data_start, boundary)` 定位 part 数据边界——**strstr 遇到数据中的 NUL 字节即提前停止**(含 NUL 的二进制
|
||||
.tar.gz/.mpk/图会误把后续 boundary 与拖尾算进数据 → 解压出错)。已改**二进制安全**的 `mem_find`(memmem 语义,手写字节扫描,
|
||||
不依赖 glibc/musl 扩展)。这修复了字体库 tar.gz 导入,也顺带修复了二进制 `.mpk`/文件上传的潜在同病。**实现优先**,供回改协议/审计。
|
||||
13. **`/api/fonts*`(新增,§5.11)**:协议 §2 端点总览无此组;按 SPEC_REF §5.7.6「MeowPanel 预留 .zip 导入/导出」落地——**但用户
|
||||
2026-08-31 定案:改 tar.gz、放弃 zip**(与 .mpk 同构)。落地为 `/api/fonts`(列表)/`/api/fonts/import`(导入,POST multipart,
|
||||
上限 32MB,`?force=1` 覆盖)/`/api/fonts/export`(导出,GET,`<family>-<weight>.font.tar.gz`)。前两者由前端设置页「字体库」卡接入。
|
||||
还修正了 `/api/files` 排序:**目录优先 + 名称自然排序**(数字感知 track2<track10,中文按无符号字节序,见 §5.4)。
|
||||
**导入不触发 launcher 重扫**(扫描时机=启动/进设置页),响应用 `hint` 提示。
|
||||
|
||||
---
|
||||
|
||||
## 7. 已知边界 / 风险
|
||||
|
||||
- **单线程串行**:面板访问量极小,但并发请求会被排队(长上传/下载期间其它请求等待)。对面板用途可接受。
|
||||
- **字体导入内存/体积上限**:`POST /api/fonts/import` 上传体上限 **32MB**(`MAX_FONT_UPLOAD`,仅此端点放宽;其余
|
||||
multipart 仍 8MB);tar 解压到临时目录的总大小 ≤ `FONT_EXTRACT_MAX`=32MB(防 gzip 炸弹)。**全程不做整读进内存**
|
||||
(写临时文件 + `gzip -dc | tar` 管道 + rename),峰值内存很小,不依赖 dma/font.png 大件缓冲——相比内存解压方案的 14MB 约束更稳健。
|
||||
⚠️ 依赖设备 busybox `gzip`/`tar`(必带);若某内核裁剪过二者,导入/导出会失败(400/500),列表不受影响。
|
||||
- **无鉴权(默认)**:设备内网信任模型(协议 §1.3)。**高危端点**(`reboot/shutdown/ota/apps/删除/上传)在默认关鉴权时无鉴权,
|
||||
请勿把 8080 暴露到不可信网络。`meow_svc_power` 服务端做 `SO_PEERCRED uid==0` 基础校验(root 才受理动作),后端以 root 运行可过;launcher 电源菜单/后端同链路。
|
||||
**可选鉴权**(§5.9)开启后可对内网作加固(登录密码 + 会话),但密码经**局域网明文 HTTP** 传输,不提供 TLS。
|
||||
@@ -347,11 +392,11 @@ http://<host>.local:8080/
|
||||
|
||||
```
|
||||
patch_v2/meowpanel/
|
||||
├── meowpanel.c # 后端源码(约 4100 行,-Wall -Wextra 0 warning;含可选鉴权/内联 SHA-256/实时画面+增量帧/触摸注入/通知 IPC 实时化)
|
||||
├── meowpanel.c # 后端源码(约 4560 行,-Wall -Wextra 0 warning;含可选鉴权/内联 SHA-256/实时画面+增量帧/触摸注入/通知 IPC 实时化/字体库 tar.gz 导入导出/自然排序)
|
||||
├── mp_jpeg.c # 最小 baseline JPEG 编码器(顺序 DCT + 4:2:0 + 标准 Huffman,整数定点,无 libm,-Wall -Wextra 0 warning)
|
||||
├── mp_jpeg.h # mp_jpeg.c 接口(RGB565 → 内存 JPEG)
|
||||
├── build_meowpanel.sh # 交叉编译 + host 分支(-Wall -Wextra 0 warning)
|
||||
├── meowpanel # 交叉产物(mipsel 静态,约 206 KB,md5 24f53b40…)
|
||||
├── build_meowpanel.sh # 交叉编译 + host 分支(-Wall -Wextra 0 warning;meowpanel.c + mp_jpeg.c)
|
||||
├── meowpanel # 交叉产物(mipsel 静态,约 218 KB,md5 be74e2ac…)
|
||||
├── meowpanel_host # 宿主编译(本机 ld,调试用)
|
||||
├── services.d/
|
||||
│ └── meowpanel.conf # 部署到 TF 卡 MeowOS/services.d/meowpanel.conf
|
||||
|
||||
Reference in new issue
Block a user