You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2026/06/08 16:46:19 UTC

(superset) 01/01: fix(jinja): apply consistent value handling to url_param across input sources

This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch fix/jinja-url-param-consistent-handling
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 58246f0fd4913a00a7bda7cfdc233dc53eb787a5
Author: Claude Code <no...@anthropic.com>
AuthorDate: Mon Jun 8 09:45:55 2026 -0700

    fix(jinja): apply consistent value handling to url_param across input sources
    
    url_param() returned the request.args value through an early return, skipping
    the dialect-specific quoting and cache-key handling that the form_data path
    applies. Funnel both input sources through the same tail so the returned value
    is handled consistently regardless of where the parameter originated.
    
    Co-Authored-By: Claude Opus 4.8 <no...@anthropic.com>
---
 superset/jinja_context.py              | 15 ++++++++++-----
 tests/unit_tests/jinja_context_test.py | 20 ++++++++++++++++++++
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/superset/jinja_context.py b/superset/jinja_context.py
index 2a2e838708f..296769da0da 100644
--- a/superset/jinja_context.py
+++ b/superset/jinja_context.py
@@ -288,11 +288,16 @@ class ExtraCache:
         from superset.views.utils import get_form_data
 
         if has_request_context() and request.args.get(param):
-            return request.args.get(param, default)
-
-        form_data, _ = get_form_data()
-        url_params = form_data.get("url_params") or {}
-        result = url_params.get(param, default)
+            result = request.args.get(param, default)
+        else:
+            form_data, _ = get_form_data()
+            url_params = form_data.get("url_params") or {}
+            result = url_params.get(param, default)
+
+        # Apply the same handling to every input source. Values read from
+        # request.args must go through the dialect-specific quoting below just
+        # like values sourced from form_data, so the result is consistent
+        # regardless of where the parameter originated.
         if result and escape_result and self.dialect:
             # use the dialect specific quoting logic to escape string
             result = String().literal_processor(dialect=self.dialect)(value=result)[
diff --git a/tests/unit_tests/jinja_context_test.py b/tests/unit_tests/jinja_context_test.py
index cfdbc2090d0..47c97991c84 100644
--- a/tests/unit_tests/jinja_context_test.py
+++ b/tests/unit_tests/jinja_context_test.py
@@ -438,6 +438,26 @@ def test_url_param_unescaped_default_form_data() -> None:
         assert cache.url_param("bar", "O'Malley", escape_result=False) == "O'Malley"
 
 
+def test_url_param_escaped_query() -> None:
+    """
+    Test that a ``url_param`` value read from the request query string is
+    handled the same way as one sourced from ``form_data`` -- i.e. it goes
+    through the dialect-specific quoting instead of being returned raw.
+    """
+    with current_app.test_request_context(query_string={"foo": "O'Brien"}):
+        cache = ExtraCache(dialect=dialect())
+        assert cache.url_param("foo") == "O''Brien"
+
+
+def test_url_param_unescaped_query() -> None:
+    """
+    Test that ``escape_result=False`` returns the raw query-string value.
+    """
+    with current_app.test_request_context(query_string={"foo": "O'Brien"}):
+        cache = ExtraCache(dialect=dialect())
+        assert cache.url_param("foo", escape_result=False) == "O'Brien"
+
+
 def test_safe_proxy_primitive() -> None:
     """
     Test the ``safe_proxy`` helper with a function returning a ``str``.