diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2014-11-22 18:41:10 -0800 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2014-11-22 18:41:10 -0800 |
commit | e3b2f01dc35a697d06afe169bf40c62e716d8412 (patch) | |
tree | e59c583164fcfda63fb28e16447b4fc46a510bef | |
parent | f234c9b05b4857defed81eac023933e4c4a9d437 (diff) | |
parent | 9ad03a7b89c9fad16f677879da9d91275e997cfb (diff) | |
download | ffi-yajl-e3b2f01dc35a697d06afe169bf40c62e716d8412.tar.gz |
Merge pull request #32 from opscode/lcg/parser-bugs
Lcg/parser bugs
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rw-r--r-- | ext/ffi_yajl/ext/parser/parser.c | 6 | ||||
-rw-r--r-- | lib/ffi_yajl/ffi/parser.rb | 7 | ||||
-rw-r--r-- | lib/ffi_yajl/parser.rb | 2 | ||||
-rw-r--r-- | spec/ffi_yajl/parser_spec.rb | 50 |
5 files changed, 58 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index b74f762..d0a27b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ ### Bugs fixed +* fixes bare object parsing in issue #2 and #6 +* fixes parsing nil object to not coredump the MRI ruby VM (issue #15) + ## 1.2.0 (10/09/2014) ### Changes diff --git a/ext/ffi_yajl/ext/parser/parser.c b/ext/ffi_yajl/ext/parser/parser.c index e2481cd..a2813af 100644 --- a/ext/ffi_yajl/ext/parser/parser.c +++ b/ext/ffi_yajl/ext/parser/parser.c @@ -26,6 +26,7 @@ void set_value(CTX *ctx, VALUE val) { rb_hash_aset(last, key, val); break; default: + rb_ary_push(stack, val); break; } } @@ -49,8 +50,6 @@ void end_object(CTX *ctx) { rb_ivar_set(ctx->self, rb_intern("key"), rb_ary_pop(key_stack)); if ( RARRAY_LEN(stack) > 1 ) { set_value(ctx, rb_ary_pop(stack)); - } else { - rb_ivar_set(ctx->self, rb_intern("finished"), rb_ary_pop(stack)); } } @@ -211,7 +210,7 @@ static VALUE mParser_do_yajl_parse(VALUE self, VALUE str, VALUE yajl_opts) { goto raise; } yajl_free(hand); - return rb_ivar_get(self, rb_intern("finished")); + return rb_ary_pop(rb_ivar_get(self, rb_intern("stack"))); raise: if (hand) { @@ -230,4 +229,3 @@ void Init_parser() { utf8Encoding = rb_utf8_encoding(); #endif } - diff --git a/lib/ffi_yajl/ffi/parser.rb b/lib/ffi_yajl/ffi/parser.rb index 11682dc..7dfc26c 100644 --- a/lib/ffi_yajl/ffi/parser.rb +++ b/lib/ffi_yajl/ffi/parser.rb @@ -13,15 +13,13 @@ module FFI_Yajl when Array stack.last.push(val) else - raise FFI_Yajl::ParseError.new("internal error: object not a hash or array") + stack.push(val) end end def stack_pop if stack.length > 1 set_value( stack.pop ) - else - @finished = stack.pop end end @@ -138,11 +136,10 @@ module FFI_Yajl error = ::FFI_Yajl.yajl_get_error(yajl_handle, 1, str, str.bytesize) raise ::FFI_Yajl::ParseError.new(error) end - finished + stack.pop ensure ::FFI_Yajl.yajl_free(yajl_handle) if yajl_handle end end end end - diff --git a/lib/ffi_yajl/parser.rb b/lib/ffi_yajl/parser.rb index b6c8ce2..380604f 100644 --- a/lib/ffi_yajl/parser.rb +++ b/lib/ffi_yajl/parser.rb @@ -31,6 +31,8 @@ module FFI_Yajl end def parse(str) + raise FFI_Yajl::ParseError, "input must be a string or IO" unless str.is_a?(String) || str.respond_to?(:read) + # initialization that we can do in pure ruby yajl_opts = {} diff --git a/spec/ffi_yajl/parser_spec.rb b/spec/ffi_yajl/parser_spec.rb index c6ca3e4..0afae3f 100644 --- a/spec/ffi_yajl/parser_spec.rb +++ b/spec/ffi_yajl/parser_spec.rb @@ -14,6 +14,55 @@ describe "FFI_Yajl::Parser" do end end + context "when parsing nil" do + let(:json) { nil } + it "should not coredump ruby" do + expect{ parser }.to raise_error(FFI_Yajl::ParseError) + end + end + + context "when parsing bare int" do + let(:json) { "1" } + it "should parse to the int value" do + expect( parser ).to eq(1) + end + end + + context "when parsing bare string" do + let(:json) { '"a"' } + it "should parse to the string value" do + expect( parser ).to eq("a") + end + end + + context "when parsing bare true" do + let(:json) { "true" } + it "should parse to the true value" do + expect( parser ).to eq(true) + end + end + + context "when parsing bare false" do + let(:json) { "false" } + it "should parse to the false value" do + expect( parser ).to eq(false) + end + end + + context "when parsing bare null" do + let(:json) { "null" } + it "should parse to the nil value" do + expect( parser ).to eq(nil) + end + end + + context "when parsing bare float" do + let(:json) { "1.1" } + it "should parse to the a float" do + expect( parser ).to eq(1.1) + end + end + context "when json has comments" do let(:json) { '{"key": /* this is a comment */ "value"}' } @@ -482,4 +531,3 @@ describe "FFI_Yajl::Parser" do end end end - |