| From d86d283fcb35d1442a121b92030884523908a331 Mon Sep 17 00:00:00 2001 |
| From: nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> |
| Date: Sat, 22 Apr 2017 07:29:01 +0000 |
| Subject: [PATCH] merge revision(s) 58323,58324: |
| |
| Merge json-2.0.4. |
| |
| * https://github.com/flori/json/releases/tag/v2.0.4 |
| * https://github.com/flori/json/blob/09fabeb03e73ed88dc8ce8f19d76ac59e51dae20/CHANGES.md#2017-03-23-204 |
| Use `assert_raise` instead of `assert_raises`. |
| |
| git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_4@58445 b2dd03c8-39d4-4d8f-98ff-823fe69b080e |
| |
| Upstream-Status: Backport |
| CVE: CVE-2017-14064 |
| |
| Signed-off-by: Armin Kuster <akuster@mvisa.com> |
| |
| --- |
| ext/json/fbuffer/fbuffer.h | 3 --- |
| ext/json/generator/generator.c | 12 +++++----- |
| ext/json/generator/generator.h | 1 - |
| ext/json/json.gemspec | Bin 5473 -> 5474 bytes |
| ext/json/lib/json/version.rb | 2 +- |
| ext/json/parser/parser.c | 48 +++++++++++++++++++++++---------------- |
| ext/json/parser/parser.rl | 14 +++++++++--- |
| test/json/json_encoding_test.rb | 2 ++ |
| test/json/json_generator_test.rb | 0 |
| version.h | 2 +- |
| 10 files changed, 49 insertions(+), 35 deletions(-) |
| mode change 100755 => 100644 test/json/json_generator_test.rb |
| |
| Index: ruby-2.4.0/ext/json/fbuffer/fbuffer.h |
| =================================================================== |
| --- ruby-2.4.0.orig/ext/json/fbuffer/fbuffer.h |
| +++ ruby-2.4.0/ext/json/fbuffer/fbuffer.h |
| @@ -12,9 +12,6 @@ |
| #define RFLOAT_VALUE(val) (RFLOAT(val)->value) |
| #endif |
| |
| -#ifndef RARRAY_PTR |
| -#define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr |
| -#endif |
| #ifndef RARRAY_LEN |
| #define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len |
| #endif |
| Index: ruby-2.4.0/ext/json/generator/generator.c |
| =================================================================== |
| --- ruby-2.4.0.orig/ext/json/generator/generator.c |
| +++ ruby-2.4.0/ext/json/generator/generator.c |
| @@ -308,7 +308,7 @@ static char *fstrndup(const char *ptr, u |
| char *result; |
| if (len <= 0) return NULL; |
| result = ALLOC_N(char, len); |
| - memccpy(result, ptr, 0, len); |
| + memcpy(result, ptr, len); |
| return result; |
| } |
| |
| @@ -1062,7 +1062,7 @@ static VALUE cState_indent_set(VALUE sel |
| } |
| } else { |
| if (state->indent) ruby_xfree(state->indent); |
| - state->indent = strdup(RSTRING_PTR(indent)); |
| + state->indent = fstrndup(RSTRING_PTR(indent), len); |
| state->indent_len = len; |
| } |
| return Qnil; |
| @@ -1100,7 +1100,7 @@ static VALUE cState_space_set(VALUE self |
| } |
| } else { |
| if (state->space) ruby_xfree(state->space); |
| - state->space = strdup(RSTRING_PTR(space)); |
| + state->space = fstrndup(RSTRING_PTR(space), len); |
| state->space_len = len; |
| } |
| return Qnil; |
| @@ -1136,7 +1136,7 @@ static VALUE cState_space_before_set(VAL |
| } |
| } else { |
| if (state->space_before) ruby_xfree(state->space_before); |
| - state->space_before = strdup(RSTRING_PTR(space_before)); |
| + state->space_before = fstrndup(RSTRING_PTR(space_before), len); |
| state->space_before_len = len; |
| } |
| return Qnil; |
| @@ -1173,7 +1173,7 @@ static VALUE cState_object_nl_set(VALUE |
| } |
| } else { |
| if (state->object_nl) ruby_xfree(state->object_nl); |
| - state->object_nl = strdup(RSTRING_PTR(object_nl)); |
| + state->object_nl = fstrndup(RSTRING_PTR(object_nl), len); |
| state->object_nl_len = len; |
| } |
| return Qnil; |
| @@ -1208,7 +1208,7 @@ static VALUE cState_array_nl_set(VALUE s |
| } |
| } else { |
| if (state->array_nl) ruby_xfree(state->array_nl); |
| - state->array_nl = strdup(RSTRING_PTR(array_nl)); |
| + state->array_nl = fstrndup(RSTRING_PTR(array_nl), len); |
| state->array_nl_len = len; |
| } |
| return Qnil; |
| Index: ruby-2.4.0/ext/json/generator/generator.h |
| =================================================================== |
| --- ruby-2.4.0.orig/ext/json/generator/generator.h |
| +++ ruby-2.4.0/ext/json/generator/generator.h |
| @@ -1,7 +1,6 @@ |
| #ifndef _GENERATOR_H_ |
| #define _GENERATOR_H_ |
| |
| -#include <string.h> |
| #include <math.h> |
| #include <ctype.h> |
| |
| Index: ruby-2.4.0/ext/json/lib/json/version.rb |
| =================================================================== |
| --- ruby-2.4.0.orig/ext/json/lib/json/version.rb |
| +++ ruby-2.4.0/ext/json/lib/json/version.rb |
| @@ -1,7 +1,7 @@ |
| # frozen_string_literal: false |
| module JSON |
| # JSON version |
| - VERSION = '2.0.2' |
| + VERSION = '2.0.4' |
| VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: |
| VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: |
| VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: |
| Index: ruby-2.4.0/ext/json/parser/parser.c |
| =================================================================== |
| --- ruby-2.4.0.orig/ext/json/parser/parser.c |
| +++ ruby-2.4.0/ext/json/parser/parser.c |
| @@ -1435,13 +1435,21 @@ static VALUE json_string_unescape(VALUE |
| break; |
| case 'u': |
| if (pe > stringEnd - 4) { |
| - return Qnil; |
| + rb_enc_raise( |
| + EXC_ENCODING eParserError, |
| + "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p |
| + ); |
| } else { |
| UTF32 ch = unescape_unicode((unsigned char *) ++pe); |
| pe += 3; |
| if (UNI_SUR_HIGH_START == (ch & 0xFC00)) { |
| pe++; |
| - if (pe > stringEnd - 6) return Qnil; |
| + if (pe > stringEnd - 6) { |
| + rb_enc_raise( |
| + EXC_ENCODING eParserError, |
| + "%u: incomplete surrogate pair at '%s'", __LINE__, p |
| + ); |
| + } |
| if (pe[0] == '\\' && pe[1] == 'u') { |
| UTF32 sur = unescape_unicode((unsigned char *) pe + 2); |
| ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) |
| @@ -1471,7 +1479,7 @@ static VALUE json_string_unescape(VALUE |
| } |
| |
| |
| -#line 1475 "parser.c" |
| +#line 1483 "parser.c" |
| enum {JSON_string_start = 1}; |
| enum {JSON_string_first_final = 8}; |
| enum {JSON_string_error = 0}; |
| @@ -1479,7 +1487,7 @@ enum {JSON_string_error = 0}; |
| enum {JSON_string_en_main = 1}; |
| |
| |
| -#line 504 "parser.rl" |
| +#line 512 "parser.rl" |
| |
| |
| static int |
| @@ -1501,15 +1509,15 @@ static char *JSON_parse_string(JSON_Pars |
| |
| *result = rb_str_buf_new(0); |
| |
| -#line 1505 "parser.c" |
| +#line 1513 "parser.c" |
| { |
| cs = JSON_string_start; |
| } |
| |
| -#line 525 "parser.rl" |
| +#line 533 "parser.rl" |
| json->memo = p; |
| |
| -#line 1513 "parser.c" |
| +#line 1521 "parser.c" |
| { |
| if ( p == pe ) |
| goto _test_eof; |
| @@ -1534,7 +1542,7 @@ case 2: |
| goto st0; |
| goto st2; |
| tr2: |
| -#line 490 "parser.rl" |
| +#line 498 "parser.rl" |
| { |
| *result = json_string_unescape(*result, json->memo + 1, p); |
| if (NIL_P(*result)) { |
| @@ -1545,14 +1553,14 @@ tr2: |
| {p = (( p + 1))-1;} |
| } |
| } |
| -#line 501 "parser.rl" |
| +#line 509 "parser.rl" |
| { p--; {p++; cs = 8; goto _out;} } |
| goto st8; |
| st8: |
| if ( ++p == pe ) |
| goto _test_eof8; |
| case 8: |
| -#line 1556 "parser.c" |
| +#line 1564 "parser.c" |
| goto st0; |
| st3: |
| if ( ++p == pe ) |
| @@ -1628,7 +1636,7 @@ case 7: |
| _out: {} |
| } |
| |
| -#line 527 "parser.rl" |
| +#line 535 "parser.rl" |
| |
| if (json->create_additions && RTEST(match_string = json->match_string)) { |
| VALUE klass; |
| @@ -1675,7 +1683,7 @@ static VALUE convert_encoding(VALUE sour |
| } |
| FORCE_UTF8(source); |
| } else { |
| - source = rb_str_conv_enc(source, NULL, rb_utf8_encoding()); |
| + source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding()); |
| } |
| #endif |
| return source; |
| @@ -1808,7 +1816,7 @@ static VALUE cParser_initialize(int argc |
| } |
| |
| |
| -#line 1812 "parser.c" |
| +#line 1820 "parser.c" |
| enum {JSON_start = 1}; |
| enum {JSON_first_final = 10}; |
| enum {JSON_error = 0}; |
| @@ -1816,7 +1824,7 @@ enum {JSON_error = 0}; |
| enum {JSON_en_main = 1}; |
| |
| |
| -#line 720 "parser.rl" |
| +#line 728 "parser.rl" |
| |
| |
| /* |
| @@ -1833,16 +1841,16 @@ static VALUE cParser_parse(VALUE self) |
| GET_PARSER; |
| |
| |
| -#line 1837 "parser.c" |
| +#line 1845 "parser.c" |
| { |
| cs = JSON_start; |
| } |
| |
| -#line 736 "parser.rl" |
| +#line 744 "parser.rl" |
| p = json->source; |
| pe = p + json->len; |
| |
| -#line 1846 "parser.c" |
| +#line 1854 "parser.c" |
| { |
| if ( p == pe ) |
| goto _test_eof; |
| @@ -1876,7 +1884,7 @@ st0: |
| cs = 0; |
| goto _out; |
| tr2: |
| -#line 712 "parser.rl" |
| +#line 720 "parser.rl" |
| { |
| char *np = JSON_parse_value(json, p, pe, &result, 0); |
| if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} |
| @@ -1886,7 +1894,7 @@ st10: |
| if ( ++p == pe ) |
| goto _test_eof10; |
| case 10: |
| -#line 1890 "parser.c" |
| +#line 1898 "parser.c" |
| switch( (*p) ) { |
| case 13: goto st10; |
| case 32: goto st10; |
| @@ -1975,7 +1983,7 @@ case 9: |
| _out: {} |
| } |
| |
| -#line 739 "parser.rl" |
| +#line 747 "parser.rl" |
| |
| if (cs >= JSON_first_final && p == pe) { |
| return result; |
| Index: ruby-2.4.0/ext/json/parser/parser.rl |
| =================================================================== |
| --- ruby-2.4.0.orig/ext/json/parser/parser.rl |
| +++ ruby-2.4.0/ext/json/parser/parser.rl |
| @@ -446,13 +446,21 @@ static VALUE json_string_unescape(VALUE |
| break; |
| case 'u': |
| if (pe > stringEnd - 4) { |
| - return Qnil; |
| + rb_enc_raise( |
| + EXC_ENCODING eParserError, |
| + "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p |
| + ); |
| } else { |
| UTF32 ch = unescape_unicode((unsigned char *) ++pe); |
| pe += 3; |
| if (UNI_SUR_HIGH_START == (ch & 0xFC00)) { |
| pe++; |
| - if (pe > stringEnd - 6) return Qnil; |
| + if (pe > stringEnd - 6) { |
| + rb_enc_raise( |
| + EXC_ENCODING eParserError, |
| + "%u: incomplete surrogate pair at '%s'", __LINE__, p |
| + ); |
| + } |
| if (pe[0] == '\\' && pe[1] == 'u') { |
| UTF32 sur = unescape_unicode((unsigned char *) pe + 2); |
| ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) |
| @@ -570,7 +578,7 @@ static VALUE convert_encoding(VALUE sour |
| } |
| FORCE_UTF8(source); |
| } else { |
| - source = rb_str_conv_enc(source, NULL, rb_utf8_encoding()); |
| + source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding()); |
| } |
| #endif |
| return source; |
| Index: ruby-2.4.0/test/json/json_encoding_test.rb |
| =================================================================== |
| --- ruby-2.4.0.orig/test/json/json_encoding_test.rb |
| +++ ruby-2.4.0/test/json/json_encoding_test.rb |
| @@ -79,6 +79,8 @@ class JSONEncodingTest < Test::Unit::Tes |
| json = '["\ud840\udc01"]' |
| assert_equal json, generate(utf8, :ascii_only => true) |
| assert_equal utf8, parse(json) |
| + assert_raise(JSON::ParserError) { parse('"\u"') } |
| + assert_raise(JSON::ParserError) { parse('"\ud800"') } |
| end |
| |
| def test_chars |