diff --git a/site/checks.mjs b/site/checks.mjs index 8c98786..56d1365 100644 --- a/site/checks.mjs +++ b/site/checks.mjs @@ -1063,8 +1063,16 @@ export function checkPreviewField(rel, meta) { if (meta.preview === undefined || meta.preview === null || meta.preview === "") return []; const v = String(meta.preview); if (v === "none") return []; - if (/^https:\/\/\S+$/.test(v) && safeImageUrl(v) === new URL(v).href) return []; - if (/^https:\/\/\S+$/.test(v)) return [`${rel} preview must be an https:// image URL on a public host`]; + if (/^https:\/\/\S+$/.test(v)) { + let href = null; + try { + href = new URL(v).href; + } catch { + href = null; + } + if (href !== null && safeImageUrl(v) === href) return []; + return [`${rel} preview must be an https:// image URL on a public host`]; + } return [`${rel} preview must be "none" or an https:// image URL`]; } diff --git a/site/checks.test.mjs b/site/checks.test.mjs index 9f11841..f6ccdf6 100644 --- a/site/checks.test.mjs +++ b/site/checks.test.mjs @@ -828,6 +828,8 @@ accepts("preview field: https url", checkPreviewField("ok.md", { preview: "https rejects("preview field: http refused", checkPreviewField("bad.md", { preview: "http://a/b.png" }), 'bad.md preview must be "none" or an https:// image URL'); rejects("preview field: loopback refused", checkPreviewField("bad.md", { preview: "https://127.0.0.1/a.png" }), "bad.md preview must be an https:// image URL on a public host"); rejects("preview field: word refused", checkPreviewField("bad.md", { preview: "yes" }), 'bad.md preview must be "none" or an https:// image URL'); +rejects("preview field: unparseable https url refused", checkPreviewField("bad.md", { preview: "https://[bad" }), "bad.md preview must be an https:// image URL on a public host"); +rejects("preview field: userinfo refused", checkPreviewField("bad.md", { preview: "https://u:p@a.example/b.png" }), "bad.md preview must be an https:// image URL on a public host"); /* V30: line endings ------------------------------------------------------ */ accepts("V30 accepts LF-only text", checkLineEndings("ok.md", "---\nid: a\n---\n\nBody\n"));