跳转到主要内容

Oink 0.7.1:页面不再外泄,坏输入不再中断构建

Oink 0.7.1 是一次安全与校验修补。Swagger UI 不再把你的 spec 地址发给第三方, 配错的参数会告警并回退而不是中断普通构建,OpenAPI 与终端录像组件也终于像其他组件一样, 在打印、Markdown 和 RSS 中表现正常。

Oink 0.7.1 不改动任何组件 API,也不需要修改内容。它修复了对 0.7.0 主线外部审查发现的 代码问题:一个真实的隐私外泄、一类会直接中断构建的配置值,以及三个从未被告知 “非 HTML 输出"存在的组件。

概览

  • Swagger UI 不再联系在线 validator。已发布的 API 页面每次被浏览都会发出一个第三方请求,现在不会了。
  • 写在站点配置里的 URL,现在和作者写的 URL 走同一道安全检查。
  • params 中数值或布尔值写错,会告警并回退,而不是终止普通的 hugo server
  • swaggerredocasciinema 在打印、Markdown 和 RSS 中输出纯链接,只在交互 HTML 中装载运行时。

Swagger 不再向外汇报

Swagger UI 默认开启在线 validator,地址指向 validator.swagger.io。它对 localhost 跳过这个请求——这正是本地预览和浏览器测试从来看不到它的原因,也意味着每一个已经部署上线的 API 页面,都在悄悄把你的 spec 地址交给第三方。在内网站点上,那个地址就是一个内部主机名。

现在初始化写死 validatorUrl: null,并从内联 <script> 移入可缓存的 js/chunks/swagger-init.js。普通构建依然不下载任何东西,而现在普通的浏览也不再上传任何东西。

配置里的 URL 与作者写的走同一道门

有两处设置未经检查就进入了 hrefparams.ui.page_context_menu.links 里的自定义链接, 以及归档站点横幅的 params.url_latest_version。在其中任何一处写 javascript: URL, 都会渲染成一个可点击、可执行的脚本链接。

现在两者都走主题的统一 URL 策略:不支持的 scheme 会告警并丢弃该链接,而不是尝试修补。 归档版本横幅在写入页面时还会额外做 HTML 转义——因为"scheme 合法"和"放进 HTML 属性里安全” 不是一回事。

自定义链接还会跳过缺少名称或名称不是文本的条目,并且只有当确实有链接留下来时, 才渲染它们上方的分隔线。

配置写错会告警,而不再让预览挂掉

主题一直有一条规则:非法的作者或配置输入应当告警、回退到有文档记载的默认值, 并保持 hugo server 可用;而 --panicOnWarning 会在发布时把这个告警变成失败。 只是有一批数值和布尔配置从来没有接入这条规则。

在 0.7.1 之前,blog_index_size: nope 会以一个 Go 模板错误终止构建。另一些则因为安静而更糟: sidebar_width_min: -50 一声不响地输出了负的像素宽度,blog_index_columns: 2.5 把一个小数送进了 CSS 网格。

现在每一个数值与布尔配置都经过统一校验器:

输入 之前 现在
blog_index_size: nope 构建失败 告警,使用 12
blog_index_size: 0 静默变成 12 告警,使用 12
sidebar_width_min: -50 输出 -50px 告警,使用 220
sidebar_width_min: 300max: 200 布局反转 告警,使用 220/480
blog_index_columns: 2.5 小数进入 CSS 告警,使用 3
sidebar_item_overflow: clip 静默当作 ellipsis 告警,使用 ellipsis
print.toc: nope 静默当作 true 告警,使用 true

同样的处理覆盖了 Landing 各区块:hero 的 media.ratiomedia.max_width、 capabilities 的 columnsrules、以及跑马灯的 rows。其中 hero 的两个样式输入尤其值得一提—— 它们此前被原样拼进 style 属性,因此页面自己的 front matter 就能往页面上注入任意 CSS。 现在 ratio 只接受两个轨道尺寸('1fr 240px'),max_width 只接受一个纯 CSS 长度。

如果你的站点此前一直用着某个被主题静默纠正过的值,升级后会看到新的告警。这正是目的所在—— 升级后用 --panicOnWarning 构建一次,把它们找出来。

OpenAPI 与终端录像尊重其他输出

Oink 的每个组件都只渲染一次,然后适配它所在的输出:交互 HTML、静态打印、 给智能体读的纯 Markdown,以及 RSS。已有十六个组件这样做,而 swaggerredocasciinema 没有——它们把交互标记原样渲染进了全部四种输出。

结果是:Markdown 输出里带着 <div class="td-asciinema"> 和一整块 JSON 配置, 打印页面上是一个本该有播放器的空壳,而单页打印甚至真的下载了播放器运行时, 只为显示一帧静止画面。

现在三者都读取输出格式:

输出 你会得到
HTML 完整的交互组件
打印 一行带标题的静态链接,地址可见
Markdown / LLMS 一个纯 Markdown 链接,仅此而已
RSS 同样的纯链接

只有交互 HTML 会登记运行时,因此打印与机器输出不再装载播放器、Swagger 包或 ReDoc 包。 录像与 spec 地址现在同样走统一 URL 策略,而写错的 speedcolsrows 或标记时间 会告警并被忽略,不再终止构建。

其他修复

  • capabilities 的横条现在按作者写的宽度渲染。模板一直在输出这些宽度,只是样式表从未读取。
  • 生成的配置 Schema 与 Hugo 实际解析的结果一致。hugo.yaml 的行尾注释此前污染了十一个默认值—— print.toc 是以字符串 "true # section print views…" 发布的——另有四段注释挂在了错误的键上。 仅用于提示重命名的旧键不再出现在编辑器补全里。
  • heromedia 不是一个映射时会告警并丢弃该媒体,而不是终止构建。

升级

hugo mod get github.com/pgsty/[email protected]
hugo mod tidy

不需要修改内容、配置或模板。升级后建议做一件事:用 --panicOnWarning 构建一次。 那些过去被静默纠正的配置现在会开口,而这次构建就是你听到它们的地方。

完整清单见 CHANGELOG.md