syck 1.5.1.1 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.rdoc +8 -3
- data/ext/syck/implicit.c +1 -1
- data/ext/syck/rubyext.c +218 -61
- data/ext/syck/yaml2byte.c +1 -3
- data/lib/syck/constants.rb +1 -1
- data/test/test_boolean.rb +12 -0
- data/test/test_gc.rb +33 -0
- data/test/test_yaml.rb +34 -0
- metadata +5 -4
- data/syck.gemspec +0 -26
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a6f8be592c6d196af5a6fbf7bdab813819b4303d817f48b2edbc2e3441362382
|
|
4
|
+
data.tar.gz: 309adadd5621cfecdee15f0e36e39b7c1205df6406ab2521cea915b7509196fb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ef57afc974162ffda31cf27709ed5bdad7219f0a181a95a833549d575bfd0edd8fb18967ce380120b477107a643f823294ca83092f17b93a518e49ae59961288
|
|
7
|
+
data.tar.gz: abbdbea1f6eaea32d639b8ea9bcaee50c012c2f362d24d7a49489938eb079eb5c813d437bbf002cdb2ff149d323fd7510db3494075f6bb6c9a0f9884ed87a485
|
data/README.rdoc
CHANGED
|
@@ -4,9 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
== DESCRIPTION:
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
This Gem is a wrapper around {Syck}[https://github.com/indeyets/syck] (a.k.a.
|
|
8
|
+
Scripters' YAML Cobble-Yourself-a-Parser Kit), used for parsing YAML.
|
|
9
|
+
|
|
10
|
+
Syck has been removed from Ruby's stdlib, and this gem is meant to bridge the
|
|
11
|
+
gap for people that haven't updated their YAML yet.
|
|
12
|
+
|
|
13
|
+
If you are starting a new project, you probably should use
|
|
14
|
+
{Psych}[https://github.com/ruby/psych] instead.
|
|
10
15
|
|
|
11
16
|
== FEATURES/PROBLEMS:
|
|
12
17
|
|
data/ext/syck/implicit.c
CHANGED
data/ext/syck/rubyext.c
CHANGED
|
@@ -13,29 +13,6 @@
|
|
|
13
13
|
#include <sys/types.h>
|
|
14
14
|
#include <time.h>
|
|
15
15
|
|
|
16
|
-
typedef struct RVALUE {
|
|
17
|
-
union {
|
|
18
|
-
#if 0
|
|
19
|
-
struct {
|
|
20
|
-
unsigned long flags; /* always 0 for freed obj */
|
|
21
|
-
struct RVALUE *next;
|
|
22
|
-
} free;
|
|
23
|
-
#endif
|
|
24
|
-
struct RBasic basic;
|
|
25
|
-
struct RObject object;
|
|
26
|
-
/*struct RClass klass;*/
|
|
27
|
-
/*struct RFloat flonum;*/
|
|
28
|
-
/*struct RString string;*/
|
|
29
|
-
struct RArray array;
|
|
30
|
-
/*struct RRegexp regexp;*/
|
|
31
|
-
/*struct RHash hash;*/
|
|
32
|
-
/*struct RData data;*/
|
|
33
|
-
/*struct RStruct rstruct;*/
|
|
34
|
-
/*struct RBignum bignum;*/
|
|
35
|
-
/*struct RFile file;*/
|
|
36
|
-
} as;
|
|
37
|
-
} RVALUE;
|
|
38
|
-
|
|
39
16
|
typedef struct {
|
|
40
17
|
long hash;
|
|
41
18
|
char *buffer;
|
|
@@ -93,6 +70,75 @@ struct emitter_xtra {
|
|
|
93
70
|
VALUE port;
|
|
94
71
|
};
|
|
95
72
|
|
|
73
|
+
/*
|
|
74
|
+
* The untyped Data API (Data_Wrap_Struct / Data_Get_Struct) has been
|
|
75
|
+
* removed from current Ruby, so every wrapper here uses the TypedData
|
|
76
|
+
* API and the rb_data_type_t definitions below.
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
static void syck_node_mark(SyckNode *n);
|
|
80
|
+
static void syck_mark_parser(SyckParser *parser);
|
|
81
|
+
void rb_syck_free_parser(SyckParser *p);
|
|
82
|
+
static void syck_mark_emitter(SyckEmitter *emitter);
|
|
83
|
+
void rb_syck_free_emitter(SyckEmitter *e);
|
|
84
|
+
|
|
85
|
+
static const rb_data_type_t syck_parser_type = {
|
|
86
|
+
"syck/parser",
|
|
87
|
+
{
|
|
88
|
+
(void (*)(void *))syck_mark_parser,
|
|
89
|
+
(void (*)(void *))rb_syck_free_parser,
|
|
90
|
+
0,
|
|
91
|
+
},
|
|
92
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
static const rb_data_type_t syck_node_type = {
|
|
96
|
+
"syck/node",
|
|
97
|
+
{
|
|
98
|
+
(void (*)(void *))syck_node_mark,
|
|
99
|
+
(void (*)(void *))syck_free_node,
|
|
100
|
+
0,
|
|
101
|
+
},
|
|
102
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/*
|
|
106
|
+
* Nodes owned by the parser must not be freed by the GC. syck_node_type
|
|
107
|
+
* is set as the parent so a single &syck_node_type accepts either kind
|
|
108
|
+
* of node in the accessors below.
|
|
109
|
+
*/
|
|
110
|
+
static const rb_data_type_t syck_node_type_nofree = {
|
|
111
|
+
"syck/node",
|
|
112
|
+
{
|
|
113
|
+
(void (*)(void *))syck_node_mark,
|
|
114
|
+
0,
|
|
115
|
+
0,
|
|
116
|
+
},
|
|
117
|
+
&syck_node_type, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
static const rb_data_type_t syck_emitter_type = {
|
|
121
|
+
"syck/emitter",
|
|
122
|
+
{
|
|
123
|
+
(void (*)(void *))syck_mark_emitter,
|
|
124
|
+
(void (*)(void *))rb_syck_free_emitter,
|
|
125
|
+
0,
|
|
126
|
+
},
|
|
127
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/*
|
|
131
|
+
* The taint API (OBJ_TAINT / OBJ_TAINTED) has also been removed from
|
|
132
|
+
* current Ruby, while older supported versions still provide it; shim
|
|
133
|
+
* it to a no-op where Ruby no longer defines it.
|
|
134
|
+
*/
|
|
135
|
+
#ifndef OBJ_TAINT
|
|
136
|
+
#define OBJ_TAINT(obj) ((void)(obj))
|
|
137
|
+
#endif
|
|
138
|
+
#ifndef OBJ_TAINTED
|
|
139
|
+
#define OBJ_TAINTED(obj) (0)
|
|
140
|
+
#endif
|
|
141
|
+
|
|
96
142
|
/*
|
|
97
143
|
* Convert YAML to bytecode
|
|
98
144
|
*/
|
|
@@ -636,6 +682,99 @@ yaml_org_handler( SyckNode *n, VALUE *ref )
|
|
|
636
682
|
}
|
|
637
683
|
|
|
638
684
|
static void syck_node_mark( SyckNode *n );
|
|
685
|
+
static VALUE id_hash_new(void);
|
|
686
|
+
|
|
687
|
+
/*
|
|
688
|
+
* Rewrite every reference to `from` inside `obj` so it points at `to`.
|
|
689
|
+
*
|
|
690
|
+
* A self-referential anchor (`--- &a\n- *a\n`) is aliased before the anchored
|
|
691
|
+
* node is finished, so the parser hands out a BadAlias placeholder and only
|
|
692
|
+
* later learns which object the anchor really is. Only containers can hold a
|
|
693
|
+
* placeholder, so the walk stops at anything else. `seen` must compare by
|
|
694
|
+
* identity, otherwise equal-but-distinct nodes collapse and cycles that are
|
|
695
|
+
* already in place would recurse forever.
|
|
696
|
+
*/
|
|
697
|
+
static void
|
|
698
|
+
syck_swap_placeholder(VALUE obj, VALUE from, VALUE to, VALUE seen)
|
|
699
|
+
{
|
|
700
|
+
long i;
|
|
701
|
+
VALUE ivars;
|
|
702
|
+
|
|
703
|
+
if ( SPECIAL_CONST_P( obj ) || OBJ_FROZEN( obj ) ) return;
|
|
704
|
+
|
|
705
|
+
switch ( BUILTIN_TYPE( obj ) )
|
|
706
|
+
{
|
|
707
|
+
case T_ARRAY:
|
|
708
|
+
case T_HASH:
|
|
709
|
+
case T_STRUCT:
|
|
710
|
+
case T_OBJECT:
|
|
711
|
+
break;
|
|
712
|
+
|
|
713
|
+
default:
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
if ( RTEST( rb_hash_lookup( seen, obj ) ) ) return;
|
|
718
|
+
rb_hash_aset( seen, obj, Qtrue );
|
|
719
|
+
|
|
720
|
+
switch ( BUILTIN_TYPE( obj ) )
|
|
721
|
+
{
|
|
722
|
+
case T_ARRAY:
|
|
723
|
+
for ( i = 0; i < RARRAY_LEN( obj ); i++ )
|
|
724
|
+
{
|
|
725
|
+
VALUE v = rb_ary_entry( obj, i );
|
|
726
|
+
if ( v == from ) rb_ary_store( obj, i, to );
|
|
727
|
+
else syck_swap_placeholder( v, from, to, seen );
|
|
728
|
+
}
|
|
729
|
+
break;
|
|
730
|
+
|
|
731
|
+
case T_HASH:
|
|
732
|
+
{
|
|
733
|
+
VALUE keys = rb_funcall( obj, s_keys, 0 );
|
|
734
|
+
for ( i = 0; i < RARRAY_LEN( keys ); i++ )
|
|
735
|
+
{
|
|
736
|
+
VALUE key = rb_ary_entry( keys, i );
|
|
737
|
+
VALUE val = rb_hash_aref( obj, key );
|
|
738
|
+
|
|
739
|
+
if ( key == from || val == from )
|
|
740
|
+
{
|
|
741
|
+
VALUE new_key = key == from ? to : key;
|
|
742
|
+
VALUE new_val = val == from ? to : val;
|
|
743
|
+
|
|
744
|
+
if ( new_key != key ) rb_hash_delete( obj, key );
|
|
745
|
+
rb_hash_aset( obj, new_key, new_val );
|
|
746
|
+
key = new_key;
|
|
747
|
+
val = new_val;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
syck_swap_placeholder( key, from, to, seen );
|
|
751
|
+
syck_swap_placeholder( val, from, to, seen );
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
break;
|
|
755
|
+
|
|
756
|
+
case T_STRUCT:
|
|
757
|
+
for ( i = 0; i < RSTRUCT_LEN( obj ); i++ )
|
|
758
|
+
{
|
|
759
|
+
VALUE v = rb_struct_aref( obj, LONG2NUM( i ) );
|
|
760
|
+
if ( v == from ) rb_struct_aset( obj, LONG2NUM( i ), to );
|
|
761
|
+
else syck_swap_placeholder( v, from, to, seen );
|
|
762
|
+
}
|
|
763
|
+
break;
|
|
764
|
+
|
|
765
|
+
default:
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
ivars = rb_obj_instance_variables( obj );
|
|
770
|
+
for ( i = 0; i < RARRAY_LEN( ivars ); i++ )
|
|
771
|
+
{
|
|
772
|
+
ID name = SYM2ID( rb_ary_entry( ivars, i ) );
|
|
773
|
+
VALUE v = rb_ivar_get( obj, name );
|
|
774
|
+
if ( v == from ) rb_ivar_set( obj, name, to );
|
|
775
|
+
else syck_swap_placeholder( v, from, to, seen );
|
|
776
|
+
}
|
|
777
|
+
}
|
|
639
778
|
|
|
640
779
|
/*
|
|
641
780
|
* {native mode} node handler
|
|
@@ -645,6 +784,7 @@ SYMID
|
|
|
645
784
|
rb_syck_load_handler(SyckParser *p, SyckNode *n)
|
|
646
785
|
{
|
|
647
786
|
VALUE obj = Qnil;
|
|
787
|
+
VALUE node_wrapper;
|
|
648
788
|
struct parser_xtra *bonus = (struct parser_xtra *)p->bonus;
|
|
649
789
|
VALUE resolver = bonus->resolver;
|
|
650
790
|
if ( NIL_P( resolver ) )
|
|
@@ -655,16 +795,32 @@ rb_syck_load_handler(SyckParser *p, SyckNode *n)
|
|
|
655
795
|
/*
|
|
656
796
|
* Create node,
|
|
657
797
|
*/
|
|
658
|
-
|
|
798
|
+
node_wrapper = TypedData_Wrap_Struct( cNode, &syck_node_type_nofree, n );
|
|
799
|
+
obj = rb_funcall( resolver, s_node_import, 1, node_wrapper );
|
|
800
|
+
|
|
801
|
+
/*
|
|
802
|
+
* syck_hdlr_add_node frees `n` as soon as we return (handler.c:25, when
|
|
803
|
+
* the node has no anchor). Ruby may still keep `node_wrapper` reachable
|
|
804
|
+
* via a conservative GC root on the machine stack, so the next GC would
|
|
805
|
+
* call syck_node_mark() with a dangling SyckNode*. Zero the wrapper's
|
|
806
|
+
* data pointer to make the mark a no-op. See ruby/syck#50.
|
|
807
|
+
*/
|
|
808
|
+
DATA_PTR( node_wrapper ) = NULL;
|
|
659
809
|
|
|
660
810
|
/*
|
|
661
|
-
*
|
|
811
|
+
* A placeholder was handed out for this node while it was still being
|
|
812
|
+
* parsed. Syck used to fuse the two by copying the real object over the
|
|
813
|
+
* placeholder's heap slot, which is wrong on every count the GC cares
|
|
814
|
+
* about: the slot is sized for the placeholder, the copied flags carry
|
|
815
|
+
* the source object's age bits, no write barrier fires, and zeroing the
|
|
816
|
+
* source turns a live object into T_NONE behind the GC's back. The heap
|
|
817
|
+
* then stays corrupted until some unrelated allocation crashes. Rewrite
|
|
818
|
+
* the references instead.
|
|
662
819
|
*/
|
|
663
820
|
if (n->id > 0 && !NIL_P(obj))
|
|
664
821
|
{
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
obj = n->id;
|
|
822
|
+
syck_swap_placeholder( obj, (VALUE)n->id, obj, id_hash_new() );
|
|
823
|
+
n->id = obj;
|
|
668
824
|
}
|
|
669
825
|
|
|
670
826
|
if ( bonus->taint) OBJ_TAINT( obj );
|
|
@@ -701,7 +857,7 @@ rb_syck_bad_anchor_handler(SyckParser *p, char *a)
|
|
|
701
857
|
{
|
|
702
858
|
VALUE anchor_name = rb_str_new2( a );
|
|
703
859
|
SyckNode *badanc = syck_new_map( rb_str_new2( "name" ), anchor_name );
|
|
704
|
-
badanc->type_id = syck_strndup( "tag:ruby.yaml.org,2002:object:YAML::Syck::BadAlias",
|
|
860
|
+
badanc->type_id = syck_strndup( "tag:ruby.yaml.org,2002:object:YAML::Syck::BadAlias", 50 );
|
|
705
861
|
return badanc;
|
|
706
862
|
}
|
|
707
863
|
|
|
@@ -712,7 +868,7 @@ void
|
|
|
712
868
|
syck_set_model(VALUE p, VALUE input, VALUE model)
|
|
713
869
|
{
|
|
714
870
|
SyckParser *parser;
|
|
715
|
-
|
|
871
|
+
TypedData_Get_Struct(p, SyckParser, &syck_parser_type, parser);
|
|
716
872
|
syck_parser_handler( parser, rb_syck_load_handler );
|
|
717
873
|
/* WARN: gonna be obsoleted soon!! */
|
|
718
874
|
if ( model == sym_generic )
|
|
@@ -791,7 +947,7 @@ syck_parser_s_alloc(VALUE class)
|
|
|
791
947
|
parser->bonus = S_ALLOC( struct parser_xtra );
|
|
792
948
|
S_MEMZERO( parser->bonus, struct parser_xtra, 1 );
|
|
793
949
|
|
|
794
|
-
pobj =
|
|
950
|
+
pobj = TypedData_Wrap_Struct( class, &syck_parser_type, parser );
|
|
795
951
|
|
|
796
952
|
syck_parser_set_root_on_error( parser, Qnil );
|
|
797
953
|
|
|
@@ -828,7 +984,7 @@ syck_parser_bufsize_set(VALUE self, VALUE size)
|
|
|
828
984
|
|
|
829
985
|
if ( rb_respond_to( size, s_to_i ) ) {
|
|
830
986
|
int n = NUM2INT(rb_funcall(size, s_to_i, 0));
|
|
831
|
-
|
|
987
|
+
TypedData_Get_Struct(self, SyckParser, &syck_parser_type, parser);
|
|
832
988
|
parser->bufsize = n;
|
|
833
989
|
}
|
|
834
990
|
return self;
|
|
@@ -842,7 +998,7 @@ syck_parser_bufsize_get(VALUE self)
|
|
|
842
998
|
{
|
|
843
999
|
SyckParser *parser;
|
|
844
1000
|
|
|
845
|
-
|
|
1001
|
+
TypedData_Get_Struct(self, SyckParser, &syck_parser_type, parser);
|
|
846
1002
|
return INT2FIX( parser->bufsize );
|
|
847
1003
|
}
|
|
848
1004
|
|
|
@@ -860,7 +1016,7 @@ syck_parser_load(int argc, VALUE *argv, VALUE self)
|
|
|
860
1016
|
|
|
861
1017
|
input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input );
|
|
862
1018
|
model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model );
|
|
863
|
-
|
|
1019
|
+
TypedData_Get_Struct(self, SyckParser, &syck_parser_type, parser);
|
|
864
1020
|
syck_set_model( self, input, model );
|
|
865
1021
|
|
|
866
1022
|
bonus = (struct parser_xtra *)parser->bonus;
|
|
@@ -887,7 +1043,7 @@ syck_parser_load_documents(int argc, VALUE *argv, VALUE self)
|
|
|
887
1043
|
|
|
888
1044
|
input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input );
|
|
889
1045
|
model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model );
|
|
890
|
-
|
|
1046
|
+
TypedData_Get_Struct(self, SyckParser, &syck_parser_type, parser);
|
|
891
1047
|
syck_set_model( self, input, model );
|
|
892
1048
|
|
|
893
1049
|
bonus = (struct parser_xtra *)parser->bonus;
|
|
@@ -973,7 +1129,7 @@ syck_resolver_node_import(VALUE self, VALUE node)
|
|
|
973
1129
|
SyckNode *n;
|
|
974
1130
|
VALUE obj = Qnil;
|
|
975
1131
|
int i = 0;
|
|
976
|
-
|
|
1132
|
+
TypedData_Get_Struct(node, SyckNode, &syck_node_type, n);
|
|
977
1133
|
|
|
978
1134
|
switch (n->kind)
|
|
979
1135
|
{
|
|
@@ -1264,7 +1420,7 @@ syck_defaultresolver_node_import(VALUE self, VALUE node)
|
|
|
1264
1420
|
{
|
|
1265
1421
|
SyckNode *n;
|
|
1266
1422
|
VALUE obj;
|
|
1267
|
-
|
|
1423
|
+
TypedData_Get_Struct( node, SyckNode, &syck_node_type, n );
|
|
1268
1424
|
if ( !yaml_org_handler( n, &obj ) )
|
|
1269
1425
|
{
|
|
1270
1426
|
obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj );
|
|
@@ -1281,7 +1437,7 @@ syck_genericresolver_node_import(VALUE self, VALUE node)
|
|
|
1281
1437
|
SyckNode *n;
|
|
1282
1438
|
int i = 0;
|
|
1283
1439
|
VALUE t = Qnil, obj = Qnil, v = Qnil, style = Qnil;
|
|
1284
|
-
|
|
1440
|
+
TypedData_Get_Struct(node, SyckNode, &syck_node_type, n);
|
|
1285
1441
|
|
|
1286
1442
|
if ( n->type_id != NULL )
|
|
1287
1443
|
{
|
|
@@ -1413,6 +1569,7 @@ static void
|
|
|
1413
1569
|
syck_node_mark(SyckNode *n)
|
|
1414
1570
|
{
|
|
1415
1571
|
int i;
|
|
1572
|
+
if ( n == NULL ) return;
|
|
1416
1573
|
rb_gc_mark_maybe( n->id );
|
|
1417
1574
|
switch ( n->kind )
|
|
1418
1575
|
{
|
|
@@ -1448,7 +1605,7 @@ VALUE
|
|
|
1448
1605
|
syck_scalar_alloc(VALUE class)
|
|
1449
1606
|
{
|
|
1450
1607
|
SyckNode *node = syck_alloc_str();
|
|
1451
|
-
VALUE obj =
|
|
1608
|
+
VALUE obj = TypedData_Wrap_Struct( class, &syck_node_type, node );
|
|
1452
1609
|
node->id = obj;
|
|
1453
1610
|
return obj;
|
|
1454
1611
|
}
|
|
@@ -1473,7 +1630,7 @@ VALUE
|
|
|
1473
1630
|
syck_scalar_style_set(VALUE self, VALUE style)
|
|
1474
1631
|
{
|
|
1475
1632
|
SyckNode *node;
|
|
1476
|
-
|
|
1633
|
+
TypedData_Get_Struct( self, SyckNode, &syck_node_type, node );
|
|
1477
1634
|
|
|
1478
1635
|
if ( NIL_P( style ) )
|
|
1479
1636
|
{
|
|
@@ -1511,7 +1668,7 @@ VALUE
|
|
|
1511
1668
|
syck_scalar_value_set(VALUE self, VALUE val)
|
|
1512
1669
|
{
|
|
1513
1670
|
SyckNode *node;
|
|
1514
|
-
|
|
1671
|
+
TypedData_Get_Struct( self, SyckNode, &syck_node_type, node );
|
|
1515
1672
|
|
|
1516
1673
|
StringValue( val );
|
|
1517
1674
|
node->data.str->ptr = syck_strndup( RSTRING_PTR(val), RSTRING_LEN(val) );
|
|
@@ -1531,7 +1688,7 @@ syck_seq_alloc(VALUE class)
|
|
|
1531
1688
|
SyckNode *node;
|
|
1532
1689
|
VALUE obj;
|
|
1533
1690
|
node = syck_alloc_seq();
|
|
1534
|
-
obj =
|
|
1691
|
+
obj = TypedData_Wrap_Struct( class, &syck_node_type, node );
|
|
1535
1692
|
node->id = obj;
|
|
1536
1693
|
return obj;
|
|
1537
1694
|
}
|
|
@@ -1543,7 +1700,7 @@ VALUE
|
|
|
1543
1700
|
syck_seq_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style)
|
|
1544
1701
|
{
|
|
1545
1702
|
SyckNode *node;
|
|
1546
|
-
|
|
1703
|
+
TypedData_Get_Struct( self, SyckNode, &syck_node_type, node );
|
|
1547
1704
|
|
|
1548
1705
|
rb_iv_set( self, "@kind", sym_seq );
|
|
1549
1706
|
rb_funcall( self, s_type_id_set, 1, type_id );
|
|
@@ -1559,7 +1716,7 @@ VALUE
|
|
|
1559
1716
|
syck_seq_value_set(VALUE self, VALUE val)
|
|
1560
1717
|
{
|
|
1561
1718
|
SyckNode *node;
|
|
1562
|
-
|
|
1719
|
+
TypedData_Get_Struct( self, SyckNode, &syck_node_type, node );
|
|
1563
1720
|
|
|
1564
1721
|
val = rb_check_array_type( val );
|
|
1565
1722
|
if ( !NIL_P( val ) ) {
|
|
@@ -1583,7 +1740,7 @@ syck_seq_add_m(VALUE self, VALUE val)
|
|
|
1583
1740
|
{
|
|
1584
1741
|
SyckNode *node;
|
|
1585
1742
|
VALUE emitter = rb_ivar_get( self, s_emitter );
|
|
1586
|
-
|
|
1743
|
+
TypedData_Get_Struct( self, SyckNode, &syck_node_type, node );
|
|
1587
1744
|
|
|
1588
1745
|
if ( rb_respond_to( emitter, s_node_export ) ) {
|
|
1589
1746
|
val = rb_funcall( emitter, s_node_export, 1, val );
|
|
@@ -1601,7 +1758,7 @@ VALUE
|
|
|
1601
1758
|
syck_seq_style_set(VALUE self, VALUE style)
|
|
1602
1759
|
{
|
|
1603
1760
|
SyckNode *node;
|
|
1604
|
-
|
|
1761
|
+
TypedData_Get_Struct( self, SyckNode, &syck_node_type, node );
|
|
1605
1762
|
|
|
1606
1763
|
if ( style == sym_inline )
|
|
1607
1764
|
{
|
|
@@ -1625,7 +1782,7 @@ syck_map_alloc(VALUE class)
|
|
|
1625
1782
|
SyckNode *node;
|
|
1626
1783
|
VALUE obj;
|
|
1627
1784
|
node = syck_alloc_map();
|
|
1628
|
-
obj =
|
|
1785
|
+
obj = TypedData_Wrap_Struct( class, &syck_node_type, node );
|
|
1629
1786
|
node->id = obj;
|
|
1630
1787
|
return obj;
|
|
1631
1788
|
}
|
|
@@ -1637,7 +1794,7 @@ VALUE
|
|
|
1637
1794
|
syck_map_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style)
|
|
1638
1795
|
{
|
|
1639
1796
|
SyckNode *node;
|
|
1640
|
-
|
|
1797
|
+
TypedData_Get_Struct( self, SyckNode, &syck_node_type, node );
|
|
1641
1798
|
|
|
1642
1799
|
if ( !NIL_P( val ) )
|
|
1643
1800
|
{
|
|
@@ -1671,7 +1828,7 @@ VALUE
|
|
|
1671
1828
|
syck_map_value_set(VALUE self, VALUE val)
|
|
1672
1829
|
{
|
|
1673
1830
|
SyckNode *node;
|
|
1674
|
-
|
|
1831
|
+
TypedData_Get_Struct( self, SyckNode, &syck_node_type, node );
|
|
1675
1832
|
|
|
1676
1833
|
if ( !NIL_P( val ) )
|
|
1677
1834
|
{
|
|
@@ -1704,7 +1861,7 @@ syck_map_add_m(VALUE self, VALUE key, VALUE val)
|
|
|
1704
1861
|
{
|
|
1705
1862
|
SyckNode *node;
|
|
1706
1863
|
VALUE emitter = rb_ivar_get( self, s_emitter );
|
|
1707
|
-
|
|
1864
|
+
TypedData_Get_Struct( self, SyckNode, &syck_node_type, node );
|
|
1708
1865
|
|
|
1709
1866
|
if ( rb_respond_to( emitter, s_node_export ) ) {
|
|
1710
1867
|
key = rb_funcall( emitter, s_node_export, 1, key );
|
|
@@ -1723,7 +1880,7 @@ VALUE
|
|
|
1723
1880
|
syck_map_style_set(VALUE self, VALUE style)
|
|
1724
1881
|
{
|
|
1725
1882
|
SyckNode *node;
|
|
1726
|
-
|
|
1883
|
+
TypedData_Get_Struct( self, SyckNode, &syck_node_type, node );
|
|
1727
1884
|
|
|
1728
1885
|
if ( style == sym_inline )
|
|
1729
1886
|
{
|
|
@@ -1756,8 +1913,8 @@ syck_node_init_copy(VALUE copy, VALUE orig)
|
|
|
1756
1913
|
rb_raise( rb_eTypeError, "wrong argument type" );
|
|
1757
1914
|
}
|
|
1758
1915
|
|
|
1759
|
-
|
|
1760
|
-
|
|
1916
|
+
TypedData_Get_Struct( orig, SyckNode, &syck_node_type, orig_n );
|
|
1917
|
+
TypedData_Get_Struct( copy, SyckNode, &syck_node_type, copy_n );
|
|
1761
1918
|
MEMCPY( copy_n, orig_n, SyckNode, 1 );
|
|
1762
1919
|
return copy;
|
|
1763
1920
|
}
|
|
@@ -1770,7 +1927,7 @@ VALUE
|
|
|
1770
1927
|
syck_node_type_id_set(VALUE self, VALUE type_id)
|
|
1771
1928
|
{
|
|
1772
1929
|
SyckNode *node;
|
|
1773
|
-
|
|
1930
|
+
TypedData_Get_Struct( self, SyckNode, &syck_node_type, node );
|
|
1774
1931
|
|
|
1775
1932
|
S_FREE( node->type_id );
|
|
1776
1933
|
|
|
@@ -1792,8 +1949,8 @@ syck_node_transform(VALUE self)
|
|
|
1792
1949
|
VALUE t;
|
|
1793
1950
|
SyckNode *n = NULL;
|
|
1794
1951
|
SyckNode *orig_n;
|
|
1795
|
-
|
|
1796
|
-
t =
|
|
1952
|
+
TypedData_Get_Struct(self, SyckNode, &syck_node_type, orig_n);
|
|
1953
|
+
t = TypedData_Wrap_Struct( cNode, &syck_node_type, 0 );
|
|
1797
1954
|
|
|
1798
1955
|
switch (orig_n->kind)
|
|
1799
1956
|
{
|
|
@@ -1846,7 +2003,7 @@ void
|
|
|
1846
2003
|
rb_syck_emitter_handler(SyckEmitter *e, st_data_t data)
|
|
1847
2004
|
{
|
|
1848
2005
|
SyckNode *n;
|
|
1849
|
-
|
|
2006
|
+
TypedData_Get_Struct((VALUE)data, SyckNode, &syck_node_type, n);
|
|
1850
2007
|
|
|
1851
2008
|
switch (n->kind)
|
|
1852
2009
|
{
|
|
@@ -1907,7 +2064,7 @@ syck_out_mark(VALUE emitter, VALUE node)
|
|
|
1907
2064
|
{
|
|
1908
2065
|
SyckEmitter *emitterPtr;
|
|
1909
2066
|
struct emitter_xtra *bonus;
|
|
1910
|
-
|
|
2067
|
+
TypedData_Get_Struct(emitter, SyckEmitter, &syck_emitter_type, emitterPtr);
|
|
1911
2068
|
bonus = (struct emitter_xtra *)emitterPtr->bonus;
|
|
1912
2069
|
rb_ivar_set( node, s_emitter, emitter );
|
|
1913
2070
|
/* syck_emitter_mark_node( emitterPtr, (st_data_t)node ); */
|
|
@@ -1951,7 +2108,7 @@ syck_emitter_s_alloc(VALUE class)
|
|
|
1951
2108
|
emitter->bonus = S_ALLOC( struct emitter_xtra );
|
|
1952
2109
|
S_MEMZERO( emitter->bonus, struct emitter_xtra, 1 );
|
|
1953
2110
|
|
|
1954
|
-
pobj =
|
|
2111
|
+
pobj = TypedData_Wrap_Struct( class, &syck_emitter_type, emitter );
|
|
1955
2112
|
syck_emitter_handler( emitter, rb_syck_emitter_handler );
|
|
1956
2113
|
syck_output_handler( emitter, rb_syck_output_handler );
|
|
1957
2114
|
|
|
@@ -1978,7 +2135,7 @@ syck_emitter_reset(int argc, VALUE *argv, VALUE self)
|
|
|
1978
2135
|
SyckEmitter *emitter;
|
|
1979
2136
|
struct emitter_xtra *bonus;
|
|
1980
2137
|
|
|
1981
|
-
|
|
2138
|
+
TypedData_Get_Struct(self, SyckEmitter, &syck_emitter_type, emitter);
|
|
1982
2139
|
bonus = (struct emitter_xtra *)emitter->bonus;
|
|
1983
2140
|
|
|
1984
2141
|
bonus->oid = Qnil;
|
|
@@ -2024,7 +2181,7 @@ syck_emitter_emit(int argc, VALUE *argv, VALUE self)
|
|
|
2024
2181
|
rb_ivar_set(self, s_level, INT2FIX(level));
|
|
2025
2182
|
|
|
2026
2183
|
rb_scan_args(argc, argv, "1&", &oid, &proc);
|
|
2027
|
-
|
|
2184
|
+
TypedData_Get_Struct(self, SyckEmitter, &syck_emitter_type, emitter);
|
|
2028
2185
|
bonus = (struct emitter_xtra *)emitter->bonus;
|
|
2029
2186
|
|
|
2030
2187
|
/* Calculate anchors, normalize nodes, build a simpler symbol table */
|
data/ext/syck/yaml2byte.c
CHANGED
|
@@ -115,9 +115,7 @@ void bytestring_extend(bytestring_t *str, bytestring_t *ext)
|
|
|
115
115
|
|
|
116
116
|
/* convert SyckNode into yamlbyte_buffer_t objects */
|
|
117
117
|
SYMID
|
|
118
|
-
syck_yaml2byte_handler(p, n)
|
|
119
|
-
SyckParser *p;
|
|
120
|
-
SyckNode *n;
|
|
118
|
+
syck_yaml2byte_handler(SyckParser *p, SyckNode *n)
|
|
121
119
|
{
|
|
122
120
|
SYMID oid;
|
|
123
121
|
long i;
|
data/lib/syck/constants.rb
CHANGED
data/test/test_boolean.rb
CHANGED
|
@@ -32,5 +32,17 @@ module Syck
|
|
|
32
32
|
assert_equal "n", Syck.load("--- n")
|
|
33
33
|
assert_equal "N", Syck.load("--- N")
|
|
34
34
|
end
|
|
35
|
+
|
|
36
|
+
###
|
|
37
|
+
# https://github.com/ruby/syck/issues/22
|
|
38
|
+
# A boolean-like prefix followed by a non-ASCII byte must not be
|
|
39
|
+
# matched as a boolean
|
|
40
|
+
def test_bool_prefix_with_non_ascii
|
|
41
|
+
assert_equal "Noémie", Syck.load("--- Noémie")
|
|
42
|
+
assert_equal ["Noémie"], Syck.load("--- [Noémie]")
|
|
43
|
+
assert_equal "Yeså", Syck.load("--- Yeså")
|
|
44
|
+
assert_equal "trueé", Syck.load("--- trueé")
|
|
45
|
+
assert_equal "nullé", Syck.load("--- nullé")
|
|
46
|
+
end
|
|
35
47
|
end
|
|
36
48
|
end
|
data/test/test_gc.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require_relative "helper"
|
|
2
|
+
|
|
3
|
+
# Regression test for ruby/syck#50 - heap-use-after-free in syck_node_mark
|
|
4
|
+
# when GC runs between syck_hdlr_add_node freeing a SyckNode and the Ruby
|
|
5
|
+
# Data wrapper that pointed at it being collected.
|
|
6
|
+
#
|
|
7
|
+
# GC.stress forces a full GC on every allocation, so if the fix regresses
|
|
8
|
+
# this test will segfault (or fire under ASAN/valgrind).
|
|
9
|
+
class TestGC < Test::Unit::TestCase
|
|
10
|
+
def test_load_under_gc_stress
|
|
11
|
+
yaml = ({}.tap { |h| 50.times { |i| h["k#{i}"] = "v" * 64 } }).to_yaml
|
|
12
|
+
|
|
13
|
+
GC.stress = true
|
|
14
|
+
begin
|
|
15
|
+
3.times { Syck.load(yaml) }
|
|
16
|
+
ensure
|
|
17
|
+
GC.stress = false
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_load_many_documents_under_gc_stress
|
|
22
|
+
docs = Array.new(5) do |i|
|
|
23
|
+
({}.tap { |h| 30.times { |k| h["k_#{i}_#{k}"] = "v_#{i}_#{k}" } }).to_yaml
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
GC.stress = true
|
|
27
|
+
begin
|
|
28
|
+
docs.each { |d| Syck.load(d) }
|
|
29
|
+
ensure
|
|
30
|
+
GC.stress = false
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/test/test_yaml.rb
CHANGED
|
@@ -1337,6 +1337,40 @@ EOY
|
|
|
1337
1337
|
assert_equal( inspect_str, Syck::load( a.to_yaml ).inspect )
|
|
1338
1338
|
end
|
|
1339
1339
|
|
|
1340
|
+
#
|
|
1341
|
+
# A self-referential anchor is aliased before the anchored node exists, so
|
|
1342
|
+
# the parser hands out a placeholder and patches it up afterwards. That
|
|
1343
|
+
# used to be done by overwriting the placeholder's heap slot, which left
|
|
1344
|
+
# the GC heap corrupted and crashed at some later allocation.
|
|
1345
|
+
#
|
|
1346
|
+
def test_self_referential_anchor
|
|
1347
|
+
[ 1, 3, 6, 50 ].each do |n|
|
|
1348
|
+
seq = Syck::load( "--- &id001\n" + "- *id001\n" * n )
|
|
1349
|
+
assert_equal( n, seq.size )
|
|
1350
|
+
seq.each { |item| assert_same( seq, item ) }
|
|
1351
|
+
end
|
|
1352
|
+
|
|
1353
|
+
map = Syck::load( "--- &id001\nself: *id001\n" )
|
|
1354
|
+
assert_same( map, map["self"] )
|
|
1355
|
+
|
|
1356
|
+
keyed = Syck::load( "--- &id001\n? *id001\n: 1\n" )
|
|
1357
|
+
assert_same( keyed, keyed.keys.first )
|
|
1358
|
+
|
|
1359
|
+
# The alias appears as a key and again below the matching value, so
|
|
1360
|
+
# rewriting the key must not stop the walk from reaching the rest.
|
|
1361
|
+
both = Syck::load( "--- &id001\n? *id001\n: \n - *id001\n" )
|
|
1362
|
+
key, value = both.first
|
|
1363
|
+
assert_same( both, key )
|
|
1364
|
+
assert_same( both, value[0] )
|
|
1365
|
+
|
|
1366
|
+
nested = Syck::load( "--- &id001\n- &id002\n - *id001\n- *id002\n" )
|
|
1367
|
+
assert_same( nested, nested[0][0] )
|
|
1368
|
+
assert_same( nested[0], nested[1] )
|
|
1369
|
+
|
|
1370
|
+
GC.start
|
|
1371
|
+
assert_nothing_raised { GC.verify_internal_consistency }
|
|
1372
|
+
end
|
|
1373
|
+
|
|
1340
1374
|
#
|
|
1341
1375
|
# Test Symbol cycle
|
|
1342
1376
|
#
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: syck
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hiroshi SHIBATA
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
- Mat Brown
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: bundler
|
|
@@ -100,12 +100,12 @@ files:
|
|
|
100
100
|
- lib/syck/yamlnode.rb
|
|
101
101
|
- lib/syck/ypath.rb
|
|
102
102
|
- lib/yaml/syck.rb
|
|
103
|
-
- syck.gemspec
|
|
104
103
|
- test/helper.rb
|
|
105
104
|
- test/test_array.rb
|
|
106
105
|
- test/test_boolean.rb
|
|
107
106
|
- test/test_class.rb
|
|
108
107
|
- test/test_exception.rb
|
|
108
|
+
- test/test_gc.rb
|
|
109
109
|
- test/test_hash.rb
|
|
110
110
|
- test/test_null.rb
|
|
111
111
|
- test/test_omap.rb
|
|
@@ -136,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
136
136
|
- !ruby/object:Gem::Version
|
|
137
137
|
version: 0.9.5
|
|
138
138
|
requirements: []
|
|
139
|
-
rubygems_version: 3.6.
|
|
139
|
+
rubygems_version: 3.6.9
|
|
140
140
|
specification_version: 4
|
|
141
141
|
summary: A gemified version of Syck from Ruby's stdlib
|
|
142
142
|
test_files:
|
|
@@ -145,6 +145,7 @@ test_files:
|
|
|
145
145
|
- test/test_boolean.rb
|
|
146
146
|
- test/test_class.rb
|
|
147
147
|
- test/test_exception.rb
|
|
148
|
+
- test/test_gc.rb
|
|
148
149
|
- test/test_hash.rb
|
|
149
150
|
- test/test_null.rb
|
|
150
151
|
- test/test_omap.rb
|
data/syck.gemspec
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
|
-
|
|
3
|
-
Gem::Specification.new do |s|
|
|
4
|
-
s.name = "syck"
|
|
5
|
-
s.version = "1.5.1.1"
|
|
6
|
-
|
|
7
|
-
s.summary = "A gemified version of Syck from Ruby's stdlib"
|
|
8
|
-
s.description = "A gemified version of Syck from Ruby's stdlib. Syck has been removed from\nRuby's stdlib, and this gem is meant to bridge the gap for people that haven't\nupdated their YAML yet."
|
|
9
|
-
s.authors = ["Hiroshi SHIBATA", "Aaron Patterson", "Mat Brown"]
|
|
10
|
-
s.email = ["hsbt@ruby-lang.org", "aaron@tenderlovemaking.com"]
|
|
11
|
-
s.homepage = "https://github.com/ruby/syck"
|
|
12
|
-
s.license = "MIT"
|
|
13
|
-
s.require_paths = ["lib"]
|
|
14
|
-
s.extensions = ["ext/syck/extconf.rb"]
|
|
15
|
-
s.files = Dir["[A-Z]*", "ext/**/*", "lib/**/*.rb", "test/**/*.rb"] - %w[Gemfile.lock ext/syck/gram.y]
|
|
16
|
-
s.extra_rdoc_files = ["README.rdoc"]
|
|
17
|
-
s.test_files = Dir["test/**/*.rb"]
|
|
18
|
-
s.rdoc_options = ["--main", "README.rdoc"]
|
|
19
|
-
s.required_ruby_version = Gem::Requirement.new(">= 2.0.0")
|
|
20
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0.9.5")
|
|
21
|
-
s.rubygems_version = "2.0.3"
|
|
22
|
-
|
|
23
|
-
s.add_development_dependency(%q<bundler>)
|
|
24
|
-
s.add_development_dependency(%q<test-unit>)
|
|
25
|
-
s.add_development_dependency(%q<rake-compiler>)
|
|
26
|
-
end
|