diff --git a/CHANGELOG.md b/CHANGELOG.md index 6366a4d92..64d998307 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ **Master** +- Escape URI delimiters inside asset paths and query values. [Oskar Eichler](https://github.com/OskarEichler) + Get upgrade notes from Sprockets 3.x to 4.x at https://github.com/rails/sprockets/blob/master/UPGRADING.md # 4.4.1 diff --git a/README.md b/README.md index 958b44cd4..5856b1659 100644 --- a/README.md +++ b/README.md @@ -714,3 +714,5 @@ Please see the [CHANGELOG](https://github.com/rails/sprockets/tree/master/CHANGE ## License Sprockets is released under the [MIT License](MIT-LICENSE). + +Asset filenames containing `?`, `[` or `]` and query values containing `&` are escaped as components, preserving existing plus, slash and percent handling. diff --git a/lib/sprockets/uri_utils.rb b/lib/sprockets/uri_utils.rb index 03e0f19cc..79cf2e0d3 100644 --- a/lib/sprockets/uri_utils.rb +++ b/lib/sprockets/uri_utils.rb @@ -24,6 +24,11 @@ module URIUtils URI_PARSER = defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::Generic::DEFAULT_PARSER private_constant :URI_PARSER + # The URI parser character set, excluding component delimiters. + URI_PATH_UNSAFE = /[^\-_.!~*'()a-zA-Z\d;\/:@&=+$,]/ + URI_QUERY_UNSAFE = /[^\-_.!~*'()a-zA-Z\d;\/?:@=+$,\[\]]/ + private_constant :URI_PATH_UNSAFE, :URI_QUERY_UNSAFE + # Internal: Parse URI into component parts. # # uri - String uri @@ -66,7 +71,7 @@ def join_file_uri(scheme, host, path, query) str = +"#{scheme}://" str << host if host path = "/#{path}" unless path.start_with?("/".freeze) - str << URI_PARSER.escape(path) + str << URI_PARSER.escape(path, URI_PATH_UNSAFE) str << "?#{query}" if query str end @@ -165,7 +170,7 @@ def encode_uri_query_params(params) when Integer query << "#{key}=#{value}" when String, Symbol - query << "#{key}=#{URI_PARSER.escape(value.to_s)}" + query << "#{key}=#{URI_PARSER.escape(value.to_s, URI_QUERY_UNSAFE)}" when TrueClass query << "#{key}" when FalseClass, NilClass