aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Allen2025-07-17 11:14:45 -0700
committerEli Zaretskii2025-08-02 16:49:52 +0300
commit5140e317b75d0467bfbbabb5d12404568fee1bb7 (patch)
tree0c20b284c67f2e4aadb45ab7620d2941c6aff088
parent5979d17ea94d5fbc1597821a36759f41eef1c282 (diff)
downloademacs-5140e317b75d0467bfbbabb5d12404568fee1bb7.tar.gz
emacs-5140e317b75d0467bfbbabb5d12404568fee1bb7.zip
url: %-encode literal % characters when building query strings
When building a query string via `url-build-query-string', %-encode literal % characters appearing in both the keys and the values. * lisp/url/url-util.el (url--query-key-value-preserved-chars): Define a new constant based on `url-query-key-value-allowed-chars' specifying the characters that should be preserved when %-encoding query-string keys and values. (url-build-query-string): Use the new constant (fixes Bug#78984). * test/lisp/url/url-util-tests.el (url-util-tests): Add a test.
-rw-r--r--lisp/url/url-util.el9
-rw-r--r--test/lisp/url/url-util-tests.el8
2 files changed, 12 insertions, 5 deletions
diff --git a/lisp/url/url-util.el b/lisp/url/url-util.el
index 8435114bbc2..47ef8811c5e 100644
--- a/lisp/url/url-util.el
+++ b/lisp/url/url-util.el
@@ -409,6 +409,13 @@ should return it unchanged."
409 (url-hexify-string frag url-query-allowed-chars))) 409 (url-hexify-string frag url-query-allowed-chars)))
410 (url-recreate-url obj))) 410 (url-recreate-url obj)))
411 411
412(defconst url--query-key-value-preserved-chars
413 (let ((vec (copy-sequence url-query-key-value-allowed-chars)))
414 (aset vec ?% nil)
415 vec)
416 "Byte mask used for %-encoding keys and values in the query segment of a URI.
417`url-query-key-value-allowed-chars' minus '%'.")
418
412;;;###autoload 419;;;###autoload
413(defun url-build-query-string (query &optional semicolons keep-empty) 420(defun url-build-query-string (query &optional semicolons keep-empty)
414 "Build a query-string. 421 "Build a query-string.
@@ -436,7 +443,7 @@ instead of just \"key\" as in the example above."
436 (let ((escaped 443 (let ((escaped
437 (mapcar (lambda (sym) 444 (mapcar (lambda (sym)
438 (url-hexify-string (format "%s" sym) 445 (url-hexify-string (format "%s" sym)
439 url-query-key-value-allowed-chars)) 446 url--query-key-value-preserved-chars))
440 key-vals))) 447 key-vals)))
441 (mapconcat (lambda (val) 448 (mapconcat (lambda (val)
442 (let ((vprint (format "%s" val)) 449 (let ((vprint (format "%s" val))
diff --git a/test/lisp/url/url-util-tests.el b/test/lisp/url/url-util-tests.el
index d34bfc8509c..6e79a798333 100644
--- a/test/lisp/url/url-util-tests.el
+++ b/test/lisp/url/url-util-tests.el
@@ -33,10 +33,10 @@
33 ((key1 "val1") (key2 val2) (key3 val1 val2) ("key4") (key5 "")) t) 33 ((key1 "val1") (key2 val2) (key3 val1 val2) ("key4") (key5 "")) t)
34 ("key1=val1;key2=val2;key3=val1;key3=val2;key4=;key5=" 34 ("key1=val1;key2=val2;key3=val1;key3=val2;key4=;key5="
35 ((key1 val1) (key2 val2) ("key3" val1 val2) (key4) (key5 "")) t t) 35 ((key1 val1) (key2 val2) ("key3" val1 val2) (key4) (key5 "")) t t)
36 ("key1=val/slash;key2=val%3Bsemi;key3=val%26amp;key4=val%3Deq" 36 ("key1=val/slash;key2=val%3Bsemi;key3=val%26amp;key4=val%3Deq;key5=val%25perc"
37 ((key1 "val/slash") (key2 "val;semi") (key3 "val&amp") (key4 "val=eq")) t) 37 ((key1 "val/slash") (key2 "val;semi") (key3 "val&amp") (key4 "val=eq") (key5 "val%perc")) t)
38 ("key%3Deq=val1;key%3Bsemi=val2;key%26amp=val3" 38 ("key%3Deq=val1;key%3Bsemi=val2;key%26amp=val3;key%25perc=val4"
39 (("key=eq" val1) ("key;semi" val2) ("key&amp" val3)) t))) 39 (("key=eq" val1) ("key;semi" val2) ("key&amp" val3) ("key%perc" val4)) t)))
40 test) 40 test)
41 (while tests 41 (while tests
42 (setq test (car tests) 42 (setq test (car tests)