From a4c3f8d3b270b9c21caabcd084bf55049b5bc700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Dimitrov?= Date: Tue, 31 Oct 2017 13:24:13 +0100 Subject: stdlib: Fix case normalization (normalize/1) --- lib/stdlib/src/uri_string.erl | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/stdlib/src/uri_string.erl b/lib/stdlib/src/uri_string.erl index 2c73e38324..b8e0432fd6 100644 --- a/lib/stdlib/src/uri_string.erl +++ b/lib/stdlib/src/uri_string.erl @@ -296,12 +296,14 @@ URIString :: uri_string(), NormalizedURI :: uri_string(). normalize(URIString) -> - %% Case normalization and percent-encoding normalization are achieved - %% by running parse and recompose on the input URI string. + %% Percent-encoding normalization and case normalization for + %% percent-encoded triplets are achieved by running parse and + %% recompose on the input URI string. recompose( normalize_path_segment( normalize_scheme_based( - parse(URIString)))). + normalize_case( + parse(URIString))))). %%------------------------------------------------------------------------- @@ -1894,7 +1896,32 @@ form_urldecode(<>, _Acc) -> %% Helper functions for normalize %%------------------------------------------------------------------------- -%% RFC 3986 +%% 6.2.2.1. Case Normalization +normalize_case(#{scheme := Scheme, host := Host} = Map) -> + Map#{scheme => to_lower(Scheme), + host => to_lower(Host)}; +normalize_case(#{host := Host} = Map) -> + Map#{host => to_lower(Host)}; +normalize_case(#{scheme := Scheme} = Map) -> + Map#{scheme => to_lower(Scheme)}; +normalize_case(#{} = Map) -> + Map. + + +to_lower(Cs) when is_list(Cs) -> + B = convert_binary(Cs, utf8, utf8), + convert_list(to_lower(B), utf8); +to_lower(Cs) when is_binary(Cs) -> + to_lower(Cs, <<>>). +%% +to_lower(<>, Acc) when $A =< C, C =< $Z -> + to_lower(Cs, <>); +to_lower(<>, Acc) -> + to_lower(Cs, <>); +to_lower(<<>>, Acc) -> + Acc. + + %% 6.2.2.3. Path Segment Normalization %% 5.2.4. Remove Dot Segments normalize_path_segment(Map) -> -- cgit v1.2.3