Skip to content

fix: strip spurious default-image-extension from shortcode and empty-URL image sources#14634

Merged
cderv merged 2 commits into
mainfrom
fix/default-image-extension-global
Jun 29, 2026
Merged

fix: strip spurious default-image-extension from shortcode and empty-URL image sources#14634
cderv merged 2 commits into
mainfrom
fix/default-image-extension-global

Conversation

@cderv

@cderv cderv commented Jun 29, 2026

Copy link
Copy Markdown
Member

Pandoc appends default-image-extension to any extensionless image source at parse time. No URL guard exists in Pandoc (confirmed against Pandoc HEAD source). This breaks two cases:

Fix

The shortcode case is fixed after the shortcode resolves in shortcodes.lua, where the resolved path is finally known: the appended default extension is stripped only when the resolved path already carries an extension of its own. This preserves the multi-format workflow — a shortcode resolving to an extensionless path (e.g. figures/plot) keeps the appended default so format-specific rendering still works.

The URL case is fixed in the normalize stage (fixupdatauri.lua), only for the provably-spurious empty-filename form (path ends in /.ext). A URL with a non-empty last segment — such as https://badgen.net/badge/name parsed to https://badgen.net/badge/name.png — is byte-identical to a real file URL after parsing and is left untouched. The documented workaround (default-image-extension: "") remains for badge-style URLs; a proper fix requires a URI guard upstream in Pandoc.

Fixes #14583, related to #6092

…URL image sources

Pandoc appends default-image-extension to any extensionless image source at
parse time, with no URL guard (confirmed against Pandoc HEAD source). This
breaks two cases:

- A shortcode used as an image source is parsed without an extension, so
  Pandoc appends the default. When the shortcode later resolves to a path that
  already has its own extension, the result carries a doubled extension (e.g.
  logo.png.png, or logo.png.svg in Typst where the default differs) (#14583).
- An extensionless URL ending in a slash gets the extension appended, breaking
  embed/iframe syntax (#6092).

The shortcode case is fixed after the shortcode resolves, where the resolved
path is finally known: the appended default extension is stripped only when the
resolved path already carries an extension of its own, so the multi-format
workflow (a shortcode resolving to an extensionless path) keeps its appended
extension. The URL case is fixed in the normalize stage, only for the
provably-spurious empty-filename form; a URL with a non-empty last segment is
indistinguishable from a real file after parsing and is left untouched.
@posit-snyk-bot

posit-snyk-bot commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@cderv cderv merged commit ecb482c into main Jun 29, 2026
51 checks passed
@cderv cderv deleted the fix/default-image-extension-global branch June 29, 2026 13:28
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.

Image missing https://quarto.org/docs/computations/python.html#positron

2 participants