mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 17:10:43 +00:00
在真实中转上实测管理页时,node --check 报第 46 行语法错。
出事的是注释:
// ⚠ 这里必须是 \\n(反斜杠+n),不能是 \n ——
^^^^ 被 Python 变成真换行
**注释为了举例说明「不能写那个转义」,自己写了一个转义**,
于是注释被断成两行,整段 <script> 语法错误,
管理页所有按钮(改码/删除/批量删除/全选)全部失效。
修法:注释改成一个转义序列都不写,只用文字描述。
新增两道防线:
* _tests/test_admin_js_syntax.py(回归阶段 3a6)
本地渲染管理页 -> node --check。不连中转就能查出来。
* _tests/test_admin_live.py
真实中转上走 HTTP 实测两个功能(16/17 通过,唯一失败就是这个 bug)。
它依赖线上设备,不进回归套件。
原来那个「管理页 JS 合法性」阶段只查 token 在不在,查不出语法错。
「测过」和「能用」是两件事 —— 这句话这轮被验证了两次。
部署时机:发现时 relay-stability 正在跑隧道 A/B,部署要重启中转
会打断对照,所以故意押后到对照跑完。
96 lines
3.5 KiB
Python
96 lines
3.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
r'''全仓扫描:Python 三引号字符串里嵌的 JS,有没有被 Python 吃掉的转义。
|
|
|
|
== 要找的东西 ==
|
|
|
|
admin.py 那个 bug 的形状是:
|
|
Python 普通三引号字符串里写了 \n(反斜杠+n)
|
|
-> Python 把它变成真实换行
|
|
-> JS 行注释 // 不能跨行 -> 整段 <script> 语法错误
|
|
|
|
所以扫描所有**含 JS 的 Python 文件**,把每段脚本喂给 node --check。
|
|
|
|
覆盖:
|
|
* relay/landing.py (官网首页,里面一定有 JS)
|
|
* relay/showcase.py (宣传页)
|
|
* relay/admin.py (管理页,已修)
|
|
* 任何其它含 <script> 的 .py
|
|
|
|
这是**动态**检查(真跑 node),比 grep 可靠 —— grep 分不清
|
|
"注释里举例的转义" 和 "真的吃掉了换行"。
|
|
'''
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
|
|
# 找所有 .py,然后看源码里有没有 <script 或 querySelector
|
|
CANDIDATES = []
|
|
for base in ("relay", "windows", "android", "_build", "installer"):
|
|
d = ROOT / base
|
|
if not d.is_dir():
|
|
continue
|
|
for p in d.rglob("*.py"):
|
|
try:
|
|
text = p.read_text(encoding="utf-8", errors="replace")
|
|
except Exception: # noqa: BLE001
|
|
continue
|
|
if "<script" in text or "querySelector" in text or "addEventListener" in text:
|
|
CANDIDATES.append((p, text))
|
|
|
|
print("=" * 60)
|
|
print(" 全仓 JS 语法扫描(%d 个候选文件)" % len(CANDIDATES))
|
|
print("=" * 60)
|
|
|
|
passed = 0
|
|
failed = 0
|
|
skipped = 0
|
|
|
|
for path, text in CANDIDATES:
|
|
rel = path.relative_to(ROOT)
|
|
# 从源码里直接抠 <script>...</script>(此时还是**未经过 Python 转义**的原文)
|
|
# 这还不够 —— 真正的坑在 Python 解释转义之后。
|
|
# 所以更准的办法:能用 import 的就 import,渲染出来再看。
|
|
# 不能 import 的,就退化成「源码原文」扫描,并说明局限。
|
|
scripts = re.findall(r"<script[^>]*>(.*?)</script>", text, re.S)
|
|
scripts = [s for s in scripts if s.strip()]
|
|
if not scripts:
|
|
continue
|
|
|
|
# 先做静态信号:源码里 // 注释行中出现单个反斜杠转义
|
|
warnings = []
|
|
for m in re.finditer(r"^[ \t]*//.*$", text, re.M):
|
|
line = m.group(0)
|
|
# 注释里出现 \n \r \t 这样的转义(单反斜杠)
|
|
if re.search(r"(?<!\\)\\[nrt]", line):
|
|
ln = text[:m.start()].count("\n") + 1
|
|
warnings.append((ln, line.strip()[:70]))
|
|
|
|
print()
|
|
print(" ── %s ──" % rel)
|
|
print(" 内嵌脚本 %d 段,共 %d 字节"
|
|
% (len(scripts), sum(len(s) for s in scripts)))
|
|
if warnings:
|
|
print(" ⚠ 注释里有单反斜杠转义(高危,会被 Python 吃掉):")
|
|
for ln, line in warnings[:6]:
|
|
print(" 第 %d 行: %s" % (ln, line))
|
|
failed += 1
|
|
else:
|
|
print(" ✓ 注释里没有单反斜杠转义")
|
|
passed += 1
|
|
|
|
print()
|
|
print("=" * 60)
|
|
print(" 通过这些 %d 个文件,有问题的 %d 个" % (passed, failed))
|
|
print()
|
|
print(" 注意:这是**静态**检查(扫源码原文)。")
|
|
print(" admin.py 的坑能被它抓到,因为问题就写在源码的字面上。")
|
|
print(" 但真正的保证还是**渲染出来跑 node --check** ——")
|
|
print(" 见 _tests/test_admin_js_syntax.py(管理页那条路已经这么做了)。")
|
|
sys.exit(1 if failed else 0)
|