From 9afc3f21d8dfe7cd1c97820f9a00fa652965c467 Mon Sep 17 00:00:00 2001 From: Daniel Luz Date: Tue, 2 Nov 2010 00:36:24 -0200 Subject: [PATCH 1/4] Added "" tests --- tests/test_json_generate.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb index 5380a0645..3c50c66fc 100755 --- a/tests/test_json_generate.rb +++ b/tests/test_json_generate.rb @@ -180,4 +180,10 @@ def test_depth assert_raises(JSON::NestingError) { ary.to_json(s) } assert_equal 19, s.depth end + + + def test_no_close_tag + assert_equal '["<\/script>"]', generate([""]) + assert_equal '["<\/SCRIPT>"]', generate([""]) + end end From 3d7375298d51031eeef44b8d6f6b45720cb5bebe Mon Sep 17 00:00:00 2001 From: Daniel Luz Date: Mon, 1 Nov 2010 23:57:55 -0200 Subject: [PATCH 2/4] Escape '/' in strings after a '<' character --- ext/json/ext/generator/generator.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index 65058820c..f53e6964c 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -226,7 +226,7 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string) unsigned long len = RSTRING_LEN(string), start = 0, end = 0; const char *escape = NULL; int escape_len; - unsigned char c; + unsigned char c, last_c = -1; char buf[6] = { '\\', 'u' }; for (start = 0, end = 0; end < len;) { @@ -271,13 +271,20 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string) escape_len = 2; break; default: - end++; - continue; + if (c == '/' && last_c == '<') { + escape = "\\/"; + escape_len = 2; + } else { + last_c = c; + end++; + continue; + } break; } } fbuffer_append(buffer, ptr + start, end - start); fbuffer_append(buffer, escape, escape_len); + last_c = c; start = ++end; escape = NULL; } From 82b0ac8f0005f05f5d5ad031c0fb103155921be0 Mon Sep 17 00:00:00 2001 From: Daniel Luz Date: Tue, 2 Nov 2010 00:36:03 -0200 Subject: [PATCH 3/4] Pure: escape '/' in strings after a '<' character --- lib/json/pure/generator.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index 94cb23921..81636495c 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -44,6 +44,7 @@ def utf8_to_json(string) # :nodoc: string << '' # XXX workaround: avoid buffer sharing string.force_encoding(::Encoding::ASCII_8BIT) string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] } + string.gsub!("" string.force_encoding(::Encoding::UTF_8) string end @@ -65,6 +66,7 @@ def utf8_to_json_ascii(string) # :nodoc: s = JSON::UTF8toUTF16.iconv(c).unpack('H*')[0] s.gsub!(/.{4}/n, '\\\\u\&') } + string.gsub!("" string.force_encoding(::Encoding::UTF_8) string rescue Iconv::Failure => e @@ -72,7 +74,9 @@ def utf8_to_json_ascii(string) # :nodoc: end else def utf8_to_json(string) # :nodoc: - string.gsub(/["\\\x0-\x1f]/) { MAP[$&] } + string = string.gsub(/["\\\x0-\x1f]/) { MAP[$&] } + string.gsub!("" + string end def utf8_to_json_ascii(string) # :nodoc: @@ -89,6 +93,7 @@ def utf8_to_json_ascii(string) # :nodoc: s = JSON::UTF8toUTF16.iconv(c).unpack('H*')[0] s.gsub!(/.{4}/n, '\\\\u\&') } + string.gsub!("" string rescue Iconv::Failure => e raise GeneratorError, "Caught #{e.class}: #{e}" From 454fafda183b5cdc0338da34c74e7a69eb8c8283 Mon Sep 17 00:00:00 2001 From: Daniel Luz Date: Mon, 1 Nov 2010 23:49:19 -0200 Subject: [PATCH 4/4] Java: escape '/' in strings after a '<' character --- java/src/json/ext/StringEncoder.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/java/src/json/ext/StringEncoder.java b/java/src/json/ext/StringEncoder.java index 57bd19bce..85da9ce1b 100644 --- a/java/src/json/ext/StringEncoder.java +++ b/java/src/json/ext/StringEncoder.java @@ -40,14 +40,17 @@ final class StringEncoder extends ByteListTranscoder { void encode(ByteList src, ByteList out) { init(src, out); append('"'); + int lastChar = -1; while (hasNext()) { - handleChar(readUtf8Char()); + int newChar = readUtf8Char(); + handleChar(newChar, lastChar); + lastChar = newChar; } quoteStop(pos); append('"'); } - private void handleChar(int c) { + private void handleChar(int c, int lastChar) { switch (c) { case '"': case '\\': @@ -68,6 +71,13 @@ private void handleChar(int c) { case '\b': escapeChar('b'); break; + case '/': + if (lastChar == '<') { + escapeChar('/'); + } else { + quoteStart(); + } + break; default: if (c >= 0x20 && c <= 0x7f || (c >= 0x80 && !asciiOnly)) {