From 041ac05d2a06a42e728c999cb14789770fc2d523 Mon Sep 17 00:00:00 2001 From: MAEDA Go Date: Mon, 5 Oct 2026 17:17:39 +0900 Subject: [PATCH] Send PDF compatible Illustrator files as application/pdf only when displayed inline --- app/controllers/attachments_controller.rb | 11 +++++------ test/functional/attachments_controller_test.rb | 7 ++++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index 3302dc0ac..7e4b01457 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -79,8 +79,11 @@ class AttachmentsController < ApplicationController end if stale?(:etag => @attachment.digest, :template => false) + # PDF compatible files, such as Illustrator files, must be sent as PDF + # when displayed inline because browsers do not display them otherwise + is_inline_pdf = disposition(@attachment) == 'inline' && @attachment.pdf_previewable? send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename), - :type => detect_content_type(@attachment), + :type => is_inline_pdf ? 'application/pdf' : detect_content_type(@attachment), :disposition => disposition(@attachment) end end @@ -298,10 +301,6 @@ class AttachmentsController < ApplicationController content_type = Redmine::MimeType.of(attachment.filename).presence || "application/octet-stream" - elsif Marcel::Magic.child?(content_type, "application/pdf") - # Send PDF compatible files, such as Illustrator files, as PDF so that - # browsers display them inline - content_type = "application/pdf" end if is_thumb && !content_type.start_with?("image/") @@ -315,7 +314,7 @@ class AttachmentsController < ApplicationController # Inline disposition can be requested only for PDF compatible files (used # by the PDF preview), to prevent XSS with e.g. HTML or SVG files def disposition(attachment) - if params[:disposition] == 'inline' && detect_content_type(attachment) == 'application/pdf' + if params[:disposition] == 'inline' && attachment.pdf_previewable? 'inline' else 'attachment' diff --git a/test/functional/attachments_controller_test.rb b/test/functional/attachments_controller_test.rb index 468f87674..8ac686ee0 100644 --- a/test/functional/attachments_controller_test.rb +++ b/test/functional/attachments_controller_test.rb @@ -469,7 +469,7 @@ class AttachmentsControllerTest < Redmine::ControllerTest assert_select 'div.filecontent.pdf object[type=?]', 'application/pdf' end - def test_download_pdf_compatible_illustrator_file_with_inline_disposition_param_should_be_sent_inline_as_pdf + def test_download_pdf_compatible_illustrator_file_should_be_sent_as_pdf_only_with_inline_disposition_param set_tmp_attachments_directory attachment = Attachment.create!( :file => mock_file_with_options( @@ -480,6 +480,11 @@ class AttachmentsControllerTest < Redmine::ControllerTest :container => Issue.find(1) ) + get(:download, :params => {:id => attachment.id}) + assert_response :success + assert_equal 'application/illustrator', @response.media_type + assert_match %r{\Aattachment}, @response.headers['Content-Disposition'] + get(:download, :params => {:id => attachment.id, :disposition => 'inline'}) assert_response :success assert_equal 'application/pdf', @response.media_type -- 2.55.0