diff --git a/ext/yajl/yajl_encode.c b/ext/yajl/yajl_encode.c index 8535c1b4..716ddded 100644 --- a/ext/yajl/yajl_encode.c +++ b/ext/yajl/yajl_encode.c @@ -162,8 +162,8 @@ void yajl_string_decode(yajl_buf buf, const unsigned char * str, end+=3; /* check if this is a surrogate */ if ((codepoint & 0xFC00) == 0xD800) { - end++; - if (str[end] == '\\' && str[end + 1] == 'u') { + if (end + 2 < len && str[end + 1] == '\\' && str[end + 2] == 'u') { + end++; unsigned int surrogate = 0; hexToDigit(&surrogate, str + end + 2); codepoint = diff --git a/spec/parsing/one_off_spec.rb b/spec/parsing/one_off_spec.rb index 9bc6b324..f1a8aea6 100644 --- a/spec/parsing/one_off_spec.rb +++ b/spec/parsing/one_off_spec.rb @@ -2,6 +2,13 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb') describe "One-off JSON examples" do + it "should not blow up with a bad surrogate trailer" do + # https://github.com/brianmario/yajl-ruby/issues/176 + bad_json = "{\"e\":{\"\\uD800\\\\DC00\":\"a\"}}" + + Yajl::Parser.new.parse(bad_json) + end + it "should parse 23456789012E666 and return Infinity" do infinity = (1.0/0) silence_warnings do