Project

General

Profile

Feature #44362 » 0001-Extract-the-fallback-for-undetermined-content-types-.patch

Go MAEDA, 2026-08-20 13:53

View differences:

app/controllers/attachments_controller.rb
294 294
  end
295 295

  
296 296
  def detect_content_type(attachment, is_thumb = false)
297
    content_type = attachment.content_type
298
    if content_type.blank? || content_type == "application/octet-stream"
299
      content_type =
300
        Redmine::MimeType.of(attachment.filename).presence ||
301
        "application/octet-stream"
302
    end
297
    content_type = Redmine::MimeType.infer_type(attachment.content_type, attachment.filename)
303 298

  
304 299
    if is_thumb && !content_type.start_with?("image/")
305 300
      # Thumbnails of non-image files are stored in PNG format
app/helpers/icons_helper.rb
160 160
  end
161 161

  
162 162
  def icon_for_mime_type(mime, filename = nil)
163
    # Content type detection falls back to application/octet-stream when it
164
    # cannot tell the type from the file contents. In that case only, guess
165
    # the type from the filename, as AttachmentsController#detect_content_type
166
    # does.
167
    if filename.present? && (mime.blank? || mime == 'application/octet-stream')
168
      mime = Redmine::MimeType.of(filename)
169
    end
163
    mime = Redmine::MimeType.infer_type(mime, filename)
170 164

  
171 165
    MIME_TYPE_ICONS[mime] ||
172 166
      MIME_TYPE_ICONS[mime.to_s.split('/').first] ||
lib/redmine/mime_type.rb
73 73
      end
74 74
    end
75 75

  
76
    # Returns content_type, or the type guessed from name if content_type is
77
    # undetermined, ie. blank or application/octet-stream
78
    def self.infer_type(content_type, name)
79
      if content_type.blank? || content_type == 'application/octet-stream'
80
        of(name).presence || 'application/octet-stream'
81
      else
82
        content_type
83
      end
84
    end
85

  
76 86
    # Returns the css class associated to
77 87
    # the mime type of name
78 88
    def self.css_class_of(name)
test/unit/lib/redmine/mime_type_test.rb
37 37
    assert_nil Redmine::MimeType.of('test.unk')
38 38
  end
39 39

  
40
  def test_infer_type
41
    to_test = {
42
      # A determined type is returned as is, even if the filename suggests
43
      # another type
44
      ['text/html', 'not-really-an-image.png'] => 'text/html',
45
      # An undetermined type is resolved from the filename
46
      ['application/octet-stream', 'test.pdf'] => 'application/pdf',
47
      ['', 'test.pdf'] => 'application/pdf',
48
      [nil, 'test.pdf'] => 'application/pdf',
49
      # application/octet-stream is kept when the filename does not help
50
      ['application/octet-stream', 'test.unk'] => 'application/octet-stream',
51
      [nil, 'test.unk'] => 'application/octet-stream',
52
    }
53
    to_test.each do |args, expected|
54
      assert_equal expected, Redmine::MimeType.infer_type(*args)
55
    end
56
  end
57

  
40 58
  def test_css_class_of
41 59
    to_test = {
42 60
      'test.txt' => 'text-plain',
(1-1/3)