Permalink
Browse files

update json to v1.7.5

  • Loading branch information...
1 parent f0dd768 commit 914dd77899ccc28ae2fd32e2bd4f378788b978c3 @Watson1978 Watson1978 committed Aug 28, 2012
View
@@ -2,8 +2,8 @@
#ifndef _FBUFFER_H_
#define _FBUFFER_H_
-#include <assert.h>
#include "ruby.h"
+#include <assert.h>
#ifdef __MACRUBY__
/* We cannot use the GC memory functions here
@@ -19,6 +19,27 @@
# define ruby_xfree(x) free(x)
#endif
+#ifndef RHASH_SIZE
+#define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries)
+#endif
+
+#ifndef RFLOAT_VALUE
+#define RFLOAT_VALUE(val) (RFLOAT(val)->value)
+#endif
+
+#ifndef RARRAY_PTR
+#define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr
+#endif
+#ifndef RARRAY_LEN
+#define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len
+#endif
+#ifndef RSTRING_PTR
+#define RSTRING_PTR(string) RSTRING(string)->ptr
+#endif
+#ifndef RSTRING_LEN
+#define RSTRING_LEN(string) RSTRING(string)->len
+#endif
+
#ifdef HAVE_RUBY_ENCODING_H
#include "ruby/encoding.h"
#define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
@@ -49,10 +70,14 @@ static FBuffer *fbuffer_alloc(unsigned long initial_length);
static void fbuffer_free(FBuffer *fb);
static void fbuffer_clear(FBuffer *fb);
static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
+#ifdef JSON_GENERATOR
static void fbuffer_append_long(FBuffer *fb, long number);
+#endif
static void fbuffer_append_char(FBuffer *fb, char newchr);
+#ifdef JSON_GENERATOR
static FBuffer *fbuffer_dup(FBuffer *fb);
static VALUE fbuffer_to_s(FBuffer *fb);
+#endif
static FBuffer *fbuffer_alloc(unsigned long initial_length)
{
@@ -101,6 +126,7 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
}
}
+#ifdef JSON_GENERATOR
static void fbuffer_append_str(FBuffer *fb, VALUE str)
{
const char *newstr = StringValuePtr(str);
@@ -110,6 +136,7 @@ static void fbuffer_append_str(FBuffer *fb, VALUE str)
fbuffer_append(fb, newstr, len);
}
+#endif
static void fbuffer_append_char(FBuffer *fb, char newchr)
{
@@ -118,6 +145,7 @@ static void fbuffer_append_char(FBuffer *fb, char newchr)
fb->len++;
}
+#ifdef JSON_GENERATOR
static void freverse(char *start, char *end)
{
char c;
@@ -168,3 +196,4 @@ static VALUE fbuffer_to_s(FBuffer *fb)
return result;
}
#endif
+#endif
@@ -10,4 +10,5 @@
end
end
+$defs << "-DJSON_GENERATOR"
create_makefile 'json/ext/generator'
@@ -853,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
@@ -862,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;
}
@@ -4,6 +4,7 @@
#include <string.h>
#include <assert.h>
#include <math.h>
+#include <ctype.h>
#include "ruby.h"
@@ -15,27 +16,6 @@
#define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key))
-#ifndef RHASH_SIZE
-#define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries)
-#endif
-
-#ifndef RFLOAT_VALUE
-#define RFLOAT_VALUE(val) (RFLOAT(val)->value)
-#endif
-
-#ifndef RARRAY_PTR
-#define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr
-#endif
-#ifndef RARRAY_LEN
-#define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len
-#endif
-#ifndef RSTRING_PTR
-#define RSTRING_PTR(string) RSTRING(string)->ptr
-#endif
-#ifndef RSTRING_LEN
-#define RSTRING_LEN(string) RSTRING(string)->len
-#endif
-
/* unicode defintions */
#define UNI_STRICT_CONVERSION 1
@@ -20,10 +20,13 @@ def self.json_create(object)
# Returns a hash, that will be turned into a JSON object and represent this
# object.
def as_json(*)
+ nanoseconds = [ tv_usec * 1000 ]
+ respond_to?(:tv_nsec) and nanoseconds << tv_nsec
+ nanoseconds = nanoseconds.max
{
JSON.create_id => self.class.name,
's' => tv_sec,
- 'n' => respond_to?(:tv_nsec) ? tv_nsec : tv_usec * 1000
+ 'n' => nanoseconds,
}
end
@@ -1,4 +1,5 @@
require 'json/version'
+require 'json/generic_object'
module JSON
class << self
@@ -110,7 +111,13 @@ def generator=(generator) # :nodoc:
MinusInfinity = -Infinity
# The base exception for JSON errors.
- class JSONError < StandardError; end
+ class JSONError < StandardError
+ def self.wrap(exception)
+ obj = new("Wrapped(#{exception.class}): #{exception.message.inspect}")
+ obj.set_backtrace exception.backtrace
+ obj
+ end
+ end
# This exception is raised if a parser error occurs.
class ParserError < JSONError; end
@@ -406,7 +413,10 @@ def self.swap!(string) # :nodoc:
end
# Shortuct for iconv.
- if ::String.method_defined?(:encode)
+ if ::String.method_defined?(:encode) &&
+ # XXX Rubinius doesn't support ruby 1.9 encoding yet
+ defined?(RUBY_ENGINE) && RUBY_ENGINE != 'rbx'
+ then
# Encodes string using Ruby's _String.encode_
def self.iconv(to, from, string)
string.encode(to, from)
@@ -0,0 +1,39 @@
+require 'ostruct'
+
+module JSON
+ class GenericObject < OpenStruct
+ class << self
+ alias [] new
+
+ def json_create(data)
+ data = data.dup
+ data.delete JSON.create_id
+ self[data]
+ end
+ end
+
+ def to_hash
+ table
+ end
+
+ def [](name)
+ table[name.to_sym]
+ end
+
+ def []=(name, value)
+ __send__ "#{name}=", value
+ end
+
+ def |(other)
+ self.class[other.to_hash.merge(to_hash)]
+ end
+
+ def as_json(*)
+ { JSON.create_id => self.class.name }.merge to_hash
+ end
+
+ def to_json(*a)
+ as_json.to_json(*a)
+ end
+ end
+end
@@ -41,7 +41,6 @@ module JSON
if defined?(::Encoding)
def utf8_to_json(string) # :nodoc:
string = string.dup
- string << '' # XXX workaround: avoid buffer sharing
string.force_encoding(::Encoding::ASCII_8BIT)
string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
string.force_encoding(::Encoding::UTF_8)
@@ -50,9 +49,8 @@ def utf8_to_json(string) # :nodoc:
def utf8_to_json_ascii(string) # :nodoc:
string = string.dup
- string << '' # XXX workaround: avoid buffer sharing
string.force_encoding(::Encoding::ASCII_8BIT)
- string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
+ string.gsub!(/["\\\x0-\x1f]/n) { MAP[$&] }
string.gsub!(/(
(?:
[\xc2-\xdf][\x80-\xbf] |
@@ -63,16 +61,18 @@ def utf8_to_json_ascii(string) # :nodoc:
)/nx) { |c|
c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
+ s.force_encoding(::Encoding::ASCII_8BIT)
s.gsub!(/.{4}/n, '\\\\u\&')
+ s.force_encoding(::Encoding::UTF_8)
}
string.force_encoding(::Encoding::UTF_8)
string
rescue => e
- raise GeneratorError, "Caught #{e.class}: #{e}"
+ raise GeneratorError.wrap(e)
end
else
def utf8_to_json(string) # :nodoc:
- string.gsub(/["\\\x0-\x1f]/) { MAP[$&] }
+ string.gsub(/["\\\x0-\x1f]/n) { MAP[$&] }
end
def utf8_to_json_ascii(string) # :nodoc:
@@ -91,7 +91,7 @@ def utf8_to_json_ascii(string) # :nodoc:
}
string
rescue => e
- raise GeneratorError, "Caught #{e.class}: #{e}"
+ raise GeneratorError.wrap(e)
end
end
module_function :utf8_to_json, :utf8_to_json_ascii
@@ -255,8 +255,12 @@ def to_h
# GeneratorError exception.
def generate(obj)
result = obj.to_json(self)
- if !@quirks_mode && result !~ /\A\s*(?:\[.*\]|\{.*\})\s*\Z/m
- raise GeneratorError, "only generation of JSON objects or arrays allowed"
+ unless @quirks_mode
+ unless result =~ /\A\s*\[/ && result =~ /\]\s*\Z/ ||
+ result =~ /\A\s*\{/ && result =~ /\}\s*\Z/
+ then
+ raise GeneratorError, "only generation of JSON objects or arrays allowed"
+ end
end
result
end
@@ -1,6 +1,6 @@
module JSON
# JSON version
- VERSION = '1.6.5'
+ VERSION = '1.7.5'
VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
Oops, something went wrong.

0 comments on commit 914dd77

Please sign in to comment.