module Ronin::Support::Encoding::JS
Contains methods for encoding/decoding escaping/unescaping JavaScript data.
## Core-Ext Methods
-
{Integer#js_escape}
-
{Integer#js_encode}
-
{String#js_escape}
-
{String#js_unescape}
-
{String#js_encode}
-
{String#js_decode}
-
{String#js_string}
-
{String#js_unquote}
@api public
Constants
- BACKSLASHED_CHARS
JavaScript characters that must be back-slashed.
- ESCAPE_BYTES
Special JavaScript bytes and their escaped Strings.
Public Class Methods
Alias for {unescape}.
@param [String] data
The escaped JavaScript data.
@return [String]
The unescaped JavaScript String.
@see unescape
# File lib/ronin/support/encoding/js.rb, line 248 def self.decode(data) unescape(data) end
JavaScript escapes every character of the String
.
@param [String] data
The data to JavaScript escape.
@return [String]
The JavaScript escaped String.
@example
Encoding::JS.encode("hello") # => "\\u0068\\u0065\\u006C\\u006C\\u006F"
# File lib/ronin/support/encoding/js.rb, line 221 def self.encode(data) encoded = String.new if data.valid_encoding? data.each_codepoint do |codepoint| encoded << encode_byte(codepoint) end else data.each_byte do |byte| encoded << encode_byte(byte) end end return encoded end
Encodes the byte as a JavaScript character.
@param [Integer] byte
The byte to encode.
@return [String]
The encoded JavaScript character.
@example
Encoding::JS.encode_byte(0x41) # => "\\x41"
# File lib/ronin/support/encoding/js.rb, line 124 def self.encode_byte(byte) if byte > 0xff then "\\u%.4X" % byte else "\\x%.2X" % byte end end
Escapes a String
for JavaScript.
@param [String] data
The data to JavaScript escape.
@return [String]
The JavaScript escaped String.
@example
"hello\nworld\n".js_escape # => "hello\\nworld\\n"
# File lib/ronin/support/encoding/js.rb, line 155 def self.escape(data) escaped = String.new if data.valid_encoding? data.each_codepoint do |codepoint| escaped << escape_byte(codepoint) end else data.each_byte do |byte| escaped << escape_byte(byte) end end return escaped end
Escapes the byte as a JavaScript character.
@param [Integer] byte
The byte to escape.
@return [String]
The escaped JavaScript character.
@example
Encoding::JS.escape_byte(0x41) # => "A" Encoding::JS.escape_byte(0x22) # => "\\\"" Encoding::JS.escape_byte(0x7f) # => "\\x7F"
# File lib/ronin/support/encoding/js.rb, line 97 def self.escape_byte(byte) if byte >= 0x00 && byte <= 0xff ESCAPE_BYTES.fetch(byte) do if byte >= 0x20 && byte <= 0x7e byte.chr else encode_byte(byte) end end else encode_byte(byte) end end
Converts the String
into a JavaScript string.
@param [String] data
The data to escape and quote.
@return [String]
The unquoted and unescaped String.
@example
Encoding::JS.quote("hello\nworld\n") # => "\"hello\\nworld\\n\""
# File lib/ronin/support/encoding/js.rb, line 265 def self.quote(data) "\"#{escape(data)}\"" end
Unescapes a JavaScript escaped String
.
@param [String] data
The escaped JavaScript data.
@return [String]
The unescaped JavaScript String.
@example
Encoding::JS.unescape("\\u0068\\u0065\\u006C\\u006C\\u006F world") # => "hello world"
# File lib/ronin/support/encoding/js.rb, line 184 def self.unescape(data) unescaped = String.new(encoding: Encoding::UTF_8) scanner = StringScanner.new(data) until scanner.eos? unescaped << if (backslash_escape = scanner.scan(/\\[btnfr'"\\]/)) BACKSLASHED_CHARS[backslash_escape] elsif (surrogate_pair = scanner.scan(/\\u[dD][890abAB][0-9a-fA-F]{2}\\u[dD][cdefCDEF][0-9a-fA-F]{2}/)) hi = surrogate_pair[2..6].to_i(16) lo = surrogate_pair[8..12].to_i(16) (0x1_0000 + ((hi - 0xd800) * 0x400) + (lo - 0xdc00)) elsif (unicode_escape = scanner.scan(/[\\%]u[0-9a-fA-F]{1,4}/)) unicode_escape[2..].to_i(16) elsif (hex_escape = scanner.scan(/[\\%][0-9a-fA-F]{1,2}/)) hex_escape[1..].to_i(16) else scanner.getch end end return unescaped end
Removes the quotes an unescapes a JavaScript string.
@param [String] data
The JavaScript string to unquote.
@return [String]
The un-quoted String if the String begins and ends with quotes, or the same String if it is not quoted.
@example
Encoding::JS.unquote("\"hello\\nworld\"") # => "hello\nworld"
# File lib/ronin/support/encoding/js.rb, line 283 def self.unquote(data) if ((data[0] == '"' && data[-1] == '"') || (data[0] == "'" && data[-1] == "'")) unescape(data[1..-2]) else data end end