Skip to content

Commit

Permalink
Fix incompatible encodings error in RKellyAdapter.
Browse files Browse the repository at this point in the history
Convert latin1 escape sequences into UTF-8.  By default they resulted
in ASCII-8BIT (binary) encoding, which wasn't compatible with UTF-8,
resulting in error.

Added wrapper encoding method to cope with Ruby 1.8 which has no
builtin encodings support.

The tests file is now also a pure ASCII file, so no funky encoding-stuff
happens there.

Fixes #491
  • Loading branch information
nene committed Nov 14, 2013
1 parent e48d7c9 commit eb2ee82
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
18 changes: 16 additions & 2 deletions lib/jsduck/js/rkelly_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,9 @@ def string_value(string)
if STRING_ESCAPES[s]
STRING_ESCAPES[s]
elsif s =~ /^\\[0-9]/
s[1..-1].oct.chr
nr_to_str(s[1..-1].oct, s)
elsif s =~ /^\\x[0-9A-F]/
s[2..-1].hex.chr
nr_to_str(s[2..-1].hex, s)
elsif s =~ /^\\u[0-9A-F]/
[s[2..-1].hex].pack("U")
else
Expand All @@ -492,6 +492,20 @@ def string_value(string)
end
end

# Converts a latin1 character code to UTF-8 string.
# When running in Ruby <= 1.8, only converts ASCII chars,
# others are left as escape sequences.
def nr_to_str(nr, original)
str = nr.chr
if str.respond_to?(:encode)
str.encode('UTF-8', 'ISO-8859-1')
elsif nr < 127
str
else
original
end
end

STRING_ESCAPES = {
'\b' => "\b",
'\f' => "\f",
Expand Down
21 changes: 18 additions & 3 deletions spec/js_rkelly_adapter_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# encoding: ASCII-8BIT
# encoding: ASCII
require "rkelly"
require "jsduck/js/rkelly_adapter"

Expand Down Expand Up @@ -40,6 +40,17 @@ def adapt_value(string)
end

describe "values of strings" do
def nr_to_str(nr, original)
str = nr.chr
if str.respond_to?(:encode)
str.encode('UTF-8', 'ISO-8859-1')
elsif nr < 127
str
else
original
end
end

it "single-quoted" do
adapt_value("'foo'").should == 'foo'
end
Expand All @@ -57,17 +68,21 @@ def adapt_value(string)
end

it "with latin1 octal escape" do
adapt_value('"\101 \251"').should == "A \251"
adapt_value('"\101 \251"').should == "A " + nr_to_str(0251, '\251')
end

it "with latin1 hex escape" do
adapt_value('"\x41 \xA9"').should == "A \xA9"
adapt_value('"\x41 \xA9"').should == "A " + nr_to_str(0xA9, '\xA9')
end

it "with unicode escape" do
adapt_value('"\u00A9"').should == [0x00A9].pack("U")
end

it "with multiple escapes together" do
adapt_value('"\xA0\u1680"').should == nr_to_str(0xA0, '\xA0') + [0x1680].pack("U")
end

it "with Ruby-like variable interpolation" do
adapt_value('"#{foo}"').should == '#{foo}'
end
Expand Down

0 comments on commit eb2ee82

Please sign in to comment.