From 119ad2fb7b666ca7e4a89c8d9fd5a1427308657f Mon Sep 17 00:00:00 2001 From: "Laurent Desausoi (lade)" Date: Fri, 3 Jun 2022 09:05:00 +0000 Subject: [PATCH] [FIX] web_editor: validate qweb fields upon submission When editing database fields via the web editor, their value are not checked. Thus, stack traces can come up to the front-end user. Step to reproduce the issue: 1) Install the E-Learning module and connect to the website 2) On the main website (not the backend), go to Courses > Edit 3) Edit the Next Rank treshold with any non integer string (e.g.: coucou) A stracktrace will be shown upon save. Solution: The issue is that there are no validation on the submitted fields, this can cause stacktraces. A try-catch was used around the parsing of the input value to catch and properly raise these exceptions to show clean errors. On top of this, integers were not properly parsed, they were not taking into account the `thousands_sep` of the user lang (e.g.: 35,000 for 35000). NB: Generic fix of the following PR [1]. [1]: https://github.com/odoo/odoo/pull/85535 opw-2819392 closes odoo/odoo#96187 X-original-commit: edf76dbb0880c9b08354563a3c77e7c06a604802 Signed-off-by: Romain Derie (rde) Signed-off-by: Desausoi Laurent (lade) --- addons/web_editor/i18n/web_editor.pot | 13 ++++++------- addons/web_editor/models/ir_qweb_fields.py | 21 +++++++++------------ addons/web_editor/models/ir_ui_view.py | 9 +++++++-- addons/web_editor/tests/test_converter.py | 1 + 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/addons/web_editor/i18n/web_editor.pot b/addons/web_editor/i18n/web_editor.pot index c1458b84dca..3a15ae61fdd 100644 --- a/addons/web_editor/i18n/web_editor.pot +++ b/addons/web_editor/i18n/web_editor.pot @@ -1315,6 +1315,12 @@ msgstr "" msgid "Install" msgstr "" +#. module: web_editor +#: code:addons/web_editor/models/ir_ui_view.py:0 +#, python-format +msgid "Invalid field value for %s: %s" +msgstr "" + #. module: web_editor #. openerp-web #: code:addons/web_editor/static/src/js/editor/snippets.editor.js:0 @@ -2792,13 +2798,6 @@ msgid "" "You can upload images with the button located in the top left of the screen." msgstr "" -#. module: web_editor -#: code:addons/web_editor/models/ir_qweb_fields.py:0 -#: code:addons/web_editor/models/ir_qweb_fields.py:0 -#, python-format -msgid "You entered an invalid value, please try again." -msgstr "" - #. module: web_editor #: code:addons/web_editor/controllers/main.py:0 #, python-format diff --git a/addons/web_editor/models/ir_qweb_fields.py b/addons/web_editor/models/ir_qweb_fields.py index 58e4d0e49a6..bcb29dab339 100644 --- a/addons/web_editor/models/ir_qweb_fields.py +++ b/addons/web_editor/models/ir_qweb_fields.py @@ -29,7 +29,6 @@ from werkzeug import urls import odoo.modules from odoo import _, api, models, fields -from odoo.exceptions import ValidationError from odoo.tools import ustr, posix_to_ldml, pycompat from odoo.tools import html_escape as escape from odoo.tools.misc import get_lang, babel_locale_parse @@ -170,7 +169,11 @@ class Integer(models.AbstractModel): _description = 'Qweb Field Integer' _inherit = 'ir.qweb.field.integer' - value_from_string = int + @api.model + def from_html(self, model, field, element): + lang = self.user_lang() + value = element.text_content().strip() + return int(value.replace(lang.thousands_sep, '')) class Float(models.AbstractModel): @@ -182,11 +185,8 @@ class Float(models.AbstractModel): def from_html(self, model, field, element): lang = self.user_lang() value = element.text_content().strip() - try: - return float(value.replace(lang.thousands_sep, '') - .replace(lang.decimal_point, '.')) - except: - raise ValidationError(_('You entered an invalid value, please try again.')) + return float(value.replace(lang.thousands_sep, '') + .replace(lang.decimal_point, '.')) class ManyToOne(models.AbstractModel): @@ -482,11 +482,8 @@ class Monetary(models.AbstractModel): value = element.find('span').text.strip() - try: - return float(value.replace(lang.thousands_sep, '') - .replace(lang.decimal_point, '.')) - except: - raise ValidationError(_('You entered an invalid value, please try again.')) + return float(value.replace(lang.thousands_sep, '') + .replace(lang.decimal_point, '.')) class Duration(models.AbstractModel): diff --git a/addons/web_editor/models/ir_ui_view.py b/addons/web_editor/models/ir_ui_view.py index f49a7b893bd..f1627a1ac8e 100644 --- a/addons/web_editor/models/ir_ui_view.py +++ b/addons/web_editor/models/ir_ui_view.py @@ -6,8 +6,9 @@ import logging import uuid from lxml import etree, html -from odoo import api, models +from odoo import api, models, _ from odoo.osv import expression +from odoo.exceptions import ValidationError _logger = logging.getLogger(__name__) @@ -40,7 +41,11 @@ class IrUiView(models.Model): model = 'ir.qweb.field.' + el.get('data-oe-type') converter = self.env[model] if model in self.env else self.env['ir.qweb.field'] - value = converter.from_html(Model, Model._fields[field], el) + + try: + value = converter.from_html(Model, Model._fields[field], el) + except ValueError: + raise ValidationError(_("Invalid field value for %s: %s", Model._fields[field].string, el.text_content().strip())) if value is not None: # TODO: batch writes? diff --git a/addons/web_editor/tests/test_converter.py b/addons/web_editor/tests/test_converter.py index 245ef631e0d..99b9d682c9a 100644 --- a/addons/web_editor/tests/test_converter.py +++ b/addons/web_editor/tests/test_converter.py @@ -145,6 +145,7 @@ class TestConvertBack(common.TransactionCase): def test_integer(self): self.field_roundtrip('integer', 42) + self.field_roundtrip('integer', 42000) def test_float(self): self.field_roundtrip('float', 42.567890)