Skip to content

Commit 6b45855

Browse files
committed
Fix edge cases for URI.decode/1
1 parent 4083555 commit 6b45855

File tree

2 files changed

+18
-12
lines changed

2 files changed

+18
-12
lines changed

lib/elixir/lib/uri.ex

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -230,25 +230,28 @@ defmodule URI do
230230
231231
"""
232232
def decode(uri) do
233-
decode(uri, uri)
233+
unpercent(uri)
234+
catch
235+
:malformed_uri ->
236+
raise ArgumentError, "malformed URI #{inspect uri}"
234237
end
235238

236-
def decode(<<?%, hex1, hex2, tail :: binary >>, uri) do
237-
<<bsl(hex_to_dec(hex1, uri), 4) + hex_to_dec(hex2, uri)>> <> decode(tail, uri)
239+
defp unpercent(<<?%, hex_1, hex_2, tail :: binary>>) do
240+
<<bsl(hex_to_dec(hex_1), 4) + hex_to_dec(hex_2)>> <> unpercent(tail)
238241
end
242+
defp unpercent(<<?%, _>>), do: throw(:malformed_uri)
243+
defp unpercent(<<?%>>), do: throw(:malformed_uri)
239244

240-
def decode(<<head, tail :: binary >>, uri) do
241-
<<head>> <> decode(tail, uri)
245+
defp unpercent(<<head, tail :: binary>>) do
246+
<<head>> <> unpercent(tail)
242247
end
243248

244-
def decode(<<>>, _uri), do: <<>>
249+
defp unpercent(<<>>), do: <<>>
245250

246-
defp hex_to_dec(n, _uri) when n in ?A..?F, do: n - ?A + 10
247-
defp hex_to_dec(n, _uri) when n in ?a..?f, do: n - ?a + 10
248-
defp hex_to_dec(n, _uri) when n in ?0..?9, do: n - ?0
249-
defp hex_to_dec(_n, uri) do
250-
raise ArgumentError, "malformed URI #{inspect uri}"
251-
end
251+
defp hex_to_dec(n) when n in ?A..?F, do: n - ?A + 10
252+
defp hex_to_dec(n) when n in ?a..?f, do: n - ?a + 10
253+
defp hex_to_dec(n) when n in ?0..?9, do: n - ?0
254+
defp hex_to_dec(_n), do: throw(:malformed_uri)
252255

253256
@doc """
254257
Parses a URI into components.

lib/elixir/test/elixir/uri_test.exs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ defmodule URITest do
5757
assert_raise ArgumentError, ~R/malformed URI/, fn ->
5858
URI.decode("% invalid")
5959
end
60+
assert_raise ArgumentError, ~R/malformed URI/, fn ->
61+
URI.decode("invalid%")
62+
end
6063
end
6164

6265
test :parse_http do

0 commit comments

Comments
 (0)