meow_netmgrd 期2.1 修复:status JSON 漏闭 bt 对象(/api/net/status res.json() 必炸)

根因(patch_v2/meow_netmgrd.c build_status_json):bt 对象开 '{' 后,dns 数组之后漏收 '}',
导致 rfkill/rate 被吞进 bt、bt 与 root 均不闭合 → 外层 data 对象收尾只剩 3 个 '}',JSON 非法,
面板 /api/net/status 纯透传 MSG_NET_STATUS_RESULT(0xE0) 后 res.json() 失败。

修法:bt 的 dns 是末字段,收尾改为 ']},'(数组闭 + bt 闭 + 逗号)——不应含尾逗号
(首版 '],},' 产生 "dns":[...],} 尾逗号 JSON 非法,一并修正)。

顺手核查:build_iface_json(0xE2 单/全接口)括号配对正确、JSON 合法;conns/dns 为文本表非 JSON,不受影响。

加固:test_netmgrd.sh 增 T13b-e 端到端断言 STATUS(0xE0)/IFACE_ALL(0xE2)/IFACE_WLAN(0xE2) 的原始 JSON
可被 json.loads 完整解析(括号配对/无尾逗号/唯一有效对象)。

验证:宿主 test_netmgrd.sh 52/52、qemu-mipsel 52/52、test_netmgrd_p2(宿主+qemu) 全过、netmgrd_authtest 全过;
交叉 -Wall -Wextra 0 warning。新 meow_netmgrd md5 abfb97680b4f576f3669a3e4b3b29134(主会话热更设备)。
This commit is contained in:
MeowOS committed 2026-09-01 21:24:35 +08:00
1 parent 8e54b2c150
commit 30e2ec901f
6 files changed
+30 -1

No files matched your search

Binary file not shown.
+1 -1
View File
@@ -878,7 +878,7 @@ static void build_status_json(char *out, size_t cap)
dns_read(ns, &n); dns_read(ns, &n);
for (int i = 0; i < n; i++) { if (i) jadd(&w, ","); jadd(&w, "\"%s\"", ns[i]); } for (int i = 0; i < n; i++) { if (i) jadd(&w, ","); jadd(&w, "\"%s\"", ns[i]); }
} }
jadd(&w, "],"); jadd(&w, "]},"); /* 关闭 dns[] + bt 对象 + 逗号(dns 是 bt 末字段,不能留尾逗号;此前漏收 bt 致 rfkill/rate 被吞、root 不闭合) */
rfkill_list(); rfkill_list();
jadd(&w, "\"rfkill\":["); jadd(&w, "\"rfkill\":[");
Binary file not shown.
Binary file not shown.
+29
View File
@@ -203,6 +203,35 @@ ck T12b "proxy disabled" "$OUT"
OUT=$(env $ENVS $Q "$T/meow_net" dns flush 2>&1) OUT=$(env $ENVS $Q "$T/meow_net" dns flush 2>&1)
ck T13a "permission denied" "$OUT" ck T13a "permission denied" "$OUT"
# ---- T13b: 端到端 JSON 合法性(STATUS_0xE0 / IFACE_0xE2 可被完整解析,括号配对/无尾逗号)----
JOUT=$(python3 - "$T/net.sock" <<'PYEOF'
import socket,struct,sys,json
s=socket.socket(socket.AF_UNIX,socket.SOCK_STREAM); s.connect(sys.argv[1]); s.settimeout(2)
def recvn(n):
d=b""
while len(d)<n:
c=s.recv(n-len(d))
if not c: return d
d+=c
return d
def req(typ,payload=b""):
s.sendall(struct.pack('<IHHII',0x4D4F5701,1,typ,1,len(payload))+payload)
H=struct.unpack('<IHHII', recvn(16)); body=recvn(H[4])
code,jlen=struct.unpack('<IH',body[:6]); return body[8:8+jlen].decode('utf-8','replace')
ok=1
for nm,typ,pl in [("STATUS",0x00E0,b""),("IFACE_ALL",0x00E2,b"\x00"*32),("IFACE_WLAN",0x00E2,b"wlan0"+b"\x00"*27)]:
js=req(typ,pl)
try:
json.loads(js); sys.stdout.write("%s VALID\n" % nm)
except Exception as e:
sys.stdout.write("%s INVALID %s\n" % (nm,e))
PYEOF
)
ck T13b "STATUS VALID" "$JOUT"
ck T13c "IFACE_ALL VALID" "$JOUT"
ck T13d "IFACE_WLAN VALID" "$JOUT"
echo "$JOUT" | grep -q "INVALID" && { FAIL=$((FAIL+1)); echo "FAIL T13e 存在无效 JSON"; } || { PASS=$((PASS+1)); echo "PASS T13e no INVALID"; }
# ---- T14: DNS 代理 wire 实测(守护 B:高端口 + 桩上游 + 全局 deny;测 deny/forward/cache)---- # ---- T14: DNS 代理 wire 实测(守护 B:高端口 + 桩上游 + 全局 deny;测 deny/forward/cache)----
HOSTIP=$(hostname -I 2>/dev/null | awk '{print $1}') HOSTIP=$(hostname -I 2>/dev/null | awk '{print $1}')
[ -n "$HOSTIP" ] || HOSTIP="127.0.0.1" [ -n "$HOSTIP" ] || HOSTIP="127.0.0.1"
Binary file not shown.