import urllib.parse from odoo import models from odoo.http import request class IrHttp(models.AbstractModel): _inherit = 'ir.http' @classmethod def _url_localized(cls, url=None, **kwargs): """ Sanitize the URL to resolve dot segments before passing it to the base implementation. This prevents a ValueError in tools.urls.urljoin when canonical_domain is set. """ if url is None and request: qs = request.httprequest.query_string.decode('utf-8') url = request.httprequest.path + ('?%s' % qs if qs else '') if url: path, sep, qs = url.partition('?') # Check for dot segments (. or ..) in the path # urllib.parse.unquote is used to catch encoded segments like %2e decoded_path = urllib.parse.unquote(path, errors='strict') if any(seg in ('.', '..') for seg in decoded_path.split('/')): # Resolve dot segments using urllib.parse.urljoin relative to root path = urllib.parse.urljoin('/', path) url = path + sep + qs return super()._url_localized(url=url, **kwargs)