json 1.6.3 → 1.6.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of json might be problematic. Click here for more details.
- data/CHANGES +4 -0
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/ext/json/ext/generator/extconf.rb +3 -3
- data/ext/json/ext/parser/extconf.rb +3 -3
- data/ext/json/ext/parser/parser.c +77 -71
- data/ext/json/ext/parser/parser.rl +8 -2
- data/java/src/json/ext/OptionsReader.java +1 -7
- data/java/src/json/ext/Parser.java +207 -156
- data/java/src/json/ext/Parser.rl +127 -76
- data/json.gemspec +4 -4
- data/json_pure.gemspec +4 -4
- data/lib/json/version.rb +1 -1
- data/tests/test_json.rb +53 -2
- metadata +223 -229
- data/java/lib/bytelist-1.0.6.jar +0 -0
- data/java/lib/jcodings.jar +0 -0
data/java/src/json/ext/Parser.rl
CHANGED
@@ -26,6 +26,8 @@ import org.jruby.runtime.ThreadContext;
|
|
26
26
|
import org.jruby.runtime.Visibility;
|
27
27
|
import org.jruby.runtime.builtin.IRubyObject;
|
28
28
|
import org.jruby.util.ByteList;
|
29
|
+
import org.jruby.util.ConvertBytes;
|
30
|
+
import static org.jruby.util.ConvertDouble.DoubleConverter;
|
29
31
|
|
30
32
|
/**
|
31
33
|
* The <code>JSON::Ext::Parser</code> class.
|
@@ -56,7 +58,7 @@ public class Parser extends RubyObject {
|
|
56
58
|
|
57
59
|
private static final int DEFAULT_MAX_NESTING = 19;
|
58
60
|
|
59
|
-
private static final
|
61
|
+
private static final ByteList JSON_MINUS_INFINITY = new ByteList(ByteList.plain("-Infinity"));
|
60
62
|
// constant names in the JSON module containing those values
|
61
63
|
private static final String CONST_NAN = "NaN";
|
62
64
|
private static final String CONST_INFINITY = "Infinity";
|
@@ -80,13 +82,13 @@ public class Parser extends RubyObject {
|
|
80
82
|
* The result of the successful parsing. Should never be
|
81
83
|
* <code>null</code>.
|
82
84
|
*/
|
83
|
-
|
85
|
+
IRubyObject result;
|
84
86
|
/**
|
85
87
|
* The point where the parser returned.
|
86
88
|
*/
|
87
|
-
|
89
|
+
int p;
|
88
90
|
|
89
|
-
|
91
|
+
void update(IRubyObject result, int p) {
|
90
92
|
this.result = result;
|
91
93
|
this.p = p;
|
92
94
|
}
|
@@ -301,9 +303,11 @@ public class Parser extends RubyObject {
|
|
301
303
|
private final Parser parser;
|
302
304
|
private final ThreadContext context;
|
303
305
|
private final ByteList byteList;
|
306
|
+
private final ByteList view;
|
304
307
|
private final byte[] data;
|
305
308
|
private final StringDecoder decoder;
|
306
309
|
private int currentNesting = 0;
|
310
|
+
private final DoubleConverter dc;
|
307
311
|
|
308
312
|
// initialization value for all state variables.
|
309
313
|
// no idea about the origins of this value, ask Flori ;)
|
@@ -314,7 +318,9 @@ public class Parser extends RubyObject {
|
|
314
318
|
this.context = context;
|
315
319
|
this.byteList = parser.checkAndGetSource().getByteList();
|
316
320
|
this.data = byteList.unsafeBytes();
|
321
|
+
this.view = new ByteList(data, false);
|
317
322
|
this.decoder = new StringDecoder(context);
|
323
|
+
this.dc = new DoubleConverter();
|
318
324
|
}
|
319
325
|
|
320
326
|
private RaiseException unexpectedToken(int absStart, int absEnd) {
|
@@ -387,7 +393,7 @@ public class Parser extends RubyObject {
|
|
387
393
|
}
|
388
394
|
action parse_number {
|
389
395
|
if (pe > fpc + 9 - (parser.quirksMode ? 1 : 0) &&
|
390
|
-
absSubSequence(fpc, fpc + 9).
|
396
|
+
absSubSequence(fpc, fpc + 9).equals(JSON_MINUS_INFINITY)) {
|
391
397
|
|
392
398
|
if (parser.allowNaN) {
|
393
399
|
result = getConstant(CONST_MINUS_INFINITY);
|
@@ -398,13 +404,13 @@ public class Parser extends RubyObject {
|
|
398
404
|
throw unexpectedToken(p, pe);
|
399
405
|
}
|
400
406
|
}
|
401
|
-
|
402
|
-
if (res != null) {
|
407
|
+
parseFloat(res, fpc, pe);
|
408
|
+
if (res.result != null) {
|
403
409
|
result = res.result;
|
404
410
|
fexec res.p;
|
405
411
|
}
|
406
|
-
res
|
407
|
-
if (res != null) {
|
412
|
+
parseInteger(res, fpc, pe);
|
413
|
+
if (res.result != null) {
|
408
414
|
result = res.result;
|
409
415
|
fexec res.p;
|
410
416
|
}
|
@@ -412,8 +418,8 @@ public class Parser extends RubyObject {
|
|
412
418
|
fbreak;
|
413
419
|
}
|
414
420
|
action parse_string {
|
415
|
-
|
416
|
-
if (res == null) {
|
421
|
+
parseString(res, fpc, pe);
|
422
|
+
if (res.result == null) {
|
417
423
|
fhold;
|
418
424
|
fbreak;
|
419
425
|
} else {
|
@@ -423,9 +429,9 @@ public class Parser extends RubyObject {
|
|
423
429
|
}
|
424
430
|
action parse_array {
|
425
431
|
currentNesting++;
|
426
|
-
|
432
|
+
parseArray(res, fpc, pe);
|
427
433
|
currentNesting--;
|
428
|
-
if (res == null) {
|
434
|
+
if (res.result == null) {
|
429
435
|
fhold;
|
430
436
|
fbreak;
|
431
437
|
} else {
|
@@ -435,9 +441,9 @@ public class Parser extends RubyObject {
|
|
435
441
|
}
|
436
442
|
action parse_object {
|
437
443
|
currentNesting++;
|
438
|
-
|
444
|
+
parseObject(res, fpc, pe);
|
439
445
|
currentNesting--;
|
440
|
-
if (res == null) {
|
446
|
+
if (res.result == null) {
|
441
447
|
fhold;
|
442
448
|
fbreak;
|
443
449
|
} else {
|
@@ -462,7 +468,7 @@ public class Parser extends RubyObject {
|
|
462
468
|
) %*exit;
|
463
469
|
}%%
|
464
470
|
|
465
|
-
|
471
|
+
void parseValue(ParserResult res, int p, int pe) {
|
466
472
|
int cs = EVIL;
|
467
473
|
IRubyObject result = null;
|
468
474
|
|
@@ -470,9 +476,9 @@ public class Parser extends RubyObject {
|
|
470
476
|
%% write exec;
|
471
477
|
|
472
478
|
if (cs >= JSON_value_first_final && result != null) {
|
473
|
-
|
479
|
+
res.update(result, p);
|
474
480
|
} else {
|
475
|
-
|
481
|
+
res.update(null, p);
|
476
482
|
}
|
477
483
|
}
|
478
484
|
|
@@ -489,7 +495,18 @@ public class Parser extends RubyObject {
|
|
489
495
|
main := '-'? ( '0' | [1-9][0-9]* ) ( ^[0-9]? @exit );
|
490
496
|
}%%
|
491
497
|
|
492
|
-
|
498
|
+
void parseInteger(ParserResult res, int p, int pe) {
|
499
|
+
int new_p = parseIntegerInternal(p, pe);
|
500
|
+
if (new_p == -1) {
|
501
|
+
res.update(null, p);
|
502
|
+
return;
|
503
|
+
}
|
504
|
+
RubyInteger number = createInteger(p, new_p);
|
505
|
+
res.update(number, new_p + 1);
|
506
|
+
return;
|
507
|
+
}
|
508
|
+
|
509
|
+
int parseIntegerInternal(int p, int pe) {
|
493
510
|
int cs = EVIL;
|
494
511
|
|
495
512
|
%% write init;
|
@@ -497,15 +514,22 @@ public class Parser extends RubyObject {
|
|
497
514
|
%% write exec;
|
498
515
|
|
499
516
|
if (cs < JSON_integer_first_final) {
|
500
|
-
return
|
517
|
+
return -1;
|
501
518
|
}
|
502
519
|
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
520
|
+
return p;
|
521
|
+
}
|
522
|
+
|
523
|
+
RubyInteger createInteger(int p, int new_p) {
|
524
|
+
Ruby runtime = getRuntime();
|
525
|
+
ByteList num = absSubSequence(p, new_p);
|
526
|
+
return bytesToInum(runtime, num);
|
527
|
+
}
|
528
|
+
|
529
|
+
RubyInteger bytesToInum(Ruby runtime, ByteList num) {
|
530
|
+
return runtime.is1_9() ?
|
531
|
+
ConvertBytes.byteListToInum19(runtime, num, 10, true) :
|
532
|
+
ConvertBytes.byteListToInum(runtime, num, 10, true);
|
509
533
|
}
|
510
534
|
|
511
535
|
%%{
|
@@ -525,7 +549,18 @@ public class Parser extends RubyObject {
|
|
525
549
|
( ^[0-9Ee.\-]? @exit );
|
526
550
|
}%%
|
527
551
|
|
528
|
-
|
552
|
+
void parseFloat(ParserResult res, int p, int pe) {
|
553
|
+
int new_p = parseFloatInternal(p, pe);
|
554
|
+
if (new_p == -1) {
|
555
|
+
res.update(null, p);
|
556
|
+
return;
|
557
|
+
}
|
558
|
+
RubyFloat number = createFloat(p, new_p);
|
559
|
+
res.update(number, new_p + 1);
|
560
|
+
return;
|
561
|
+
}
|
562
|
+
|
563
|
+
int parseFloatInternal(int p, int pe) {
|
529
564
|
int cs = EVIL;
|
530
565
|
|
531
566
|
%% write init;
|
@@ -533,15 +568,16 @@ public class Parser extends RubyObject {
|
|
533
568
|
%% write exec;
|
534
569
|
|
535
570
|
if (cs < JSON_float_first_final) {
|
536
|
-
return
|
571
|
+
return -1;
|
537
572
|
}
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
573
|
+
|
574
|
+
return p;
|
575
|
+
}
|
576
|
+
|
577
|
+
RubyFloat createFloat(int p, int new_p) {
|
578
|
+
Ruby runtime = getRuntime();
|
579
|
+
ByteList num = absSubSequence(p, new_p);
|
580
|
+
return RubyFloat.newFloat(runtime, dc.parse(num, true, runtime.is1_9()));
|
545
581
|
}
|
546
582
|
|
547
583
|
%%{
|
@@ -577,7 +613,7 @@ public class Parser extends RubyObject {
|
|
577
613
|
) '"' @exit;
|
578
614
|
}%%
|
579
615
|
|
580
|
-
|
616
|
+
void parseString(ParserResult res, int p, int pe) {
|
581
617
|
int cs = EVIL;
|
582
618
|
IRubyObject result = null;
|
583
619
|
|
@@ -611,9 +647,9 @@ public class Parser extends RubyObject {
|
|
611
647
|
}
|
612
648
|
|
613
649
|
if (cs >= JSON_string_first_final && result != null) {
|
614
|
-
|
650
|
+
res.update(result, p + 1);
|
615
651
|
} else {
|
616
|
-
|
652
|
+
res.update(null, p + 1);
|
617
653
|
}
|
618
654
|
}
|
619
655
|
|
@@ -624,15 +660,15 @@ public class Parser extends RubyObject {
|
|
624
660
|
write data;
|
625
661
|
|
626
662
|
action parse_value {
|
627
|
-
|
628
|
-
if (res == null) {
|
663
|
+
parseValue(res, fpc, pe);
|
664
|
+
if (res.result == null) {
|
629
665
|
fhold;
|
630
666
|
fbreak;
|
631
667
|
} else {
|
632
|
-
if (
|
633
|
-
result.
|
668
|
+
if (parser.arrayClass == getRuntime().getArray()) {
|
669
|
+
((RubyArray)result).append(res.result);
|
634
670
|
} else {
|
635
|
-
result.
|
671
|
+
result.callMethod(context, "<<", res.result);
|
636
672
|
}
|
637
673
|
fexec res.p;
|
638
674
|
}
|
@@ -656,7 +692,7 @@ public class Parser extends RubyObject {
|
|
656
692
|
end_array @exit;
|
657
693
|
}%%
|
658
694
|
|
659
|
-
|
695
|
+
void parseArray(ParserResult res, int p, int pe) {
|
660
696
|
int cs = EVIL;
|
661
697
|
|
662
698
|
if (parser.maxNesting > 0 && currentNesting > parser.maxNesting) {
|
@@ -664,17 +700,19 @@ public class Parser extends RubyObject {
|
|
664
700
|
"nesting of " + currentNesting + " is too deep");
|
665
701
|
}
|
666
702
|
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
703
|
+
IRubyObject result;
|
704
|
+
if (parser.arrayClass == getRuntime().getArray()) {
|
705
|
+
result = RubyArray.newArray(getRuntime());
|
706
|
+
} else {
|
707
|
+
result = parser.arrayClass.newInstance(context,
|
708
|
+
IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
|
709
|
+
}
|
672
710
|
|
673
711
|
%% write init;
|
674
712
|
%% write exec;
|
675
713
|
|
676
714
|
if (cs >= JSON_array_first_final) {
|
677
|
-
|
715
|
+
res.update(result, p + 1);
|
678
716
|
} else {
|
679
717
|
throw unexpectedToken(p, pe);
|
680
718
|
}
|
@@ -687,23 +725,23 @@ public class Parser extends RubyObject {
|
|
687
725
|
write data;
|
688
726
|
|
689
727
|
action parse_value {
|
690
|
-
|
691
|
-
if (res == null) {
|
728
|
+
parseValue(res, fpc, pe);
|
729
|
+
if (res.result == null) {
|
692
730
|
fhold;
|
693
731
|
fbreak;
|
694
732
|
} else {
|
695
|
-
if (
|
696
|
-
result.
|
733
|
+
if (parser.objectClass == getRuntime().getHash()) {
|
734
|
+
((RubyHash)result).op_aset(context, lastName, res.result);
|
697
735
|
} else {
|
698
|
-
result.
|
736
|
+
result.callMethod(context, "[]=", new IRubyObject[] { lastName, res.result });
|
699
737
|
}
|
700
738
|
fexec res.p;
|
701
739
|
}
|
702
740
|
}
|
703
741
|
|
704
742
|
action parse_name {
|
705
|
-
|
706
|
-
if (res == null) {
|
743
|
+
parseString(res, fpc, pe);
|
744
|
+
if (res.result == null) {
|
707
745
|
fhold;
|
708
746
|
fbreak;
|
709
747
|
} else {
|
@@ -733,9 +771,10 @@ public class Parser extends RubyObject {
|
|
733
771
|
) @exit;
|
734
772
|
}%%
|
735
773
|
|
736
|
-
|
774
|
+
void parseObject(ParserResult res, int p, int pe) {
|
737
775
|
int cs = EVIL;
|
738
776
|
IRubyObject lastName = null;
|
777
|
+
boolean objectDefault = true;
|
739
778
|
|
740
779
|
if (parser.maxNesting > 0 && currentNesting > parser.maxNesting) {
|
741
780
|
throw newException(Utils.M_NESTING_ERROR,
|
@@ -744,22 +783,34 @@ public class Parser extends RubyObject {
|
|
744
783
|
|
745
784
|
// this is guaranteed to be a RubyHash due to the earlier
|
746
785
|
// allocator test at OptionsReader#getClass
|
747
|
-
|
748
|
-
|
749
|
-
|
786
|
+
IRubyObject result;
|
787
|
+
if (parser.objectClass == getRuntime().getHash()) {
|
788
|
+
result = RubyHash.newHash(getRuntime());
|
789
|
+
} else {
|
790
|
+
objectDefault = false;
|
791
|
+
result = parser.objectClass.newInstance(context,
|
792
|
+
IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
|
793
|
+
}
|
750
794
|
|
751
795
|
%% write init;
|
752
796
|
%% write exec;
|
753
797
|
|
754
798
|
if (cs < JSON_object_first_final) {
|
755
|
-
|
799
|
+
res.update(null, p + 1);
|
800
|
+
return;
|
756
801
|
}
|
757
802
|
|
758
803
|
IRubyObject returnedResult = result;
|
759
804
|
|
760
805
|
// attempt to de-serialize object
|
761
806
|
if (parser.createAdditions) {
|
762
|
-
IRubyObject vKlassName
|
807
|
+
IRubyObject vKlassName;
|
808
|
+
if (objectDefault) {
|
809
|
+
vKlassName = ((RubyHash)result).op_aref(context, parser.createId);
|
810
|
+
} else {
|
811
|
+
vKlassName = result.callMethod(context, "[]", parser.createId);
|
812
|
+
}
|
813
|
+
|
763
814
|
if (!vKlassName.isNil()) {
|
764
815
|
// might throw ArgumentError, we let it propagate
|
765
816
|
IRubyObject klass = parser.info.jsonModule.get().
|
@@ -771,7 +822,7 @@ public class Parser extends RubyObject {
|
|
771
822
|
}
|
772
823
|
}
|
773
824
|
}
|
774
|
-
|
825
|
+
res.update(returnedResult, p + 1);
|
775
826
|
}
|
776
827
|
|
777
828
|
%%{
|
@@ -782,8 +833,8 @@ public class Parser extends RubyObject {
|
|
782
833
|
|
783
834
|
action parse_object {
|
784
835
|
currentNesting = 1;
|
785
|
-
|
786
|
-
if (res == null) {
|
836
|
+
parseObject(res, fpc, pe);
|
837
|
+
if (res.result == null) {
|
787
838
|
fhold;
|
788
839
|
fbreak;
|
789
840
|
} else {
|
@@ -794,8 +845,8 @@ public class Parser extends RubyObject {
|
|
794
845
|
|
795
846
|
action parse_array {
|
796
847
|
currentNesting = 1;
|
797
|
-
|
798
|
-
if (res == null) {
|
848
|
+
parseArray(res, fpc, pe);
|
849
|
+
if (res.result == null) {
|
799
850
|
fhold;
|
800
851
|
fbreak;
|
801
852
|
} else {
|
@@ -814,6 +865,7 @@ public class Parser extends RubyObject {
|
|
814
865
|
int cs = EVIL;
|
815
866
|
int p, pe;
|
816
867
|
IRubyObject result = null;
|
868
|
+
ParserResult res = new ParserResult();
|
817
869
|
|
818
870
|
%% write init;
|
819
871
|
p = byteList.begin();
|
@@ -834,8 +886,8 @@ public class Parser extends RubyObject {
|
|
834
886
|
write data;
|
835
887
|
|
836
888
|
action parse_value {
|
837
|
-
|
838
|
-
if (res == null) {
|
889
|
+
parseValue(res, fpc, pe);
|
890
|
+
if (res.result == null) {
|
839
891
|
fhold;
|
840
892
|
fbreak;
|
841
893
|
} else {
|
@@ -853,6 +905,7 @@ public class Parser extends RubyObject {
|
|
853
905
|
int cs = EVIL;
|
854
906
|
int p, pe;
|
855
907
|
IRubyObject result = null;
|
908
|
+
ParserResult res = new ParserResult();
|
856
909
|
|
857
910
|
%% write init;
|
858
911
|
p = byteList.begin();
|
@@ -876,16 +929,14 @@ public class Parser extends RubyObject {
|
|
876
929
|
}
|
877
930
|
|
878
931
|
/**
|
879
|
-
*
|
880
|
-
* array byte offsets (i.e., the ByteList's own begin offset is not
|
881
|
-
* automatically added).
|
932
|
+
* Updates the "view" bytelist with the new offsets and returns it.
|
882
933
|
* @param start
|
883
934
|
* @param end
|
884
935
|
*/
|
885
936
|
private ByteList absSubSequence(int absStart, int absEnd) {
|
886
|
-
|
887
|
-
|
888
|
-
|
937
|
+
view.setBegin(absStart);
|
938
|
+
view.setRealSize(absEnd - absStart);
|
939
|
+
return view;
|
889
940
|
}
|
890
941
|
|
891
942
|
/**
|