From 7523f037a4d2bfe843ac9b4c4236f500666da360 Mon Sep 17 00:00:00 2001 From: ybai08 <271969568+ybai08@users.noreply.github.com> Date: Sat, 17 Oct 2026 08:05:00 -0500 Subject: [PATCH] Escape backslashes in MySQL JSON path keys json_extract_path keys were only escaped for the SQL string literal, so a backslash in a key reached MySQL's JSON path parser as an escape character. A key such as "a\\b" matched nothing, "a\\nb" matched the key containing a newline, and a key ending in a backslash raised a syntax error. Escape backslashes and double quotes for the JSON path first, then escape the result for the SQL string literal. --- lib/ecto/adapters/myxql/connection.ex | 3 ++- test/ecto/adapters/myxql_test.exs | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/ecto/adapters/myxql/connection.ex b/lib/ecto/adapters/myxql/connection.ex index c3c45359..c609cd16 100644 --- a/lib/ecto/adapters/myxql/connection.ex +++ b/lib/ecto/adapters/myxql/connection.ex @@ -1626,8 +1626,9 @@ if Code.ensure_loaded?(MyXQL) do defp escape_json_key(value) when is_binary(value) do value + |> :binary.replace("\\", "\\\\", [:global]) + |> :binary.replace("\"", "\\\"", [:global]) |> escape_string() - |> :binary.replace("\"", "\\\\\"", [:global]) end defp ecto_cast_to_db(:id, _query), do: "unsigned" diff --git a/test/ecto/adapters/myxql_test.exs b/test/ecto/adapters/myxql_test.exs index 373bb6e4..6b5f71da 100644 --- a/test/ecto/adapters/myxql_test.exs +++ b/test/ecto/adapters/myxql_test.exs @@ -824,6 +824,12 @@ defmodule Ecto.Adapters.MyXQLTest do query = Schema |> select([s], json_extract_path(s.meta, ["\"a"])) |> plan() assert all(query) == ~s{SELECT json_extract(s0.`meta`, '$."\\\\"a"') FROM `schema` AS s0} + + query = Schema |> select([s], json_extract_path(s.meta, ["a\\b"])) |> plan() + assert all(query) == ~S{SELECT json_extract(s0.`meta`, '$."a\\\\b"') FROM `schema` AS s0} + + query = Schema |> select([s], json_extract_path(s.meta, ["a\\"])) |> plan() + assert all(query) == ~S{SELECT json_extract(s0.`meta`, '$."a\\\\"') FROM `schema` AS s0} end test "nested expressions" do