From 97d2b758fe23d15f83fcd804b54b4b2326166f10 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 17 Feb 2016 15:11:14 +0100 Subject: [PATCH] [FIX] catch exception on incorrect mime type If the user provides a known mimetype which doesn't actually match the file as far as we're concerned, warn and fallback on extension rather than blow up. This comes up when a user installs Excel on Windows: it associates CSV files with itself and sets their mime type to application/vnd.ms-excel, which is not correct and leads to us trying to load a CSV with xlrd (an excel-parsing library). Fixes #9779 --- addons/base_import/models.py | 16 +++++++++++++--- addons/base_import/tests/test_cases.py | 4 +++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/addons/base_import/models.py b/addons/base_import/models.py index 7cbd0d79e09..ae9ba9ec1eb 100644 --- a/addons/base_import/models.py +++ b/addons/base_import/models.py @@ -158,16 +158,26 @@ class ir_import(orm.TransientModel): return fields def _read_file(self, file_type, record, options): + # try reading with user-provided mimetype (file_extension, handler, req) = FILE_TYPE_DICT.get(file_type, (None, None, None)) if handler: - return getattr(self, '_read_' + file_extension)(record, options) + try: + return getattr(self, '_read_' + file_extension)(record, options) + except Exception: + _logger.warn("Failed to read file '%s' (transient id %d) using user-provided mimetype %s", + record.file_name or '', record.id, file_type) + # fallback on file extensions as mime types can be unreliable (e.g. # software setting incorrect mime types, or non-installed software # leading to browser not sending mime types) if record.file_name: p, ext = os.path.splitext(record.file_name) - if ext and EXTENSIONS.get(ext): - return getattr(self, '_read_' + ext[1:])(record, options) + if ext in EXTENSIONS: + try: + return getattr(self, '_read_' + ext[1:])(record, options) + except Exception: + _logger.warn("Failed to read file '%s' (transient id %s) using file extension", + record.file_name, record.id) if req: raise ImportError(_("Unable to load \"{extension}\" file: requires Python module \"{modname}\"").format(extension=file_extension, modname=req)) diff --git a/addons/base_import/tests/test_cases.py b/addons/base_import/tests/test_cases.py index bd9feafb9ab..5a8ad70402b 100644 --- a/addons/base_import/tests/test_cases.py +++ b/addons/base_import/tests/test_cases.py @@ -3,7 +3,7 @@ import unittest from openerp.tests.common import TransactionCase, can_import from openerp.modules.module import get_module_resource - +from openerp.tools import mute_logger from .. import models @@ -197,6 +197,7 @@ class test_preview(TransactionCase): }) return Import, id + @mute_logger('openerp.addons.base_import.models') def test_encoding(self): Import, id = self.make_import() result = Import.parse_preview(self.cr, self.uid, id, { @@ -205,6 +206,7 @@ class test_preview(TransactionCase): }) self.assertTrue('error' in result) + @mute_logger('openerp.addons.base_import.models') def test_csv_errors(self): Import, id = self.make_import()