Module: Ronin::Support::Encoding::JS

Defined in:
lib/ronin/support/encoding/js.rb

Overview

Contains methods for encoding/decoding escaping/unescaping JavaScript data.

Core-Ext Methods

Since:

  • 1.0.0

Constant Summary collapse

ESCAPE_BYTES =

Special JavaScript bytes and their escaped Strings.

Since:

  • 1.0.0

{
  0x00 => '\u0000',
  0x01 => '\u0001',
  0x02 => '\u0002',
  0x03 => '\u0003',
  0x04 => '\u0004',
  0x05 => '\u0005',
  0x06 => '\u0006',
  0x07 => '\u0007',
  0x08 => '\b',
  0x09 => '\t',
  0x0a => '\n',
  0x0b => '\u000b',
  0x0c => '\f',
  0x0d => '\r',
  0x0e => '\u000e',
  0x0f => '\u000f',
  0x10 => '\u0010',
  0x11 => '\u0011',
  0x12 => '\u0012',
  0x13 => '\u0013',
  0x14 => '\u0014',
  0x15 => '\u0015',
  0x16 => '\u0016',
  0x17 => '\u0017',
  0x18 => '\u0018',
  0x19 => '\u0019',
  0x1a => '\u001a',
  0x1b => '\u001b',
  0x1c => '\u001c',
  0x1d => '\u001d',
  0x1e => '\u001e',
  0x1f => '\u001f',
  0x22 => '\"',
  0x5c => '\\\\'
}
BACKSLASHED_CHARS =

JavaScript characters that must be back-slashed.

Since:

  • 1.0.0

{
  "\\b"  => "\b",
  "\\t"  => "\t",
  "\\n"  => "\n",
  "\\f"  => "\f",
  "\\r"  => "\r",
  "\\\"" => "\"",
  "\\'"  => "'",
  "\\\\" => "\\"
}

Class Method Summary collapse

Class Method Details

.decode(data) ⇒ String

Alias for unescape.

Parameters:

  • data (String)

    The escaped JavaScript data.

Returns:

  • (String)

    The unescaped JavaScript String.

See Also:

Since:

  • 1.0.0



242
243
244
# File 'lib/ronin/support/encoding/js.rb', line 242

def self.decode(data)
  unescape(data)
end

.encode(data) ⇒ String

JavaScript escapes every character of the String.

Examples:

Encoding::JS.encode("hello")
# => "\\u0068\\u0065\\u006C\\u006C\\u006F"

Parameters:

  • data (String)

    The data to JavaScript escape.

Returns:

  • (String)

    The JavaScript escaped String.

Since:

  • 1.0.0



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/ronin/support/encoding/js.rb', line 215

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

.encode_byte(byte) ⇒ String

Encodes the byte as a JavaScript character.

Examples:

Encoding::JS.encode_byte(0x41)
# => "\\x41"

Parameters:

  • byte (Integer)

    The byte to encode.

Returns:

  • (String)

    The encoded JavaScript character.

Since:

  • 1.0.0



124
125
126
127
128
# 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

.escape(data) ⇒ String

Escapes a String for JavaScript.

Examples:

"hello\nworld\n".js_escape
# => "hello\\nworld\\n"

Parameters:

  • data (String)

    The data to JavaScript escape.

Returns:

  • (String)

    The JavaScript escaped String.

Since:

  • 1.0.0



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# 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

.escape_byte(byte) ⇒ String

Escapes the byte as a JavaScript character.

Examples:

Encoding::JS.escape_byte(0x41)
# => "A"
Encoding::JS.escape_byte(0x22)
# => "\\\""
Encoding::JS.escape_byte(0x7f)
# => "\\x7F"

Parameters:

  • byte (Integer)

    The byte to escape.

Returns:

  • (String)

    The escaped JavaScript character.

Since:

  • 1.0.0



97
98
99
100
101
102
103
104
105
106
107
108
109
# 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

.quote(data) ⇒ String

Converts the String into a JavaScript string.

Examples:

Encoding::JS.quote("hello\nworld\n")
# => "\"hello\\nworld\\n\""

Parameters:

  • data (String)

    The data to escape and quote.

Returns:

  • (String)

    The unquoted and unescaped String.

Since:

  • 1.0.0



259
260
261
# File 'lib/ronin/support/encoding/js.rb', line 259

def self.quote(data)
  "\"#{escape(data)}\""
end

.unescape(data) ⇒ String

Unescapes a JavaScript escaped String.

Examples:

Encoding::JS.unescape("\\u0068\\u0065\\u006C\\u006C\\u006F world")
# => "hello world"

Parameters:

  • data (String)

    The escaped JavaScript data.

Returns:

  • (String)

    The unescaped JavaScript String.

Since:

  • 1.0.0



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/ronin/support/encoding/js.rb', line 184

def self.unescape(data)
  unescaped = String.new(encoding: Encoding::UTF_8)

  data.scan(/[\\%]u[0-9a-fA-F]{1,4}|[\\%][0-9a-fA-F]{1,2}|\\[btnfr\'\"\\]|./) do |c|
    unescaped << BACKSLASHED_CHARS.fetch(c) do
                   if (c.start_with?("\\u") || c.start_with?("%u"))
                     c[2..].to_i(16)
                   elsif (c.start_with?("\\") || c.start_with?("%"))
                     c[1..].to_i(16)
                   else
                     c
                   end
                 end
  end

  return unescaped
end

.unquote(data) ⇒ String

Removes the quotes an unescapes a JavaScript string.

Examples:

Encoding::JS.unquote("\"hello\\nworld\"")
# => "hello\nworld"

Parameters:

  • data (String)

    The JavaScript string to unquote.

Returns:

  • (String)

    The un-quoted String if the String begins and ends with quotes, or the same String if it is not quoted.

Since:

  • 1.0.0



277
278
279
280
281
282
283
284
# File 'lib/ronin/support/encoding/js.rb', line 277

def self.unquote(data)
  if ((data[0] == '"' && data[-1] == '"') ||
      (data[0] == "'" && data[-1] == "'"))
    unescape(data[1..-2])
  else
    data
  end
end