Defect #44358
openMarkdownized preview shows broken images: Pandoc emits <img src="media/..."> but media is never extracted
Description
The Markdown-based preview for Office attachments introduced in 7.0 (feature #8959) renders broken image icons for documents that contain images. For documents that consist mostly of images, the entire preview is a set of broken icons.
I checked for duplicates first: #8959 is the closed feature request itself, and #44029 and #44225 are related but different. I found no existing report about media handling in markdownized previews.
Steps to reproduce¶
- Install Pandoc so that markdownized previews are enabled (verified with 3.10.2)
- Create a .docx containing one or more images
- Attach it to an issue and open the attachment preview
Actual behaviour¶
Every image is rendered as a broken image icon, and the web server access log shows:
GET /attachments/media/image1.png -> 404 GET /attachments/media/image2.png -> 404
Expected behaviour¶
The preview should not reference resources that were never produced. Either the media is extracted and served, or the image elements are removed, ideally replaced by a short note such as "N image(s) are not shown in this preview", so that an image-only document does not look like a rendering failure.
Cause¶
Redmine::Markdownizer#convert builds a fixed command line in lib/redmine/markdownizer.rb:49:
args = [COMMAND, source, "-t", "gfm"]
There is no --extract-media, so the image files are never written anywhere. Pandoc does not drop the images, though: for images carrying size attributes it emits raw HTML with a relative path, for example:
<img src="media/image1.png" style="width:10.68557in;height:6.01042in" />
app/views/attachments/markdownized.html.erb renders that content through common/markup with markup_text_formatting = 'common_mark'. The CommonMark formatter allows raw HTML (unsafe: true) and then sanitizes it; the sanitizer strips dangerous attributes but keeps the img element and its src. The browser resolves the relative path against the attachment URL, which produces the 404s above.
Measured example¶
A 504 KB .docx containing two images produced a 147-byte preview consisting of exactly two img tags. The 100 KB output cap (markdownized_preview_max_output_size) is not involved.
No stack trace available¶
There is nothing to attach: no exception is raised and production.log stays completely silent. Pandoc exits 0, the preview is generated and cached successfully, and the failure is visible only in the browser and as 404s in the web server access log. That silence is part of the problem, because an administrator gets no server-side signal that previews are broken.
Not a security issue¶
Verified on this installation: passing <img src="media/x.png" onerror="alert(1)" /><script>alert(2)</script> through Redmine::WikiFormatting.to_html('common_mark', ...) returns <img src="media/x.png"> with the onerror attribute removed and the script tag escaped. The sanitizer works as intended; this report is only about referencing files that do not exist.
Not an installation problem¶
dpkg -V reports no modified files, only one pandoc binary is present, and a control run of the same document with --extract-media extracts image1.png and image2.png and rewrites src to their absolute paths. Pandoc behaves exactly as documented; the missing flag is on the Redmine side.
Possible fixes¶
- Option A: run Pandoc with
--extract-mediainto a per-attachment subdirectory ofAttachment.markdownized_previews_storage_path, serve those files through AttachmentsController under the same permission checks as the attachment itself, and rewrite the src paths. New settings could bound the cost, for examplemarkdownized_preview_max_media_countandmarkdownized_preview_max_media_total_size. Note that serving the extracted media as plain static files would bypass Redmine permission checks and expose attachments of private issues, so it has to go through the controller. - Option B, minimal: post-process the Pandoc output to drop image elements and render a short note about the omitted images.
Environment¶
Redmine version 7.0.0.stable.24900 Ruby version 3.2.0-p0 (2022-12-25) [x86_64-linux] Rails version 8.1.3.1 Environment production Database adapter PostgreSQL Mailer queue ActiveJob::QueueAdapters::AsyncAdapter Mailer delivery smtp Redmine theme Default SCM: Subversion 1.14.1, Git 2.34.1, Filesystem
Source: svn branches/7.0-stable, working copy r24907, last changed r24900. PostgreSQL 14.23, Pandoc 3.10.2, Passenger 6.0.24 with Apache, Ubuntu 22.04.