From cf187ab43e6da85fad4dc737e83c2e91b139ffca Mon Sep 17 00:00:00 2001 From: "Julien (jula)" Date: Tue, 11 Jul 2023 07:46:25 +0000 Subject: [PATCH] [FIX] website_form: prevent crashing while parsing python dict in JS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit __Description of the issue:__ - The `replace` method in JS only replace the first occurrence of a string (unless `g` flag is used in the regex) - There could be an apostrophe (`‘`) in a string value which would be replaced by a quote (`“`) - There could be “None”, “False” in a string value which would be replaced too - “True” is not taken into account __Description of the fix:__ Those regex are meant to deal with more edge cases when transforming a python dict to a JSON in JS. However there are still ways it could go wrong. For the forward port in master, it could be a good idea to consider converting dictionnaries directly in the backend using the `json` python library. __Steps to reproduce the issue:__ 1. Edit the view `website.contactus` (If `website_crm` is installed, either uninstall it or disable the `website_crm.contactus_form` view) 2. At line 5, change the attribute `t-att-data-values` to a more complicated dict like: ``` "{'email_to': res_company.email, 'name': 'Alice True', 'age': None, 'active': True, 'attr1': None , 'attr2': False , 'attr3': 'let\'s go'}" ``` 3. Go to `/contactus` on the website ↳ Traceback opw-3328690 task-3340946 closes odoo/odoo#128127 X-original-commit: 5360e10dcd89bdbae6d01a0f6597571c8592301f Signed-off-by: Romain Derie (rde) --- .../website/static/src/snippets/s_website_form/000.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/addons/website/static/src/snippets/s_website_form/000.js b/addons/website/static/src/snippets/s_website_form/000.js index ed5fa635aad..bc0a190bd83 100644 --- a/addons/website/static/src/snippets/s_website_form/000.js +++ b/addons/website/static/src/snippets/s_website_form/000.js @@ -140,9 +140,14 @@ if (!this.editTranslations && (dataForEl || Object.keys(this.preFillValues).length)) { const dataForValues = dataForEl ? JSON.parse(dataForEl.dataset.values - .replace('False', '""') - .replace('None', '""') - .replace(/'/g, '"') + // replaces `True` by `true` if they are after `,` or `:` or `[` + .replace(/([,:\[]\s*)True/g, '$1true') + // replaces `False` and `None` by `""` if they are after `,` or `:` or `[` + .replace(/([,:\[]\s*)(False|None)/g, '$1""') + // replaces the `'` by `"` if they are before `,` or `:` or `]` or `}` + .replace(/'(\s*[,:\]}])/g, '"$1') + // replaces the `'` by `"` if they are after `{` or `[` or `,` or `:` + .replace(/([{\[:,]\s*)'/g, '$1"') ) : {}; const fieldNames = this.$el.serializeArray().map(el => el.name); // All types of inputs do not have a value property (eg:hidden),