From e1dfe88857168aab85d8c28c88e1cfa73fe878ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yannik=20R=C3=B6del?= Date: Mon, 26 Sep 2022 09:18:23 +0200 Subject: [PATCH] Correctly escape variables when templating GraphiQL response This commit makes sure that values are escaped correctly when doing re.sub() while rendering a GraphiQL response. This is necessary when non-ASCII characters end up in the GraphQL variables, for example an umlaut. json.dumps() encodes such characters using a unicode escape sequence starting with "\u", which isn't a valid regex. Hence, we would get this error: re.error: bad escape \u at position 11 We get around this by re.escape()-ing everything before doing anything regexy with it. --- graphql_server/render_graphiql.py | 4 ++-- tests/flask/test_graphiqlview.py | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/graphql_server/render_graphiql.py b/graphql_server/render_graphiql.py index c942300..231aec2 100644 --- a/graphql_server/render_graphiql.py +++ b/graphql_server/render_graphiql.py @@ -230,12 +230,12 @@ def escape_js_value(value: Any) -> Any: def process_var(template: str, name: str, value: Any, jsonify=False) -> str: - pattern = r"{{\s*" + name + r"(\s*|[^}]+)*\s*}}" + pattern = r"{{\s*" + re.escape(name) + r"(\s*|[^}]+)*\s*}}" if jsonify and value not in ["null", "undefined"]: value = json.dumps(value) value = escape_js_value(value) - return re.sub(pattern, value, template) + return re.sub(pattern, re.escape(value), template) def simple_renderer(template: str, **values: Dict[str, Any]) -> str: diff --git a/tests/flask/test_graphiqlview.py b/tests/flask/test_graphiqlview.py index 4a55710..74fca1d 100644 --- a/tests/flask/test_graphiqlview.py +++ b/tests/flask/test_graphiqlview.py @@ -44,6 +44,18 @@ def test_graphiql_renders_pretty(app, client): assert pretty_response in response.data.decode("utf-8") +def test_graphiql_renders_umlauts_pretty(app, client): + with app.test_request_context(): + response = client.get( + url_for( + "graphql", + query="query helloWho($who: String){ test(who: $who) }", + variables='{"who": "Björn"}', + ), headers={"Accept": "text/html"} + ) + assert response.status_code == 200 + assert "Hello\\ Bj\\\\u00f6rn" in response.data.decode("utf-8") + def test_graphiql_default_title(app, client): with app.test_request_context():