summaryrefslogtreecommitdiff
path: root/odoo/fields.py
diff options
context:
space:
mode:
authorPedro M. Baeza <pedro.baeza@gmail.com>2018-08-27 23:36:33 +0200
committerOlivier Dony <odo@odoo.com>2018-10-03 17:48:01 +0200
commit1be50fdeafcd2b94f7b2f47d6e5bc4b6ebaceadd (patch)
tree4489771b5b5dcf02212a4dfdce4e8c2c80e3a6b5 /odoo/fields.py
parent376361c15c8d2be15a2579ffd0432f31d745deb8 (diff)
[ADD] *: support SVG images
Introduce official support for SVG files in the framework, including the following parts: 1. When client-side SVG images are uploaded, the content is displayed until you save using data URI scheme according RFC 2397 [1]. This scheme requires to specify content format. Using hardcoded "image/png" works for all images types except SVG. Type-sniffing is done using "magic byte" detection via the first base64 encode byte, so that the proper data URI scheme can be used. This should not cause SVG-related security problems as the file is displayed through `<img>` tag, which does not allow SVG scripting [2]. 2. Make /web/image controller compatible with SVG 3. Add support for SVG files for company logo, which uses a dedicated controller. 4. Resizing of SVG files is a no-op, as it makes little sense for a vector-based format. We also want to avoid micro-alterations to the SVG document (in "natural" viewport parameters) as we would store multiple copies of the files in the filestore. 5. Because SVG files are inherently dangerous, upload of SVG files is restricted to administrators, either by blocking it directly before saving it in the database (binary fields with attachment=False), or by neutering them to text/plain mimetype (for binary fields with attachment=True) 6. Add tests for the SVG upload cases and for the non-admin uploads. [1] https://tools.ietf.org/html/rfc2397 [2] https://www.w3.org/wiki/SVG_Security Closes #26635
Diffstat (limited to 'odoo/fields.py')
-rw-r--r--odoo/fields.py14
1 files changed, 13 insertions, 1 deletions
diff --git a/odoo/fields.py b/odoo/fields.py
index 8d2f939fd88..a146a1bfa07 100644
--- a/odoo/fields.py
+++ b/odoo/fields.py
@@ -10,6 +10,7 @@ from functools import partial
from operator import attrgetter
import itertools
import logging
+import base64
import pytz
@@ -27,6 +28,7 @@ from .tools import float_repr, float_round, frozendict, html_sanitize, human_siz
from .tools import DEFAULT_SERVER_DATE_FORMAT as DATE_FORMAT
from .tools import DEFAULT_SERVER_DATETIME_FORMAT as DATETIME_FORMAT
from .tools.translate import html_translate, _
+from .tools.mimetypes import guess_mimetype
DATE_LENGTH = len(date.today().strftime(DATE_FORMAT))
DATETIME_LENGTH = len(datetime.now().strftime(DATETIME_FORMAT))
@@ -1752,6 +1754,14 @@ class Binary(Field):
# on purpose - non base64 data must be passed as a 8bit byte strings.
if not value:
return None
+ # Detect if the binary content is an SVG for restricting its upload
+ # only to system users.
+ if value[:1] == b'P': # Fast detection of first 6 bits of '<' (0x3C)
+ decoded_value = base64.b64decode(value)
+ # Full mimetype detection
+ if (guess_mimetype(decoded_value).startswith('image/svg') and
+ not record.env.user._is_system()):
+ raise UserError(_("Only admins can upload SVG files."))
if isinstance(value, bytes):
return psycopg2.Binary(value)
try:
@@ -1793,7 +1803,9 @@ class Binary(Field):
# create the attachments that store the values
env = record_values[0][0].env
with env.norecompute():
- env['ir.attachment'].sudo().create([{
+ env['ir.attachment'].sudo().with_context(
+ binary_field_real_user=env.user,
+ ).create([{
'name': self.name,
'res_model': self.model_name,
'res_field': self.name,