From 5a9e1af64acc2e20d1f6e8d982cdd8554e0855ff Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Tue, 23 Aug 2016 15:13:36 +0200 Subject: [PATCH] [FIX] base: improve last chance for detection of mimetype Since we return nosniff header, we need to avoid the magic mimetype. In case of picture in compute field (eg. image_small on product),there are no mimetype saved in column, and impossible to detect it from name/extention because url are like: /web/image/product.product/47/image_small. So before to arbitrary return default_mimetype, we try to detect it from the content itself. This commit continue to fix odoo/odoo@13193 --- openerp/addons/base/ir/ir_http.py | 5 +++-- openerp/tools/mimetypes.py | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/openerp/addons/base/ir/ir_http.py b/openerp/addons/base/ir/ir_http.py index 5a423a68624..d8ece72e1b1 100644 --- a/openerp/addons/base/ir/ir_http.py +++ b/openerp/addons/base/ir/ir_http.py @@ -22,6 +22,7 @@ import openerp import openerp.exceptions import openerp.models from openerp import http +from openerp.tools.mimetypes import guess_mimetype from openerp.http import request, STATIC_CACHE, content_disposition from openerp.modules.module import get_resource_path, get_module_path from openerp.osv import osv, orm @@ -295,7 +296,8 @@ class ir_http(osv.AbstractModel): attach_mimetype = env['ir.attachment'].search_read(domain=[('res_model', '=', model), ('res_id', '=', id), ('res_field', '=', field)], fields=['mimetype'], limit=1) mimetype = attach_mimetype and attach_mimetype[0]['mimetype'] if not mimetype: - mimetype = default_mimetype + mimetype = guess_mimetype(base64.b64decode(content), default=default_mimetype) + headers += [('Content-Type', mimetype), ('X-Content-Type-Options', 'nosniff')] # cache @@ -308,7 +310,6 @@ class ir_http(osv.AbstractModel): # content-disposition default name if download: headers.append(('Content-Disposition', self.content_disposition(filename))) - return (status, headers, content) diff --git a/openerp/tools/mimetypes.py b/openerp/tools/mimetypes.py index cf5a9debc90..581dcb27bd6 100644 --- a/openerp/tools/mimetypes.py +++ b/openerp/tools/mimetypes.py @@ -103,10 +103,11 @@ _Entry = collections.namedtuple('_Entry', ['mimetype', 'signatures', 'discrimina _mime_mappings = ( # pdf _Entry('application/pdf', ['%PDF'], []), - # jpg, jpeg, png, gif + # jpg, jpeg, png, gif, bmp _Entry('image/jpeg', ['\xFF\xD8\xFF\xE0', '\xFF\xD8\xFF\xE2', '\xFF\xD8\xFF\xE3', '\xFF\xD8\xFF\xE1'], []), _Entry('image/png', ['\x89PNG\r\n\x1A\n'], []), _Entry('image/gif', ['GIF87a', 'GIF89a'], []), + _Entry('image/bmp', ['BM'], []), # OLECF files in general (Word, Excel, PPT, default to word because why not?) _Entry('application/msword', ['\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1', '\x0D\x44\x4F\x43'], [ _check_olecf @@ -114,7 +115,7 @@ _mime_mappings = ( # zip, but will include jar, odt, ods, odp, docx, xlsx, pptx, apk _Entry('application/zip', ['PK\x03\x04'], [_check_ooxml, _check_open_container_format]), ) -def guess_mimetype(bin_data): +def guess_mimetype(bin_data, default='application/octet-stream'): """ Attempts to guess the mime type of the provided binary data, similar to but significantly more limited than libmagic @@ -140,7 +141,7 @@ def guess_mimetype(bin_data): # if no discriminant or no discriminant matches, return # primary mime type return entry.mimetype - return 'application/octet-stream' + return default try: