summaryrefslogtreecommitdiff
path: root/ext/json/generator
diff options
context:
space:
mode:
Diffstat (limited to 'ext/json/generator')
-rw-r--r--ext/json/generator/depend2
-rw-r--r--ext/json/generator/extconf.rb1
-rw-r--r--ext/json/generator/generator.c26
-rw-r--r--ext/json/generator/generator.h2
4 files changed, 20 insertions, 11 deletions
diff --git a/ext/json/generator/depend b/ext/json/generator/depend
index bb76ad64000..1a042a2501e 100644
--- a/ext/json/generator/depend
+++ b/ext/json/generator/depend
@@ -1 +1 @@
-generator.o: generator.c generator.h
+generator.o: generator.c generator.h $(srcdir)/../fbuffer/fbuffer.h
diff --git a/ext/json/generator/extconf.rb b/ext/json/generator/extconf.rb
index 75c76ce15be..8627c5f4bdd 100644
--- a/ext/json/generator/extconf.rb
+++ b/ext/json/generator/extconf.rb
@@ -1,3 +1,4 @@
require 'mkmf'
+$defs << "-DJSON_GENERATOR"
create_makefile 'json/ext/generator'
diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c
index 6eea7ff1485..b1babb15f32 100644
--- a/ext/json/generator/generator.c
+++ b/ext/json/generator/generator.c
@@ -762,7 +762,6 @@ static void generate_json_bignum(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
{
VALUE tmp = rb_funcall(obj, i_to_s, 0);
fbuffer_append_str(buffer, tmp);
- RB_GC_GUARD(tmp);
}
static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
@@ -854,6 +853,21 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj)
}
/*
+ * This function returns true if string is either a JSON array or JSON object.
+ * It might suffer from false positives, e. g. syntactically incorrect JSON in
+ * the string or certain UTF-8 characters on the right hand side.
+ */
+static int isArrayOrObject(VALUE string)
+{
+ long string_len = RSTRING_LEN(string);
+ char *p = RSTRING_PTR(string), *q = p + string_len - 1;
+ if (string_len < 2) return 0;
+ for (; p < q && isspace(*p); p++);
+ for (; q > p && isspace(*q); q--);
+ return *p == '[' && *q == ']' || *p == '{' && *q == '}';
+}
+
+/*
* call-seq: generate(obj)
*
* Generates a valid JSON document from object +obj+ and returns the
@@ -863,15 +877,9 @@ static VALUE cState_partial_generate(VALUE self, VALUE obj)
static VALUE cState_generate(VALUE self, VALUE obj)
{
VALUE result = cState_partial_generate(self, obj);
- VALUE re, args[2];
GET_STATE(self);
- if (!state->quirks_mode) {
- args[0] = rb_str_new2("\\A\\s*(?:\\[.*\\]|\\{.*\\})\\s*\\Z");
- args[1] = CRegexp_MULTILINE;
- re = rb_class_new_instance(2, args, rb_cRegexp);
- if (NIL_P(rb_funcall(re, i_match, 1, result))) {
- rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed");
- }
+ if (!state->quirks_mode && !isArrayOrObject(result)) {
+ rb_raise(eGeneratorError, "only generation of JSON objects or arrays allowed");
}
return result;
}
diff --git a/ext/json/generator/generator.h b/ext/json/generator/generator.h
index 4958cf094d4..901b62c251a 100644
--- a/ext/json/generator/generator.h
+++ b/ext/json/generator/generator.h
@@ -4,6 +4,7 @@
#include <string.h>
#include <assert.h>
#include <math.h>
+#include <ctype.h>
#include "ruby.h"
@@ -105,7 +106,6 @@ typedef struct JSON_Generator_StateStruct {
Data_Get_Struct(Vstate, JSON_Generator_State, state); \
buffer = cState_prepare_buffer(Vstate); \
generate_json_##type(buffer, Vstate, state, self); \
- RB_GC_GUARD(Vstate); \
return fbuffer_to_s(buffer)
static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self);