🔒 为用户脚本执行入口加入构建期调用令牌并显式传递上下文 - #1735
Open
cyfung1031 wants to merge 7 commits into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist / 检查清单
Description / 描述
背景
ScriptCat 的普通脚本、inject 与 pre-inject 执行路径都需要把已编译的脚本函数交给执行器,再以 ScriptCat 创建的执行上下文启动用户脚本。现有流程中,部分入口通过
window[flag]完成函数交接,同时脚本主体依赖调用时的this作为全局执行上下文。本 PR 保留现有跨环境交接流程,在执行入口增加一层统一的调用约束,并把执行上下文的提供方收敛到
ExecScript。这样可以在不重构现有脚本加载与 early-start 生命周期的前提下,让“谁可以进入目标函数”和“脚本以哪个上下文执行”成为两个明确的步骤。本次改动
SC_RANDOM_FNKEY,作为脚本执行包装器与ExecScript之间的调用令牌。SC_ZN_RAND,作为执行上下文临时方法名的构建级随机前缀;包装器再追加运行时随机值,降低临时属性名称碰撞。ScriptFunc统一调整为接收token、context、named globals 与 script name;ExecScript.exec()显式提供这些参数。compileScript、inject 与 pre-inject 入口使用相同的调用约束:令牌匹配后才进入目标函数。context[key](...)的方法调用形式启动,从而保留 userscript 所需的this === context语义,同时不依赖.call()、.apply()或.bind()。codeFunction(),减少不同执行路径之间的实现差异。实现考虑
构建期调用令牌
调用令牌由构建阶段生成,而执行包装器与
ExecScript又来自同一套构建产物,因此无需为每个脚本额外维护运行时握手或状态对象,就可以给已有执行入口增加一致的调用约束。页面直接取得挂载函数后,如果没有 ScriptCat 执行器提供的令牌,不会进入目标脚本。执行上下文由执行器显式提供
旧调用方式把目标函数的
this与调用形式绑定在一起。本 PR 改为由ExecScript明确传入execContext,包装器只负责校验并启动目标函数。这样执行上下文的来源更清晰,也让普通编译脚本、inject 与 pre-inject 可以使用同一套调用契约。通过临时方法调用保留
thisuserscript 执行仍需要目标函数中的
this指向 ScriptCat 构造的上下文。实现先把目标函数写入context[key],再以对象方法形式调用,因此 JavaScript 原生调用语义会把 receiver 保持为该 context。临时属性会在参数求值阶段删除,因此目标函数真正开始执行时不会继续保留该挂载。统一生成代码与运行时契约
compileScript与生成到 MAIN-world 的 inject / pre-inject 包装器遵循相同的参数顺序和执行规则;inject / pre-inject 又共用codeFunction()生成包装代码。这样后续维护执行入口时可以围绕同一组不变量验证行为:令牌校验、context 绑定、参数透传和临时属性清理。验证
main@12fa384e3c108b19dd5944965498d9e9b8958221→security/fix-001@9982549d4fa586f21d79d1e3e1e3943932873ff9。src/app/service/content/utils.test.ts新增对生成 inject / pre-inject 代码的实际执行测试,通过new Function(...)验证生成结果可运行。compileScript继续覆盖同步、异步、异常传播与错误令牌不执行目标代码等行为。9982549d4fa586f21d79d1e3e1e3943932873ff9的 License Compliance 状态为 success。Screenshots / 截图
N/A — 本 PR 仅调整 userscript 执行包装器、构建常量与相关测试,无 UI 变更。