关于 chrome-release-cls
这项 skill 将 Chrome Releases 博客中的安全修复映射到 Gerrit 变更列表(CL)。它检索代码库历史、Gitiles 和 Gerrit,并处理组件专属来源及受限变更。
主要功能
- 01提取 CVE 和 Bug ID
- 02搜索本地及远程历史
- 03通过 Gitiles 和 Gerrit 查找修复
- 04处理组件专属代码库
- 05追溯 cherry-pick 对应的主变更
- 06按严重级别整理结果
适用场景
- 01识别 Chrome 安全发布中的修复
- 02查找已报告 Bug 对应的上游 CL
- 03追踪 Chromium roll 提交之外的组件修复
- 04核查近期或受限的修复
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ electron/ electron --skill chrome-release-cls安装后在 Claude Code 中输入/chrome-release-cls确认已加载。
详细介绍
Chrome 发布 → 查找修复 CL
将 Chrome 发布博客文章中的每项安全修复映射到修复它的 Gerrit CL。
输入
$ARGUMENTS — 一个 https://chromereleases.googleblog.com/... URL。如果为空,请向用户索取一个。
流程
1. 从博客文章中提取 CVE → Bug ID 对
博客 HTML 会将 Bug ID 隐藏在 <a> 标签中,因此请先移除标签。运行:
curl -sL "$URL" | python3 -c '
import sys, re, html
t = re.sub(r"<[^>]+>", " ", sys.stdin.read())
t = re.sub(r"\s+", " ", html.unescape(t))
seen = set()
for m in re.finditer(r"\[\s*(\d{6,})\s*\]\s*(Critical|High|Medium|Low)\s*(CVE-\d{4}-\d+):\s*([^.]+?)\.", t):
if m.group(3) in seen: continue
seen.add(m.group(3))
print(f"{m.group(3)}|{m.group(1)}|{m.group(2)}|{m.group(4).strip()}")
' > /tmp/cve_bugs.txt
cat /tmp/cve_bugs.txt
如果没有结果,说明页面格式可能已更改——请改用 grep -oE 'CVE-[0-9]{4}-[0-9]+' 和 grep -oE 'crbug\.com/[0-9]+',并按顺序配对。
2. 查找每个 Bug 对应的修复 CL
在 Chromium 检出目录和相关子仓库的 Git 历史中搜索提交,其 Bug: 或 Fixed: 页脚引用了该 Bug ID,然后提取 Reviewed-on: Gerrit URL。
按组件关键词选择仓库:
- ANGLE →
third_party/angle - Skia、Graphite →
third_party/skia - PDFium →
third_party/pdfium - Dawn →
third_party/dawn - V8、Turbofan、Maglev、Turboshaft →
v8 - 其他所有情况 →
.(chromium/src)
如果提示的仓库中没有匹配项,也始终回退到 .。
cd /root/src/electron/src # chromium root (parent of electron/)
lookup() {
local bug="$1" repos="$2"
for repo in $repos . v8 third_party/skia third_party/angle third_party/pdfium third_party/dawn; do
local hits
hits=$(git -C "$repo" log --all --since='6 months ago' -E \
--grep="(Bug|Fixed):.*\\b${bug}\\b" --format='%H' 2>/dev/null | sort -u)
[[ -z "$hits" ]] && continue
while read -r h; do
git -C "$repo" log -1 --format='%B' "$h" | grep '^Reviewed-on:' | sed 's/^/ /'
echo " ↳ $(git -C "$repo" log -1 --format='%s' "$h")"
done <<<"$hits"
return 0
done
echo " (not found locally)"
}
以 /tmp/cve_bugs.txt 为输入。优先将不带 [M1xx] 前缀的提交主题作为规范的主 CL;带 [M1xx] 的提交是分支挑选提交。
3. 处理未命中
对于本地未找到命中的 bug:
- 运行
git -C <repo> fetch origin,然后使用--remotes重新搜索(修复可能比当前检出版本更新)。 - 搜索 gitiles 历史记录——无论是否有检出都能使用,也不需要身份验证。查询
refs/heads/main以及该版本的分支 refs(chromium/src使用refs/branch-heads/<Chromium branch number>,v8/v8使用refs/branch-heads/<V8 major.minor>;对于 chromium.googlesource.com 上的angle/angle和skia也采用同样方式,以及pdfium.googlesource.com/pdfium、dawn.googlesource.com/dawn、aomedia.googlesource.com/aom)。响应以一行)]}'开头;gitilesgrep会在整条提交消息中进行子串匹配,因此请检查命中项的Bug:/Fixed:页脚:
对于gitiles_grep() { # gitiles_grep <host> <repo> <ref> <bug> e.g. chromium v8/v8 refs/branch-heads/15.2 558734727 curl -s "https://$1.googlesource.com/$2/+log/$3?format=JSON&n=50&grep=$4" | tail -n +2 | python3 -c ' import sys, json, re for c in json.load(sys.stdin).get("log", []): if re.search(r"^(Bug|Fixed):.*\b" + sys.argv[1] + r"\b", c["message"], re.M): print(c["commit"], c["message"].splitlines()[0]) ' "$4" }chromium/src,务必使用范围限制遍历——对其完整历史执行无限制 grep 会超时(HTTP 502):将refs/branch-heads/<previous milestone's branch>..refs/branch-heads/<this branch>和refs/branch-heads/<this branch>..refs/heads/main作为 ref 传入(分支编号是 Chrome 版本号的第三部分,例如 153.0.8010.x 对应 8010;前一个里程碑的分支编号可在https://chromiumdash.appspot.com/fetch_milestones?mstone=<N-1>中查询)。子仓库规模较小,可以不受限地遍历(只需几秒)。命中结果会给出 sha、ref 和(从提交消息中获取的)Reviewed-on:CL——即使 Gerrit 拒绝显示该 CL,也应将其报告为修复。 - 直接查询 Gerrit:
curl -s "https://chromium-review.googlesource.com/changes/?q=bug:${BUG}&n=10" | tail -n +2 | python3 -m json.tool(也尝试skia-review、pdfium-review、dawn-review、aomedia-review)。 - **
b/bug 格式(Skia、Graphite、Dawn):**这些仓库在提交消息中使用b/<id>引用 bug,而不是使用Bug: <id>页脚。Gerrit 的bug:查询不会返回任何结果。请改用message:<id>搜索:
如果组件是 Dawn,也对curl -s "https://skia-review.googlesource.com/changes/?q=message:${BUG}&n=5" | tail -n +2dawn-review.googlesource.com使用相同模式。 - **从合并提交追溯主分支 CL:**如果只找到
[M1xx]合并 CL,请查询 CL 详情中的cherry_pick_of_change,以找到原始主分支 CL 编号:curl -s "https://chromium-review.googlesource.com/changes/${CL_NUM}?o=CURRENT_REVISION" | tail -n +2 | python3 -c " import sys, json d = json.load(sys.stdin) print(d.get('cherry_pick_of_change', 'none')) " - **在 Gerrit 中受限的 CL 仍可能在 git 中公开。**变更记录和仓库使用不同的 ACL,且变更通常会在提交进入 main 和 branch-heads 后数天内仍处于隐藏状态。因此,只有在 git 历史记录(本地记录以及 fetch 后的
--remotes)和 gitiles 中都没有结果时,才能判定为 RESTRICTED——仅 Gerrit 未命中并不足够。 - 如果仍未找到结果,且 bug 是最近才报告的(尤其是由“Google Threat Intelligence”报告或标记为在野利用),则该 CL 可能仍受访问限制——应报告为 RESTRICTED,而不是猜测,并标记以便重新检查(限制通常会在数小时内解除)。
4. 特殊情况
-
**Roll CL——跳过并查找上游修复:**对于修复会落在上游仓库的组件(PDFium、Dawn、Skia、Graphite、libaom、libvpx、ffmpeg),chromium-review 中的命中会是
Roll src/third_party/...提交。不要将 roll CL 报告为修复,而应直接查询组件自己的 Gerrit 实例,查找实际修复 CL:- PDFium →
pdfium-review.googlesource.com(使用bug:或message:查询) - Dawn →
dawn-review.googlesource.com(使用message:查询——采用b/格式) - Skia / Graphite →
skia-review.googlesource.com(使用message:查询——采用b/格式) - libaom →
aomedia-review.googlesource.com
只有在上游 Gerrit 实例没有返回结果时,才应退而报告 roll CL——此时请附上 roll CL,并注明实际修复位于上游,但无法确定具体 CL。
- PDFium →
-
同一提交正文中有多行
Reviewed-on::cherry-pick 会保留原始行并新增一行。第一行Reviewed-on:是原始 CL。 -
一个 bug 可能有多个不同的修复 CL(修复 + 后续加固)——请全部列出。
5. 输出
按严重级别分别生成 Markdown 表格:CVE | Bug | Component | Fix CL (main)。将 Bug 链接到 https://crbug.com/<id>。将原始输出(包括所有分支合并)保存到 /tmp/cve_cls.txt,并注明该路径。