From 098f95f3ed87807e30c4b37e311bc8336c099dca Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Thu, 28 Jul 2011 01:36:24 -0700 Subject: [PATCH] Fail noisily on unfinished JSON prefixes... --- ext/yajl/yajl_ext.c | 10 ++++++++++ spec/parsing/one_off_spec.rb | 28 +++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/ext/yajl/yajl_ext.c b/ext/yajl/yajl_ext.c index 44c0f7e3..a38d0c2f 100644 --- a/ext/yajl/yajl_ext.c +++ b/ext/yajl/yajl_ext.c @@ -474,6 +474,16 @@ static VALUE rb_yajl_parser_parse(int argc, VALUE * argv, VALUE self) { return Qnil; } + // Because we've overridden the yajl_parse_complete state of the parser to allow + // us to parse multiple objects out of one stream; we can't use it to determine + // whether we've parsed a single object. Instead we'll check whether we've successfully + // parsed a single token. + if (!RARRAY_LEN(wrapper->builderStack) || + wrapper->nestedHashLevel || + wrapper->nestedArrayLevel) { + rb_raise(cParseError, "unexpected end of JSON string"); + } + return rb_ary_pop(wrapper->builderStack); } diff --git a/spec/parsing/one_off_spec.rb b/spec/parsing/one_off_spec.rb index 3a0a3543..537e92d2 100644 --- a/spec/parsing/one_off_spec.rb +++ b/spec/parsing/one_off_spec.rb @@ -56,6 +56,32 @@ output.should == {"key" => 1234} end + %w( + {"hi": + "worl + 1. + tru + nu + [[[[[f + ["hey","babe" + [{"wtf... + ).each do |example| + it "should not parse #{example.inspect}" do + lambda { + Yajl::Parser.parse(example) + }.should raise_error "unexpected end of JSON string" + end + end + + it "should not parse tails after incomplete heads" do + lambda { + Yajl::Parser.parse('{"hi":') + }.should raise_error + lambda { + Yajl::Parser.parse('"hi"}') + }.should raise_error + end + it "should parse numbers greater than 2,147,483,648" do Yajl::Parser.parse("{\"id\": 2147483649}").should eql({"id" => 2147483649}) Yajl::Parser.parse("{\"id\": 5687389800}").should eql({"id" => 5687389800}) @@ -78,4 +104,4 @@ Yajl::Parser.parse('{"key": "value"}').values.first.encoding.should eql(Encoding.default_internal) end end -end \ No newline at end of file +end