oj 1.4.0 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of oj might be problematic. Click here for more details.
- data/README.md +2 -2
- data/ext/oj/cache.c +2 -1
- data/ext/oj/dump.c +2 -0
- data/ext/oj/extconf.rb +7 -3
- data/ext/oj/fast.c +19 -6
- data/ext/oj/load.c +24 -11
- data/ext/oj/oj.c +4 -3
- data/ext/oj/oj.h +2 -2
- data/lib/oj/version.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -32,9 +32,9 @@ A fast JSON parser and Object marshaller as a Ruby gem.
|
|
32
32
|
|
33
33
|
## <a name="release">Release Notes</a>
|
34
34
|
|
35
|
-
### Release 1.4.
|
35
|
+
### Release 1.4.1
|
36
36
|
|
37
|
-
-
|
37
|
+
- Windows RubyInstaller and TCS-Ruby now supported thanks to Jarmo Pertman. Thanks Jarmo.
|
38
38
|
|
39
39
|
## <a name="description">Description</a>
|
40
40
|
|
data/ext/oj/cache.c
CHANGED
@@ -51,7 +51,8 @@ oj_cache_new(Cache *cache) {
|
|
51
51
|
}
|
52
52
|
(*cache)->key = 0;
|
53
53
|
(*cache)->value = Qundef;
|
54
|
-
bzero((*cache)->slots, sizeof((*cache)->slots));
|
54
|
+
//bzero((*cache)->slots, sizeof((*cache)->slots));
|
55
|
+
memset((*cache)->slots, 0, sizeof((*cache)->slots));
|
55
56
|
}
|
56
57
|
|
57
58
|
VALUE
|
data/ext/oj/dump.c
CHANGED
data/ext/oj/extconf.rb
CHANGED
@@ -6,8 +6,9 @@ dir_config(extension_name)
|
|
6
6
|
parts = RUBY_DESCRIPTION.split(' ')
|
7
7
|
type = parts[0]
|
8
8
|
type = 'ree' if 'ruby' == type && RUBY_DESCRIPTION.include?('Ruby Enterprise Edition')
|
9
|
+
platform = RUBY_PLATFORM
|
9
10
|
version = RUBY_VERSION.split('.')
|
10
|
-
puts ">>>>> Creating Makefile for #{type} version #{RUBY_VERSION} <<<<<"
|
11
|
+
puts ">>>>> Creating Makefile for #{type} version #{RUBY_VERSION} on #{platform} <<<<<"
|
11
12
|
|
12
13
|
dflags = {
|
13
14
|
'RUBY_TYPE' => type,
|
@@ -20,12 +21,13 @@ dflags = {
|
|
20
21
|
'HAS_ENCODING_SUPPORT' => (('ruby' == type || 'rubinius' == type) &&
|
21
22
|
(('1' == version[0] && '9' == version[1]) || '2' <= version[0])) ? 1 : 0,
|
22
23
|
'HAS_NANO_TIME' => ('ruby' == type && ('1' == version[0] && '9' == version[1]) || '2' <= version[0]) ? 1 : 0,
|
23
|
-
'HAS_RSTRUCT' => ('ruby' == type || 'ree' == type) ? 1 : 0,
|
24
|
+
'HAS_RSTRUCT' => ('ruby' == type || 'ree' == type || 'tcs-ruby' == type) ? 1 : 0,
|
24
25
|
'HAS_IVAR_HELPERS' => ('ruby' == type && ('1' == version[0] && '9' == version[1]) || '2' <= version[0]) ? 1 : 0,
|
25
26
|
'HAS_EXCEPTION_MAGIC' => ('ruby' == type && ('1' == version[0] && '9' == version[1]) || '2' <= version[0]) ? 0 : 1,
|
26
27
|
'HAS_PROC_WITH_BLOCK' => ('ruby' == type && ('1' == version[0] && '9' == version[1]) || '2' <= version[0]) ? 1 : 0,
|
27
28
|
'HAS_TOP_LEVEL_ST_H' => ('ree' == type || ('ruby' == type && '1' == version[0] && '8' == version[1])) ? 1 : 0,
|
28
|
-
'
|
29
|
+
'IS_WINDOWS' => ('i386-mingw32' == platform || 'tcs-ruby' == type) ? 1 : 0,
|
30
|
+
'SAFE_CACHE' => ('i386-mingw32' == platform || 'tcs-ruby' == type) ? 0 : 1,
|
29
31
|
}
|
30
32
|
# This is a monster hack to get around issues with 1.9.3-p0 on CentOS 5.4. SO
|
31
33
|
# some reason math.h and string.h contents are not processed. Might be a
|
@@ -35,6 +37,8 @@ if 'x86_64-linux' == RUBY_PLATFORM && '1.9.3' == RUBY_VERSION && '2011-10-30' ==
|
|
35
37
|
dflags['NEEDS_STPCPY'] = nil if File.read('/etc/redhat-release').include?('CentOS release 5.4')
|
36
38
|
rescue Exception => e
|
37
39
|
end
|
40
|
+
else
|
41
|
+
dflags['NEEDS_STPCPY'] = nil if 'i386-mingw32' == platform || 'tcs-ruby' == type
|
38
42
|
end
|
39
43
|
|
40
44
|
dflags.each do |k,v|
|
data/ext/oj/fast.c
CHANGED
@@ -28,7 +28,9 @@
|
|
28
28
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
29
|
*/
|
30
30
|
|
31
|
-
#
|
31
|
+
#if !IS_WINDOWS
|
32
|
+
#include <sys/resource.h> // for getrlimit() on linux
|
33
|
+
#endif
|
32
34
|
#include <stdlib.h>
|
33
35
|
#include <stdio.h>
|
34
36
|
#include <string.h>
|
@@ -479,7 +481,11 @@ static Leaf
|
|
479
481
|
read_next(ParseInfo pi) {
|
480
482
|
Leaf leaf = 0;
|
481
483
|
|
484
|
+
#if IS_WINDOWS
|
485
|
+
if ((uint64_t)(uint32_t)&leaf < pi->stack_min) {
|
486
|
+
#else
|
482
487
|
if ((uint64_t)&leaf < pi->stack_min) {
|
488
|
+
#endif
|
483
489
|
rb_raise(rb_eSysStackError, "JSON is too deeply nested");
|
484
490
|
}
|
485
491
|
next_non_white(pi); // skip white space
|
@@ -832,7 +838,6 @@ parse_json(VALUE clas, char *json, int given, int allocated) {
|
|
832
838
|
VALUE result = Qnil;
|
833
839
|
Doc doc;
|
834
840
|
int ex = 0;
|
835
|
-
struct rlimit lim;
|
836
841
|
|
837
842
|
if (given) {
|
838
843
|
doc = ALLOCA_N(struct _Doc, 1);
|
@@ -843,11 +848,19 @@ parse_json(VALUE clas, char *json, int given, int allocated) {
|
|
843
848
|
pi.s = pi.str;
|
844
849
|
doc_init(doc);
|
845
850
|
pi.doc = doc;
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
851
|
+
#if IS_WINDOWS
|
852
|
+
pi.stack_min = (uint64_t)(uint32_t)&pi - (512 * 1024); // assume a 1M stack and give half to ruby
|
853
|
+
#else
|
854
|
+
{
|
855
|
+
struct rlimit lim;
|
856
|
+
|
857
|
+
if (0 == getrlimit(RLIMIT_STACK, &lim)) {
|
858
|
+
pi.stack_min = (uint64_t)&pi - (lim.rlim_cur / 4 * 3); // let 3/4ths of the stack be used only
|
859
|
+
} else {
|
860
|
+
pi.stack_min = 0; // indicates not to check stack limit
|
861
|
+
}
|
850
862
|
}
|
863
|
+
#endif
|
851
864
|
// last arg is free func void* func(void*)
|
852
865
|
doc->self = rb_data_object_alloc(clas, doc, 0, free_doc_cb);
|
853
866
|
rb_gc_register_address(&doc->self);
|
data/ext/oj/load.c
CHANGED
@@ -28,10 +28,12 @@
|
|
28
28
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
29
|
*/
|
30
30
|
|
31
|
-
#
|
31
|
+
#if SAFE_CACHE
|
32
32
|
#include <pthread.h>
|
33
33
|
#endif
|
34
|
-
#
|
34
|
+
#if !IS_WINDOWS
|
35
|
+
#include <sys/resource.h> // for getrlimit() on linux
|
36
|
+
#endif
|
35
37
|
#include <stdlib.h>
|
36
38
|
#include <stdio.h>
|
37
39
|
#include <string.h>
|
@@ -162,7 +164,7 @@ classname2class(const char *name, ParseInfo pi) {
|
|
162
164
|
VALUE *slot;
|
163
165
|
int auto_define = (Yes == pi->options->auto_define);
|
164
166
|
|
165
|
-
#
|
167
|
+
#if SAFE_CACHE
|
166
168
|
pthread_mutex_lock(&oj_cache_mutex);
|
167
169
|
#endif
|
168
170
|
if (Qundef == (clas = oj_cache_get(oj_class_cache, name, &slot))) {
|
@@ -191,7 +193,7 @@ classname2class(const char *name, ParseInfo pi) {
|
|
191
193
|
*slot = clas;
|
192
194
|
}
|
193
195
|
}
|
194
|
-
#
|
196
|
+
#if SAFE_CACHE
|
195
197
|
pthread_mutex_unlock(&oj_cache_mutex);
|
196
198
|
#endif
|
197
199
|
return clas;
|
@@ -321,7 +323,11 @@ static VALUE
|
|
321
323
|
read_next(ParseInfo pi, int hint) {
|
322
324
|
VALUE obj;
|
323
325
|
|
326
|
+
#if IS_WINDOWS
|
327
|
+
if ((uint64_t)(uint32_t)&obj < pi->stack_min) {
|
328
|
+
#else
|
324
329
|
if ((uint64_t)&obj < pi->stack_min) {
|
330
|
+
#endif
|
325
331
|
rb_raise(rb_eSysStackError, "JSON is too deeply nested");
|
326
332
|
}
|
327
333
|
next_non_white(pi); // skip white space
|
@@ -498,7 +504,7 @@ read_obj(ParseInfo pi) {
|
|
498
504
|
VALUE *slot;
|
499
505
|
ID var_id;
|
500
506
|
|
501
|
-
#
|
507
|
+
#if SAFE_CACHE
|
502
508
|
pthread_mutex_lock(&oj_cache_mutex);
|
503
509
|
#endif
|
504
510
|
if (Qundef == (var_id = oj_cache_get(oj_attr_cache, ks, &slot))) {
|
@@ -514,7 +520,7 @@ read_obj(ParseInfo pi) {
|
|
514
520
|
var_id = rb_intern(attr);
|
515
521
|
*slot = var_id;
|
516
522
|
}
|
517
|
-
#
|
523
|
+
#if SAFE_CACHE
|
518
524
|
pthread_mutex_unlock(&oj_cache_mutex);
|
519
525
|
#endif
|
520
526
|
#if HAS_EXCEPTION_MAGIC
|
@@ -1003,7 +1009,6 @@ VALUE
|
|
1003
1009
|
oj_parse(char *json, Options options) {
|
1004
1010
|
VALUE obj;
|
1005
1011
|
struct _ParseInfo pi;
|
1006
|
-
struct rlimit lim;
|
1007
1012
|
|
1008
1013
|
if (0 == json) {
|
1009
1014
|
raise_error("Invalid arg, xml string can not be null", json, 0);
|
@@ -1016,11 +1021,19 @@ oj_parse(char *json, Options options) {
|
|
1016
1021
|
pi.circ_array = circ_array_new();
|
1017
1022
|
}
|
1018
1023
|
pi.options = options;
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1024
|
+
#if IS_WINDOWS
|
1025
|
+
pi.stack_min = (uint64_t)(uint32_t)&obj - (512 * 1024); // assume a 1M stack and give half to ruby
|
1026
|
+
#else
|
1027
|
+
{
|
1028
|
+
struct rlimit lim;
|
1029
|
+
|
1030
|
+
if (0 == getrlimit(RLIMIT_STACK, &lim)) {
|
1031
|
+
pi.stack_min = (uint64_t)&obj - (lim.rlim_cur / 4 * 3); // let 3/4ths of the stack be used only
|
1032
|
+
} else {
|
1033
|
+
pi.stack_min = 0; // indicates not to check stack limit
|
1034
|
+
}
|
1023
1035
|
}
|
1036
|
+
#endif
|
1024
1037
|
obj = read_next(&pi, 0);
|
1025
1038
|
if (Yes == options->circular) {
|
1026
1039
|
circ_array_free(pi.circ_array);
|
data/ext/oj/oj.c
CHANGED
@@ -34,7 +34,6 @@
|
|
34
34
|
#include <stdio.h>
|
35
35
|
#include <string.h>
|
36
36
|
#include <sys/types.h>
|
37
|
-
#include <sys/uio.h>
|
38
37
|
#include <unistd.h>
|
39
38
|
|
40
39
|
#include "oj.h"
|
@@ -108,7 +107,7 @@ Cache oj_attr_cache = 0;
|
|
108
107
|
rb_encoding *oj_utf8_encoding = 0;
|
109
108
|
#endif
|
110
109
|
|
111
|
-
#
|
110
|
+
#if SAFE_CACHE
|
112
111
|
pthread_mutex_t oj_cache_mutex; // only used if SAFE_CACHE defined
|
113
112
|
#endif
|
114
113
|
static const char json_class[] = "json_class";
|
@@ -386,6 +385,7 @@ load_with_opts(VALUE input, Options copts) {
|
|
386
385
|
}
|
387
386
|
strcpy(json, StringValuePtr(s));
|
388
387
|
#ifndef JRUBY_RUBY
|
388
|
+
#if !IS_WINDOWS
|
389
389
|
// JRuby gets confused with what is the real fileno.
|
390
390
|
} else if (rb_respond_to(input, oj_fileno_id) && Qnil != (s = rb_funcall(input, oj_fileno_id, 0))) {
|
391
391
|
int fd = FIX2INT(s);
|
@@ -402,6 +402,7 @@ load_with_opts(VALUE input, Options copts) {
|
|
402
402
|
rb_raise(rb_eIOError, "failed to read from IO Object.");
|
403
403
|
}
|
404
404
|
json[len] = '\0';
|
405
|
+
#endif
|
405
406
|
#endif
|
406
407
|
} else if (rb_respond_to(input, oj_read_id)) {
|
407
408
|
s = rb_funcall2(input, oj_read_id, 0, 0);
|
@@ -961,7 +962,7 @@ void Init_oj() {
|
|
961
962
|
// The end. bump up the size of odds if a new class is added.
|
962
963
|
odd->clas = Qundef;
|
963
964
|
|
964
|
-
#
|
965
|
+
#if SAFE_CACHE
|
965
966
|
pthread_mutex_init(&oj_cache_mutex, 0);
|
966
967
|
#endif
|
967
968
|
oj_init_doc();
|
data/ext/oj/oj.h
CHANGED
@@ -46,7 +46,7 @@ extern "C" {
|
|
46
46
|
#endif
|
47
47
|
|
48
48
|
#include "stdint.h"
|
49
|
-
#
|
49
|
+
#if SAFE_CACHE
|
50
50
|
#include <pthread.h>
|
51
51
|
#endif
|
52
52
|
#include "cache.h"
|
@@ -188,7 +188,7 @@ extern ID oj_utc_offset_id;
|
|
188
188
|
extern Cache oj_class_cache;
|
189
189
|
extern Cache oj_attr_cache;
|
190
190
|
|
191
|
-
#
|
191
|
+
#if SAFE_CACHE
|
192
192
|
extern pthread_mutex_t oj_cache_mutex;
|
193
193
|
#endif
|
194
194
|
#if defined(__cplusplus)
|
data/lib/oj/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-17 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! 'The fastest JSON parser and object serializer. '
|
15
15
|
email: peter@ohler.com
|