Skip to content

✅ 修正资源分类边界并降低页面脚本资源开销 - #1686

Open
cyfung1031 wants to merge 7 commits into
mainfrom
codex/add-performance-verification-tests
Open

✅ 修正资源分类边界并降低页面脚本资源开销#1686
cyfung1031 wants to merge 7 commits into
mainfrom
codex/add-performance-verification-tests

Conversation

@cyfung1031

@cyfung1031 cyfung1031 commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

摘要

修复脚本资源从 Service Worker 传到页面执行上下文时的边界问题,并降低每个标签页保留的资源 payload。
PR 仍保持为 draft,等待人工 review。 已測試

根因

ResourceService 原先把 @require@require-css@resource 合并到一个 string-keyed map;随后页面边界会把整个 map 转发。这样既会把已经编译进注入代码的 @require 重复带入每个标签页,也会把未授权的 @resource 带入页面。更重要的是,同一个 key 在不同资源类别中出现时,合并会丢失类别来源,可能让 JavaScript 或 CSS 消费到错误的资源内容。

实现

  • 增加共享的 @resource <name> <url> 解析器,生产者和页面筛选器使用同一套严格规则;非法声明不会创建资源或触发下载。
  • 在 Service Worker 内保留 requirerequire-cssresource 三个类别的独立 map;保留旧的合并 map 作为兼容形状,但编译、CSS 注入、页面缓存和本地资源刷新都使用类别来源。
  • 页面边界只转发:
    • 有效资源权限允许的 @resource 名称;
    • @require-css 声明的 CSS 资源;
    • 不转发已经进入编译代码的 @require
  • 资源 grant 与实际执行语义一致,覆盖 legacy/modern resource grant、普通 @grant none 和 context-menu 场景。
  • 保留 metadata 声明顺序、资源内容、base64/contentType 以及本地 file:/// 刷新行为。

验证覆盖

  • resource grant 组合:GM_getResourceTextGM_getResourceURLGM.getResourceTextGM.getResourceUrl
  • 普通 @grant none、context-menu 的 none 与 resource grant 组合。
  • malformed @resource、输入不变性和资源值完整性。
  • @require 编译顺序及页面 payload 不重复转发。
  • 两个 @require-css 的 metadata 顺序,以及 CSS key 与 @resource key 冲突时的类别隔离。
  • ResourceService 类别保留、运行时 page cache/local refresh,以及既有 sandbox、value-update 和 execution-path tests。

验证结果

  • pnpm run typecheck — 通过。
  • pnpm test -- --run — 受限环境第一次运行因验证工具监听 127.0.0.1EPERM 阻断;在允许本地监听的环境重跑后 341 个文件、4223 项全部通过
  • pnpm run build — 通过;仅有既有 bundle-size 与 Monaco 动态 require 警告。
  • focused Vitest — 资源、content executor、resource service、runtime/script tests 通过;组合测试 121 项通过。
  • isolated browser verification — 通过真实 built extension:@require 先输出 PR1686_REQUIRE_LOADED,随后 page-side result 为 {"resourceText":"resource payload","resourceUrlIsData":true,"cssValue":"ok"}
  • commit hooks — typecheck、Prettier、issue-template check 通过。

远端 checks 中 lint、两组 test shard、四组 E2E 和 License Compliance 均通过。codecov/project 目前失败的原因是项目总覆盖率由 base 的 70.07% 变为 70.04%(下降 0.03 个百分点);本次 patch 覆盖率为 80.6%。没有为了通过该总量指标加入无语义的测试填充。

本 PR 未进行精确 heap benchmark;性能收益来自页面边界不再传输/保留无关资源,定量内存对比留给后续 profiling。

提交顺序

  • dd24ac17 — page resource boundary filter
  • 9efb062b — grant and resource boundary tests
  • 3a04d08b — category-preserving production implementation
  • bed1598b — category-preserving verification tests

范围

  • Base: main
  • Branch: codex/add-performance-verification-tests
  • PR remains draft.

@cyfung1031 cyfung1031 changed the title ✅ 增加脚本执行路径验证测试 ✅ 修正资源分类边界并降低页面脚本资源开销 Aug 22, 2026
@cyfung1031
cyfung1031 marked this pull request as ready for review August 22, 2026 01:32
@cyfung1031

cyfung1031 commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator Author

结论:发现一个 P2,建议 Request changes,置信度高。

[P2] 非法 @resource 声明仍可能触发安装下载

位置:

触发值:

" https://example.com/payload"

新解析器:

value.split(/\s+/)
// ["", "https://example.com/payload"]

会因首项为空而拒绝。但安装路径中的旧逻辑:

const split = u.split(/\s+/);
if (split.length === 2) {
  url = split[1];
}

会把第二项当作 URL,继续进入 parseUrlSRIupdateResource,可能发起网络请求并持久化资源。

因此,PR 声称的“非法声明不会创建资源或触发下载”并未覆盖安装路径。

建议:

  • updateResourceByTypes 复用 parseResourceDeclaration
  • 增加直接覆盖安装路径的回归测试。

结论:发现 1 个 Medium finding,建议修改后合并。
证据路径:

  1. script.ts (line 897) 同时生成 resourceByType 和合并后的 resource。
  2. 后台/定时脚本经 offscreen/script.ts (line 56) 送入 Sandbox。
  3. gm_api.ts (line 1559) 仍读取 scriptRes.resource。
  4. 因此,声明 lib.js 并授予 GM_getResourceText 的后台脚本,可以用该 URL 读取 @require 内容,即使没有对应的 @resource
    建议修复:
  • GM Resource API 存在 resourceByType 时只读取 resourceByType.resource。
  • 仅对旧格式、没有分类表的 payload 回退到 resource。
  • 增加后台脚本和定时脚本回归测试。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant