From 846a93684d2d81ef102717004cd076c1b93544f7 Mon Sep 17 00:00:00 2001 From: Lamont Granquist Date: Fri, 17 Apr 2015 18:05:45 -0700 Subject: add :unique_key_checking flag to parser can be used to error out if keys are duplicated in input rather than silently replacing. --- ext/ffi_yajl/ext/parser/parser.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'ext/ffi_yajl/ext') diff --git a/ext/ffi_yajl/ext/parser/parser.c b/ext/ffi_yajl/ext/parser/parser.c index a2813af..e846c06 100644 --- a/ext/ffi_yajl/ext/parser/parser.c +++ b/ext/ffi_yajl/ext/parser/parser.c @@ -11,6 +11,7 @@ static VALUE mFFI_Yajl, mExt, mParser, cParseError; typedef struct { VALUE self; int symbolizeKeys; + int uniqueKeyChecking; } CTX; void set_value(CTX *ctx, VALUE val) { @@ -23,6 +24,12 @@ void set_value(CTX *ctx, VALUE val) { rb_ary_push(last, val); break; case T_HASH: + if ( ((CTX *)ctx)->uniqueKeyChecking ) { + ID sym_has_key = rb_intern("has_key?"); + if ( rb_funcall(last, sym_has_key, 1, key) == Qtrue ) { + rb_raise(cParseError, "repeated key: %s", RSTRING_PTR(key)); + } + } rb_hash_aset(last, key, val); break; default: @@ -163,7 +170,7 @@ static yajl_callbacks callbacks = { end_array_callback, }; -int get_opts_key(VALUE self, char *key) { +int get_opts_key(VALUE self, const char *key) { VALUE opts = rb_iv_get(self, "@opts"); if (TYPE(opts) != T_HASH) { rb_raise(rb_eTypeError, "opts is not a valid hash"); @@ -182,6 +189,7 @@ static VALUE mParser_do_yajl_parse(VALUE self, VALUE str, VALUE yajl_opts) { ctx.self = self; ctx.symbolizeKeys = get_opts_key(self, "symbolize_keys"); + ctx.uniqueKeyChecking = get_opts_key(self, "unique_key_checking"); hand = yajl_alloc(&callbacks, NULL, (void *)&ctx); -- cgit v1.2.1