lib/hanami/utils/escape.rb in hanami-utils-0.7.2 vs lib/hanami/utils/escape.rb in hanami-utils-0.8.0

- old
+ new

@@ -9,11 +9,11 @@ # @see https://www.owasp.org # @see https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29 # @see https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet # @see https://www.owasp.org/index.php/ESAPI # @see https://github.com/ESAPI/esapi-java-legacy - module Escape + module Escape # rubocop:disable Metrics/ModuleLength # Hex base for base 10 integer conversion # # @since 0.4.0 # @api private # @@ -28,18 +28,18 @@ # Replacement hex for non printable characters # # @since 0.4.0 # @api private - REPLACEMENT_HEX = "fffd".freeze + REPLACEMENT_HEX = 'fffd'.freeze # Low hex codes lookup table # # @since 0.4.0 # @api private HEX_CODES = (0..255).each_with_object({}) do |c, codes| - if (c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A) + if (c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A) # rubocop:disable Style/ConditionalAssignment codes[c] = nil else codes[c] = c.to_s(HEX_BASE) end end.freeze @@ -360,11 +360,11 @@ # # @since 0.4.0 # @api private # # @see Hanami::Utils::Escape.url - DEFAULT_URL_SCHEMES = ['http', 'https', 'mailto'].freeze + DEFAULT_URL_SCHEMES = %w(http https mailto).freeze # The output of an escape. # # It's marked with this special class for two reasons: # @@ -509,68 +509,69 @@ def self.url(input, schemes = DEFAULT_URL_SCHEMES) input = encode(input) return input if input.is_a?(SafeString) SafeString.new( - URI.extract( - URI.decode(input), + URI::Parser.new.extract( + URI.decode_www_form_component(input), schemes ).first.to_s ) end - private - # Encode the given string into UTF-8 - # - # @param input [String] the input - # - # @return [String] an UTF-8 encoded string - # - # @since 0.4.0 - # @api private - def self.encode(input) - return '' if input.nil? - input.to_s.encode(Encoding::UTF_8) - rescue Encoding::UndefinedConversionError - input.dup.force_encoding(Encoding::UTF_8) - end + class << self + private - # Encode the given UTF-8 char. - # - # @param char [String] an UTF-8 char - # @param safe_chars [Hash] a table of safe chars - # - # @return [String] an HTML encoded string - # - # @since 0.4.0 - # @api private - def self.encode_char(char, safe_chars = {}) - return char if safe_chars[char] + # Encode the given string into UTF-8 + # + # @param input [String] the input + # + # @return [String] an UTF-8 encoded string + # + # @since 0.4.0 + # @api private + def encode(input) + return '' if input.nil? + input.to_s.encode(Encoding::UTF_8) + rescue Encoding::UndefinedConversionError + input.dup.force_encoding(Encoding::UTF_8) + end - code = char.ord - hex = hex_for_non_alphanumeric_code(code) - return char if hex.nil? + # Encode the given UTF-8 char. + # + # @param char [String] an UTF-8 char + # @param safe_chars [Hash] a table of safe chars + # + # @return [String] an HTML encoded string + # + # @since 0.4.0 + # @api private + def encode_char(char, safe_chars = {}) + return char if safe_chars[char] - if NON_PRINTABLE_CHARS[code] - hex = REPLACEMENT_HEX - end + code = char.ord + hex = hex_for_non_alphanumeric_code(code) + return char if hex.nil? - if entity = HTML_ENTITIES[code] - "&#{ entity };" - else - "&#x#{ hex };" + hex = REPLACEMENT_HEX if NON_PRINTABLE_CHARS[code] + + if entity = HTML_ENTITIES[code] # rubocop:disable Lint/AssignmentInCondition + "&#{entity};" + else + "&#x#{hex};" + end end - end - # Transforms the given char code - # - # @since 0.4.0 - # @api private - def self.hex_for_non_alphanumeric_code(input) - if input < LOW_HEX_CODE_LIMIT - HEX_CODES[input] - else - input.to_s(HEX_BASE) + # Transforms the given char code + # + # @since 0.4.0 + # @api private + def hex_for_non_alphanumeric_code(input) + if input < LOW_HEX_CODE_LIMIT + HEX_CODES[input] + else + input.to_s(HEX_BASE) + end end end end end end