summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2014-11-22 18:41:10 -0800
committerLamont Granquist <lamont@scriptkiddie.org>2014-11-22 18:41:10 -0800
commite3b2f01dc35a697d06afe169bf40c62e716d8412 (patch)
treee59c583164fcfda63fb28e16447b4fc46a510bef
parentf234c9b05b4857defed81eac023933e4c4a9d437 (diff)
parent9ad03a7b89c9fad16f677879da9d91275e997cfb (diff)
downloadffi-yajl-e3b2f01dc35a697d06afe169bf40c62e716d8412.tar.gz
Merge pull request #32 from opscode/lcg/parser-bugs
Lcg/parser bugs
-rw-r--r--CHANGELOG.md3
-rw-r--r--ext/ffi_yajl/ext/parser/parser.c6
-rw-r--r--lib/ffi_yajl/ffi/parser.rb7
-rw-r--r--lib/ffi_yajl/parser.rb2
-rw-r--r--spec/ffi_yajl/parser_spec.rb50
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
-