[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
This commit is contained in:
Xavier Morel
2016-02-17 15:45:11 +01:00
parent b574616203
commit 97d2b758fe
2 changed files with 16 additions and 4 deletions
+13 -3
View File
@@ -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 '<unknown>', 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))
+3 -1
View File
@@ -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()