Skip to content

Commit 432520b

Browse files
committed
Fix Illustrator detection as application/pdf instead of application/illustrator
Given an .ai file with an application/postscript declared type, the filename extension would be ignored as a potential subtype of the application/pdf magic-byte-detected type. Fix by evaluating all candidate types rather than a single fallback.
1 parent 3af6778 commit 432520b

File tree

5 files changed

+17
-30
lines changed

5 files changed

+17
-30
lines changed

lib/marcel/mime_type.rb

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,8 @@ def extend(type, extensions: [], parents: [], magic: nil)
2727
#
2828
# If no type can be determined, then +application/octet-stream+ is returned.
2929
def for(pathname_or_io = nil, name: nil, extension: nil, declared_type: nil)
30-
type_from_data = for_data(pathname_or_io)
31-
fallback_type = for_declared_type(declared_type) || for_name(name) || for_extension(extension) || BINARY
32-
33-
if type_from_data
34-
most_specific_type type_from_data, fallback_type
35-
else
36-
fallback_type
37-
end
30+
filename_type = for_name(name) || for_extension(extension)
31+
most_specific_type for_data(pathname_or_io), for_declared_type(declared_type), filename_type, BINARY
3832
end
3933

4034
private
@@ -66,11 +60,7 @@ def for_extension(extension)
6660
end
6761

6862
def for_declared_type(declared_type)
69-
type = parse_media_type(declared_type)
70-
71-
if type != BINARY && !type.nil?
72-
type.downcase
73-
end
63+
parse_media_type(declared_type)
7464
end
7565

7666
def with_io(pathname_or_io, &block)
@@ -91,19 +81,9 @@ def parse_media_type(content_type)
9181
# For some document types (notably Microsoft Office) we recognise the main content
9282
# type with magic, but not the specific subclass. In this situation, if we can get a more
9383
# specific class using either the name or declared_type, we should use that in preference
94-
def most_specific_type(from_magic_type, fallback_type)
95-
if (root_types(from_magic_type) & root_types(fallback_type)).any?
96-
fallback_type
97-
else
98-
from_magic_type
99-
end
100-
end
101-
102-
def root_types(type)
103-
if TYPE_EXTS[type].nil? || TYPE_PARENTS[type].nil?
104-
[ type ]
105-
else
106-
TYPE_PARENTS[type].map {|t| root_types t }.flatten
84+
def most_specific_type(*candidates)
85+
candidates.compact.uniq.reduce do |type, candidate|
86+
Marcel::Magic.child?(candidate, type) ? candidate : type
10787
end
10888
end
10989
end

marcel.gemspec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,4 @@ Gem::Specification.new do |spec|
2424
spec.add_development_dependency 'rake', '~> 13.0'
2525
spec.add_development_dependency 'rack', '~> 2.0'
2626
spec.add_development_dependency 'nokogiri', '>= 1.9.1'
27-
spec.add_development_dependency 'byebug', '~> 10.0.2'
2827
end

test/illustrator_test.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
require 'test_helper'
2+
require 'rack'
3+
4+
class Marcel::MimeType::IllustratorTest < Marcel::TestCase
5+
test ".ai uploaded as application/postscript" do
6+
file = files("name/application/illustrator/illustrator.ai")
7+
assert_equal "application/illustrator", Marcel::MimeType.for(file, name: "illustrator.ai", declared_type: "application/postscript")
8+
end
9+
end

test/mime_type_test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def setup
1919
end
2020

2121
test "closes Pathname files after use" do
22+
skip if RUBY_ENGINE == "jruby"
2223
open_files = ObjectSpace.each_object(File).reject(&:closed?)
2324
assert open_files.none? { |f| f.path == @path }
2425
end

test/test_helper.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
require 'minitest/autorun'
2-
require 'byebug'
3-
42
require 'marcel'
53
require 'pathname'
64

7-
class Marcel::TestCase < MiniTest::Test
5+
class Marcel::TestCase < Minitest::Test
86
class << self
97
def setup(&block)
108
define_method(:setup, &block)

0 commit comments

Comments
 (0)