Skip to content

Commit 76e92e8

Browse files
committed
Exclude decoded params on invalid URL encoding
Given the squashing of all exceptions in form-decode-str, the prior implementation of form-decode would return nil keys and/or values for parameters which failed to URL decode. With this change the parameters are silently dropped. Including nil parameters creates problems for downstream middleware (e.g. ring.middleware.nested-params -- see ring-clojure/ring#243) which are not expecting them, and has no basis in the spec (https://url.spec.whatwg.org/#urlencoded-parsing). One can second guess the decision to catch all decoding exceptions (see #22) rather than allowing them to bubble up (and thus potentially allow the application to return an error status), but that decision being what it is, it seems most in the spirit of the library to drop the invalid parameters. For completeness, here are the (known) URL decoding failure cases: - Illegal hex values in % escape pattern - Incomplete % escape pattern
1 parent 02f724b commit 76e92e8

2 files changed

Lines changed: 9 additions & 6 deletions

File tree

src/ring/util/codec.clj

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,11 @@
141141
(form-decode-str encoded encoding)
142142
(reduce
143143
(fn [m param]
144-
(if-let [[k v] (str/split param #"=" 2)]
145-
(assoc-conj m (form-decode-str k encoding) (form-decode-str (or v "") encoding))
146-
m))
144+
(let [[k v] (str/split param #"=" 2)
145+
k (form-decode-str k encoding)
146+
v (form-decode-str (or v "") encoding)]
147+
(if (and k v)
148+
(assoc-conj m k v)
149+
m)))
147150
{}
148151
(str/split encoded #"&")))))

test/ring/util/test/codec.clj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@
7171
"=b" {"" "b"})
7272
(testing "invalid URL encoding"
7373
(are [x y] (= (form-decode x) y)
74-
"%=b" {nil "b"}
75-
"a=%" {"a" nil}
76-
"%=%" {nil nil}))
74+
"%=b" {}
75+
"a=%" {}
76+
"%=%" {}))
7777
(is (= (form-decode "a=foo%FE%FF%00%2Fbar" "UTF-16")
7878
{"a" "foo/bar"})))

0 commit comments

Comments
 (0)