summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2015-04-17 18:05:45 -0700
committerLamont Granquist <lamont@scriptkiddie.org>2015-04-17 18:05:45 -0700
commit846a93684d2d81ef102717004cd076c1b93544f7 (patch)
tree18615d57b3ae7d10f1a7ace71504226fde5d42ad /ext
parent5f9b3bd8e896cdba674d16dff83d4c9463d752d7 (diff)
downloadffi-yajl-846a93684d2d81ef102717004cd076c1b93544f7.tar.gz
add :unique_key_checking flag to parserlcg/unique_key_checking
can be used to error out if keys are duplicated in input rather than silently replacing.
Diffstat (limited to 'ext')
-rw-r--r--ext/ffi_yajl/ext/parser/parser.c10
1 files changed, 9 insertions, 1 deletions
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);