From deec7a1dd6ed01ae6fb0c87a5ee54cb7eb7a6c78 Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Tue, 17 May 2022 14:50:05 +0000 Subject: [PATCH] [FIX] base: add get_extension helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since PR #90855, we add extension if mimetypes doesn't match the type. Since guess_type don't know some extension, we prefer considere all string of less of 8 char as an extension before to fallback on the mimetypes lib. With this commit, a filename filename.scss will be considered with an extension .scss by our own helper instead of a fallback on .bin or .a as returned by guess_extension of mimetype. closes odoo/odoo#91905 X-original-commit: ca49c314970f32d051a449b0c0aa1aef30ca9a8b Signed-off-by: Jérémy Kersten Signed-off-by: Julien Castiaux --- odoo/addons/base/models/ir_http.py | 4 ++-- odoo/addons/base/tests/test_mimetypes.py | 16 +++++++++++++++- odoo/tools/mimetypes.py | 10 ++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/odoo/addons/base/models/ir_http.py b/odoo/addons/base/models/ir_http.py index b374240f57b..4f91d14178c 100644 --- a/odoo/addons/base/models/ir_http.py +++ b/odoo/addons/base/models/ir_http.py @@ -22,7 +22,7 @@ from odoo.exceptions import AccessDenied, AccessError, MissingError from odoo.http import request, content_disposition, Response, ROUTING_KEYS from odoo.service import security from odoo.tools import consteq, submap -from odoo.tools.mimetypes import guess_mimetype +from odoo.tools.mimetypes import get_extension, guess_mimetype from odoo.modules.module import get_resource_path, get_module_path _logger = logging.getLogger(__name__) @@ -354,7 +354,7 @@ class IrHttp(models.AbstractModel): mimetype = guess_mimetype(content, default=default_mimetype) # extension - has_extension = bool(mimetypes.guess_type(filename)[0]) + has_extension = get_extension(filename) or mimetypes.guess_type(filename)[0] if not has_extension: extension = mimetypes.guess_extension(mimetype) if extension: diff --git a/odoo/addons/base/tests/test_mimetypes.py b/odoo/addons/base/tests/test_mimetypes.py index 8de2f43d713..774c5ac1b89 100644 --- a/odoo/addons/base/tests/test_mimetypes.py +++ b/odoo/addons/base/tests/test_mimetypes.py @@ -2,7 +2,7 @@ import base64 import unittest from odoo.tests.common import BaseCase -from odoo.tools.mimetypes import guess_mimetype +from odoo.tools.mimetypes import get_extension, guess_mimetype PNG = b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC' GIF = b"R0lGODdhAQABAIAAAP///////ywAAAAAAQABAAACAkQBADs=" @@ -75,6 +75,20 @@ class test_guess_mimetype(BaseCase): self.assertEqual(mimetype, 'application/zip') + def test_mimetype_get_extension(self): + self.assertEqual(get_extension('filename.Abc'), '.abc') + self.assertEqual(get_extension('filename.scss'), '.scss') + self.assertEqual(get_extension('filename.torrent'), '.torrent') + self.assertEqual(get_extension('.htaccess'), '.htaccess') + # enough to suppose that extension is present and don't suffix the filename + self.assertEqual(get_extension('filename.tar.gz'), '.gz') + self.assertEqual(get_extension('filename'), '') + self.assertEqual(get_extension('filename.'), '') + self.assertEqual(get_extension('filename.not_alnum'), '') + self.assertEqual(get_extension('filename.with space'), '') + self.assertEqual(get_extension('filename.notAnExtension'), '') + + if __name__ == '__main__': unittest.main() diff --git a/odoo/tools/mimetypes.py b/odoo/tools/mimetypes.py index 14a0099bd98..b89434117ce 100644 --- a/odoo/tools/mimetypes.py +++ b/odoo/tools/mimetypes.py @@ -195,3 +195,13 @@ def neuter_mimetype(mimetype, user): if wrong_type and not user._is_system(): return 'text/plain' return mimetype + +def get_extension(filename): + """ Return the extension the current filename based on the heuristic that + ext is less than or equal to 10 chars and is alphanumeric. + + :param str filename: filename to try and guess a extension for + :returns: detected extension or `` + """ + ext = '.' in filename and filename.split('.')[-1] + return ext and len(ext) <= 10 and ext.isalnum() and '.' + ext.lower() or ''