Subject: bug#78984: 31.0.50; `url-build-query-string' fails to escape a literal `%' in keys and values

From: Eli Zaretskii <[email-masked]>
Date: Sat, 12 Jul 2025 12:06:52 +0300

> Date: Wed, 09 Jul 2025 14:29:17 -0700
> From:  Steven Allen via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <[email-masked]>
> 
> 
> `url-build-query-string' fails to escape literal `%' characters and keys
> and values. To reproduce, run the following and note that it's encoded
> as "%%3D" when it should be encoded as "%25%3D".
> 
>     emacs --batch --eval '(message "%s" (url-build-query-string (list (list "key" "%="))))'
> 
> The root cause appears to be that `%' is explicitly allowed in
> `url-host-allowed-chars' (inherited by
> `url-query-key-value-allowed-chars'), apparently to avoid re-encoding
> %-encoded sequences. Unfortunately, changing this will definitely break
>   things (e.g., `url-encode-url' will no longer round-trip).
> 
> The direct/simple fix would be to forbid `%' in
> `url-query-key-value-allowed-chars'.
> 
> This issue also appears to affect Eglot's `eglot-path-to-uri' function
> (`eglot--uri-path-allowed-chars' allows `%' in path-names),
> but I haven't been able to find a stand-alone reproducer.

How about documenting that url-build-query-string should already have
any literal % characters encoded as %25, and changing all the callers
to abide by that requirement?