nokogiri 1.14.2 → 1.16.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +19 -15
- data/README.md +4 -1
- data/dependencies.yml +9 -8
- data/ext/nokogiri/extconf.rb +69 -26
- data/ext/nokogiri/html4_document.c +1 -2
- data/ext/nokogiri/html4_element_description.c +19 -14
- data/ext/nokogiri/html4_sax_parser_context.c +10 -16
- data/ext/nokogiri/html4_sax_push_parser.c +3 -3
- data/ext/nokogiri/nokogiri.c +46 -24
- data/ext/nokogiri/nokogiri.h +23 -5
- data/ext/nokogiri/test_global_handlers.c +1 -1
- data/ext/nokogiri/xml_attr.c +1 -1
- data/ext/nokogiri/xml_cdata.c +30 -17
- data/ext/nokogiri/xml_comment.c +1 -1
- data/ext/nokogiri/xml_document.c +113 -25
- data/ext/nokogiri/xml_document_fragment.c +1 -1
- data/ext/nokogiri/xml_dtd.c +1 -1
- data/ext/nokogiri/xml_element_content.c +32 -29
- data/ext/nokogiri/xml_element_decl.c +5 -5
- data/ext/nokogiri/xml_encoding_handler.c +12 -4
- data/ext/nokogiri/xml_entity_reference.c +1 -1
- data/ext/nokogiri/xml_namespace.c +11 -16
- data/ext/nokogiri/xml_node.c +13 -16
- data/ext/nokogiri/xml_node_set.c +125 -105
- data/ext/nokogiri/xml_processing_instruction.c +1 -1
- data/ext/nokogiri/xml_reader.c +61 -74
- data/ext/nokogiri/xml_relax_ng.c +66 -79
- data/ext/nokogiri/xml_sax_parser.c +24 -5
- data/ext/nokogiri/xml_sax_parser_context.c +50 -25
- data/ext/nokogiri/xml_sax_push_parser.c +30 -9
- data/ext/nokogiri/xml_schema.c +94 -115
- data/ext/nokogiri/xml_syntax_error.c +3 -3
- data/ext/nokogiri/xml_text.c +26 -13
- data/ext/nokogiri/xml_xpath_context.c +153 -83
- data/ext/nokogiri/xslt_stylesheet.c +111 -53
- data/gumbo-parser/Makefile +18 -0
- data/gumbo-parser/src/error.c +8 -4
- data/gumbo-parser/src/foreign_attrs.c +13 -14
- data/gumbo-parser/src/foreign_attrs.gperf +1 -1
- data/gumbo-parser/src/parser.c +21 -5
- data/gumbo-parser/src/tokenizer.c +1 -0
- data/lib/nokogiri/css/parser_extras.rb +1 -1
- data/lib/nokogiri/css/xpath_visitor.rb +3 -23
- data/lib/nokogiri/extension.rb +1 -1
- data/lib/nokogiri/html4/document.rb +1 -1
- data/lib/nokogiri/html4/document_fragment.rb +1 -1
- data/lib/nokogiri/html4/element_description_defaults.rb +1821 -353
- data/lib/nokogiri/html4/encoding_reader.rb +1 -1
- data/lib/nokogiri/html5/document_fragment.rb +1 -1
- data/lib/nokogiri/html5/node.rb +5 -0
- data/lib/nokogiri/html5.rb +0 -63
- data/lib/nokogiri/jruby/nokogiri_jars.rb +9 -9
- data/lib/nokogiri/version/constant.rb +1 -1
- data/lib/nokogiri/version/info.rb +6 -5
- data/lib/nokogiri/xml/attr.rb +2 -2
- data/lib/nokogiri/xml/attribute_decl.rb +4 -2
- data/lib/nokogiri/xml/document.rb +4 -5
- data/lib/nokogiri/xml/document_fragment.rb +3 -3
- data/lib/nokogiri/xml/element_content.rb +10 -2
- data/lib/nokogiri/xml/element_decl.rb +4 -2
- data/lib/nokogiri/xml/entity_decl.rb +4 -2
- data/lib/nokogiri/xml/namespace.rb +1 -2
- data/lib/nokogiri/xml/node/save_options.rb +8 -0
- data/lib/nokogiri/xml/node.rb +53 -37
- data/lib/nokogiri/xml/node_set.rb +3 -3
- data/lib/nokogiri/xml/pp/node.rb +23 -12
- data/lib/nokogiri/xml/reader.rb +10 -9
- data/lib/nokogiri/xml/sax/document.rb +1 -1
- data/lib/nokogiri/xml/searchable.rb +21 -13
- data/lib/nokogiri/xml/syntax_error.rb +1 -1
- data/lib/nokogiri/xml.rb +1 -1
- data/lib/nokogiri/xslt/stylesheet.rb +29 -7
- data/lib/nokogiri/xslt.rb +74 -4
- data/lib/nokogiri.rb +13 -5
- data/lib/xsd/xmlparser/nokogiri.rb +1 -1
- data/patches/libxml2/0010-update-config.guess-and-config.sub-for-libxml2.patch +224 -0
- data/patches/libxml2/0011-rip-out-libxml2-s-libc_single_threaded-support.patch +30 -0
- data/patches/libxslt/0001-update-config.guess-and-config.sub-for-libxslt.patch +224 -0
- data/ports/archives/libxml2-2.12.8.tar.xz +0 -0
- data/ports/archives/libxslt-1.1.39.tar.xz +0 -0
- metadata +16 -12
- data/patches/libxslt/0001-update-automake-files-for-arm64.patch +0 -3037
- data/ports/archives/libxml2-2.10.3.tar.xz +0 -0
- data/ports/archives/libxslt-1.1.37.tar.xz +0 -0
@@ -5,12 +5,40 @@ VALUE cNokogiriXmlSaxParserContext ;
|
|
5
5
|
static ID id_read;
|
6
6
|
|
7
7
|
static void
|
8
|
-
|
8
|
+
xml_sax_parser_context_free(void *data)
|
9
9
|
{
|
10
|
+
xmlParserCtxtPtr ctxt = data;
|
10
11
|
ctxt->sax = NULL;
|
11
12
|
xmlFreeParserCtxt(ctxt);
|
12
13
|
}
|
13
14
|
|
15
|
+
/*
|
16
|
+
* note that htmlParserCtxtPtr == xmlParserCtxtPtr and xmlFreeParserCtxt() == htmlFreeParserCtxt()
|
17
|
+
* so we use this type for both XML::SAX::ParserContext and HTML::SAX::ParserContext
|
18
|
+
*/
|
19
|
+
static const rb_data_type_t xml_sax_parser_context_type = {
|
20
|
+
.wrap_struct_name = "Nokogiri::XML::SAX::ParserContext",
|
21
|
+
.function = {
|
22
|
+
.dfree = xml_sax_parser_context_free,
|
23
|
+
},
|
24
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
25
|
+
};
|
26
|
+
|
27
|
+
xmlParserCtxtPtr
|
28
|
+
noko_xml_sax_parser_context_unwrap(VALUE rb_context)
|
29
|
+
{
|
30
|
+
xmlParserCtxtPtr c_context;
|
31
|
+
TypedData_Get_Struct(rb_context, xmlParserCtxt, &xml_sax_parser_context_type, c_context);
|
32
|
+
return c_context;
|
33
|
+
}
|
34
|
+
|
35
|
+
VALUE
|
36
|
+
noko_xml_sax_parser_context_wrap(VALUE klass, xmlParserCtxtPtr c_context)
|
37
|
+
{
|
38
|
+
return TypedData_Wrap_Struct(klass, &xml_sax_parser_context_type, c_context);
|
39
|
+
}
|
40
|
+
|
41
|
+
|
14
42
|
/*
|
15
43
|
* call-seq:
|
16
44
|
* parse_io(io, encoding)
|
@@ -31,12 +59,16 @@ parse_io(VALUE klass, VALUE io, VALUE encoding)
|
|
31
59
|
(xmlInputReadCallback)noko_io_read,
|
32
60
|
(xmlInputCloseCallback)noko_io_close,
|
33
61
|
(void *)io, enc);
|
62
|
+
if (!ctxt) {
|
63
|
+
rb_raise(rb_eRuntimeError, "failed to create xml sax parser context");
|
64
|
+
}
|
65
|
+
|
34
66
|
if (ctxt->sax) {
|
35
67
|
xmlFree(ctxt->sax);
|
36
68
|
ctxt->sax = NULL;
|
37
69
|
}
|
38
70
|
|
39
|
-
return
|
71
|
+
return noko_xml_sax_parser_context_wrap(klass, ctxt);
|
40
72
|
}
|
41
73
|
|
42
74
|
/*
|
@@ -49,7 +81,13 @@ static VALUE
|
|
49
81
|
parse_file(VALUE klass, VALUE filename)
|
50
82
|
{
|
51
83
|
xmlParserCtxtPtr ctxt = xmlCreateFileParserCtxt(StringValueCStr(filename));
|
52
|
-
|
84
|
+
|
85
|
+
if (ctxt->sax) {
|
86
|
+
xmlFree(ctxt->sax);
|
87
|
+
ctxt->sax = NULL;
|
88
|
+
}
|
89
|
+
|
90
|
+
return noko_xml_sax_parser_context_wrap(klass, ctxt);
|
53
91
|
}
|
54
92
|
|
55
93
|
/*
|
@@ -76,7 +114,7 @@ parse_memory(VALUE klass, VALUE data)
|
|
76
114
|
ctxt->sax = NULL;
|
77
115
|
}
|
78
116
|
|
79
|
-
return
|
117
|
+
return noko_xml_sax_parser_context_wrap(klass, ctxt);
|
80
118
|
}
|
81
119
|
|
82
120
|
static VALUE
|
@@ -116,13 +154,8 @@ parse_with(VALUE self, VALUE sax_handler)
|
|
116
154
|
rb_raise(rb_eArgError, "argument must be a Nokogiri::XML::SAX::Parser");
|
117
155
|
}
|
118
156
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
/* Free the sax handler since we'll assign our own */
|
123
|
-
if (ctxt->sax && ctxt->sax != (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) {
|
124
|
-
xmlFree(ctxt->sax);
|
125
|
-
}
|
157
|
+
ctxt = noko_xml_sax_parser_context_unwrap(self);
|
158
|
+
sax = noko_sax_handler_unwrap(sax_handler);
|
126
159
|
|
127
160
|
ctxt->sax = sax;
|
128
161
|
ctxt->userData = (void *)NOKOGIRI_SAX_TUPLE_NEW(ctxt, sax_handler);
|
@@ -144,8 +177,7 @@ parse_with(VALUE self, VALUE sax_handler)
|
|
144
177
|
static VALUE
|
145
178
|
set_replace_entities(VALUE self, VALUE value)
|
146
179
|
{
|
147
|
-
xmlParserCtxtPtr ctxt;
|
148
|
-
Data_Get_Struct(self, xmlParserCtxt, ctxt);
|
180
|
+
xmlParserCtxtPtr ctxt = noko_xml_sax_parser_context_unwrap(self);
|
149
181
|
|
150
182
|
if (Qfalse == value) {
|
151
183
|
ctxt->replaceEntities = 0;
|
@@ -166,8 +198,7 @@ set_replace_entities(VALUE self, VALUE value)
|
|
166
198
|
static VALUE
|
167
199
|
get_replace_entities(VALUE self)
|
168
200
|
{
|
169
|
-
xmlParserCtxtPtr ctxt;
|
170
|
-
Data_Get_Struct(self, xmlParserCtxt, ctxt);
|
201
|
+
xmlParserCtxtPtr ctxt = noko_xml_sax_parser_context_unwrap(self);
|
171
202
|
|
172
203
|
if (0 == ctxt->replaceEntities) {
|
173
204
|
return Qfalse;
|
@@ -184,10 +215,8 @@ get_replace_entities(VALUE self)
|
|
184
215
|
static VALUE
|
185
216
|
line(VALUE self)
|
186
217
|
{
|
187
|
-
xmlParserCtxtPtr ctxt;
|
188
218
|
xmlParserInputPtr io;
|
189
|
-
|
190
|
-
Data_Get_Struct(self, xmlParserCtxt, ctxt);
|
219
|
+
xmlParserCtxtPtr ctxt = noko_xml_sax_parser_context_unwrap(self);
|
191
220
|
|
192
221
|
io = ctxt->input;
|
193
222
|
if (io) {
|
@@ -205,11 +234,9 @@ line(VALUE self)
|
|
205
234
|
static VALUE
|
206
235
|
column(VALUE self)
|
207
236
|
{
|
208
|
-
xmlParserCtxtPtr ctxt;
|
237
|
+
xmlParserCtxtPtr ctxt = noko_xml_sax_parser_context_unwrap(self);
|
209
238
|
xmlParserInputPtr io;
|
210
239
|
|
211
|
-
Data_Get_Struct(self, xmlParserCtxt, ctxt);
|
212
|
-
|
213
240
|
io = ctxt->input;
|
214
241
|
if (io) {
|
215
242
|
return INT2NUM(io->col);
|
@@ -228,8 +255,7 @@ column(VALUE self)
|
|
228
255
|
static VALUE
|
229
256
|
set_recovery(VALUE self, VALUE value)
|
230
257
|
{
|
231
|
-
xmlParserCtxtPtr ctxt;
|
232
|
-
Data_Get_Struct(self, xmlParserCtxt, ctxt);
|
258
|
+
xmlParserCtxtPtr ctxt = noko_xml_sax_parser_context_unwrap(self);
|
233
259
|
|
234
260
|
if (value == Qfalse) {
|
235
261
|
ctxt->recovery = 0;
|
@@ -250,8 +276,7 @@ set_recovery(VALUE self, VALUE value)
|
|
250
276
|
static VALUE
|
251
277
|
get_recovery(VALUE self)
|
252
278
|
{
|
253
|
-
xmlParserCtxtPtr ctxt;
|
254
|
-
Data_Get_Struct(self, xmlParserCtxt, ctxt);
|
279
|
+
xmlParserCtxtPtr ctxt = noko_xml_sax_parser_context_unwrap(self);
|
255
280
|
|
256
281
|
if (ctxt->recovery == 0) {
|
257
282
|
return Qfalse;
|
@@ -3,18 +3,35 @@
|
|
3
3
|
VALUE cNokogiriXmlSaxPushParser ;
|
4
4
|
|
5
5
|
static void
|
6
|
-
|
6
|
+
xml_sax_push_parser_free(void *data)
|
7
7
|
{
|
8
|
+
xmlParserCtxtPtr ctx = data;
|
8
9
|
if (ctx != NULL) {
|
9
10
|
NOKOGIRI_SAX_TUPLE_DESTROY(ctx->userData);
|
10
11
|
xmlFreeParserCtxt(ctx);
|
11
12
|
}
|
12
13
|
}
|
13
14
|
|
15
|
+
static const rb_data_type_t xml_sax_push_parser_type = {
|
16
|
+
.wrap_struct_name = "Nokogiri::XML::SAX::PushParser",
|
17
|
+
.function = {
|
18
|
+
.dfree = xml_sax_push_parser_free,
|
19
|
+
},
|
20
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
21
|
+
};
|
22
|
+
|
14
23
|
static VALUE
|
15
24
|
allocate(VALUE klass)
|
16
25
|
{
|
17
|
-
return
|
26
|
+
return TypedData_Wrap_Struct(klass, &xml_sax_push_parser_type, NULL);
|
27
|
+
}
|
28
|
+
|
29
|
+
xmlParserCtxtPtr
|
30
|
+
noko_xml_sax_push_parser_unwrap(VALUE rb_parser)
|
31
|
+
{
|
32
|
+
xmlParserCtxtPtr c_parser;
|
33
|
+
TypedData_Get_Struct(rb_parser, xmlParserCtxt, &xml_sax_push_parser_type, c_parser);
|
34
|
+
return c_parser;
|
18
35
|
}
|
19
36
|
|
20
37
|
/*
|
@@ -31,7 +48,7 @@ native_write(VALUE self, VALUE _chunk, VALUE _last_chunk)
|
|
31
48
|
int size = 0;
|
32
49
|
|
33
50
|
|
34
|
-
|
51
|
+
ctx = noko_xml_sax_push_parser_unwrap(self);
|
35
52
|
|
36
53
|
if (Qnil != _chunk) {
|
37
54
|
chunk = StringValuePtr(_chunk);
|
@@ -42,7 +59,7 @@ native_write(VALUE self, VALUE _chunk, VALUE _last_chunk)
|
|
42
59
|
|
43
60
|
if (xmlParseChunk(ctx, chunk, size, Qtrue == _last_chunk ? 1 : 0)) {
|
44
61
|
if (!(ctx->options & XML_PARSE_RECOVER)) {
|
45
|
-
|
62
|
+
xmlErrorConstPtr e = xmlCtxtGetLastError(ctx);
|
46
63
|
Nokogiri_error_raise(NULL, e);
|
47
64
|
}
|
48
65
|
}
|
@@ -63,7 +80,7 @@ initialize_native(VALUE self, VALUE _xml_sax, VALUE _filename)
|
|
63
80
|
const char *filename = NULL;
|
64
81
|
xmlParserCtxtPtr ctx;
|
65
82
|
|
66
|
-
|
83
|
+
sax = noko_sax_handler_unwrap(_xml_sax);
|
67
84
|
|
68
85
|
if (_filename != Qnil) { filename = StringValueCStr(_filename); }
|
69
86
|
|
@@ -89,7 +106,8 @@ static VALUE
|
|
89
106
|
get_options(VALUE self)
|
90
107
|
{
|
91
108
|
xmlParserCtxtPtr ctx;
|
92
|
-
|
109
|
+
|
110
|
+
ctx = noko_xml_sax_push_parser_unwrap(self);
|
93
111
|
|
94
112
|
return INT2NUM(ctx->options);
|
95
113
|
}
|
@@ -98,7 +116,8 @@ static VALUE
|
|
98
116
|
set_options(VALUE self, VALUE options)
|
99
117
|
{
|
100
118
|
xmlParserCtxtPtr ctx;
|
101
|
-
|
119
|
+
|
120
|
+
ctx = noko_xml_sax_push_parser_unwrap(self);
|
102
121
|
|
103
122
|
if (xmlCtxtUseOptions(ctx, (int)NUM2INT(options)) != 0) {
|
104
123
|
rb_raise(rb_eRuntimeError, "Cannot set XML parser context options");
|
@@ -118,7 +137,8 @@ static VALUE
|
|
118
137
|
get_replace_entities(VALUE self)
|
119
138
|
{
|
120
139
|
xmlParserCtxtPtr ctx;
|
121
|
-
|
140
|
+
|
141
|
+
ctx = noko_xml_sax_push_parser_unwrap(self);
|
122
142
|
|
123
143
|
if (0 == ctx->replaceEntities) {
|
124
144
|
return Qfalse;
|
@@ -138,7 +158,8 @@ static VALUE
|
|
138
158
|
set_replace_entities(VALUE self, VALUE value)
|
139
159
|
{
|
140
160
|
xmlParserCtxtPtr ctx;
|
141
|
-
|
161
|
+
|
162
|
+
ctx = noko_xml_sax_push_parser_unwrap(self);
|
142
163
|
|
143
164
|
if (Qfalse == value) {
|
144
165
|
ctx->replaceEntities = 0;
|
data/ext/nokogiri/xml_schema.c
CHANGED
@@ -3,11 +3,20 @@
|
|
3
3
|
VALUE cNokogiriXmlSchema;
|
4
4
|
|
5
5
|
static void
|
6
|
-
|
6
|
+
xml_schema_deallocate(void *data)
|
7
7
|
{
|
8
|
+
xmlSchemaPtr schema = data;
|
8
9
|
xmlSchemaFree(schema);
|
9
10
|
}
|
10
11
|
|
12
|
+
static const rb_data_type_t xml_schema_type = {
|
13
|
+
.wrap_struct_name = "Nokogiri::XML::Schema",
|
14
|
+
.function = {
|
15
|
+
.dfree = xml_schema_deallocate,
|
16
|
+
},
|
17
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
18
|
+
};
|
19
|
+
|
11
20
|
/*
|
12
21
|
* call-seq:
|
13
22
|
* validate_document(document)
|
@@ -22,8 +31,8 @@ validate_document(VALUE self, VALUE document)
|
|
22
31
|
xmlSchemaValidCtxtPtr valid_ctxt;
|
23
32
|
VALUE errors;
|
24
33
|
|
25
|
-
|
26
|
-
|
34
|
+
TypedData_Get_Struct(self, xmlSchema, &xml_schema_type, schema);
|
35
|
+
doc = noko_xml_document_unwrap(document);
|
27
36
|
|
28
37
|
errors = rb_ary_new();
|
29
38
|
|
@@ -63,7 +72,7 @@ validate_file(VALUE self, VALUE rb_filename)
|
|
63
72
|
const char *filename ;
|
64
73
|
VALUE errors;
|
65
74
|
|
66
|
-
|
75
|
+
TypedData_Get_Struct(self, xmlSchema, &xml_schema_type, schema);
|
67
76
|
filename = (const char *)StringValueCStr(rb_filename) ;
|
68
77
|
|
69
78
|
errors = rb_ary_new();
|
@@ -90,60 +99,54 @@ validate_file(VALUE self, VALUE rb_filename)
|
|
90
99
|
return errors;
|
91
100
|
}
|
92
101
|
|
93
|
-
/*
|
94
|
-
* call-seq:
|
95
|
-
* read_memory(string)
|
96
|
-
*
|
97
|
-
* Create a new Schema from the contents of +string+
|
98
|
-
*/
|
99
102
|
static VALUE
|
100
|
-
|
103
|
+
xml_schema_parse_schema(
|
104
|
+
VALUE klass,
|
105
|
+
xmlSchemaParserCtxtPtr c_parser_context,
|
106
|
+
VALUE rb_parse_options
|
107
|
+
)
|
101
108
|
{
|
102
|
-
VALUE
|
103
|
-
VALUE parse_options;
|
109
|
+
VALUE rb_errors;
|
104
110
|
int parse_options_int;
|
105
|
-
|
106
|
-
xmlSchemaPtr schema;
|
107
|
-
VALUE errors;
|
108
|
-
VALUE rb_schema;
|
109
|
-
int scanned_args = 0;
|
111
|
+
xmlSchemaPtr c_schema;
|
110
112
|
xmlExternalEntityLoader old_loader = 0;
|
113
|
+
VALUE rb_schema;
|
111
114
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
+
if (NIL_P(rb_parse_options)) {
|
116
|
+
rb_parse_options = rb_const_get_at(
|
117
|
+
rb_const_get_at(mNokogiriXml, rb_intern("ParseOptions")),
|
118
|
+
rb_intern("DEFAULT_SCHEMA")
|
119
|
+
);
|
115
120
|
}
|
116
|
-
parse_options_int = (int)NUM2INT(rb_funcall(parse_options, rb_intern("to_i"), 0));
|
117
121
|
|
118
|
-
|
119
|
-
|
120
|
-
errors = rb_ary_new();
|
121
|
-
xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher);
|
122
|
+
rb_errors = rb_ary_new();
|
123
|
+
xmlSetStructuredErrorFunc((void *)rb_errors, Nokogiri_error_array_pusher);
|
122
124
|
|
123
125
|
#ifdef HAVE_XMLSCHEMASETPARSERSTRUCTUREDERRORS
|
124
126
|
xmlSchemaSetParserStructuredErrors(
|
125
|
-
|
127
|
+
c_parser_context,
|
126
128
|
Nokogiri_error_array_pusher,
|
127
|
-
(void *)
|
129
|
+
(void *)rb_errors
|
128
130
|
);
|
129
131
|
#endif
|
130
132
|
|
133
|
+
parse_options_int = (int)NUM2INT(rb_funcall(rb_parse_options, rb_intern("to_i"), 0));
|
131
134
|
if (parse_options_int & XML_PARSE_NONET) {
|
132
135
|
old_loader = xmlGetExternalEntityLoader();
|
133
136
|
xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
|
134
137
|
}
|
135
138
|
|
136
|
-
|
139
|
+
c_schema = xmlSchemaParse(c_parser_context);
|
137
140
|
|
138
141
|
if (old_loader) {
|
139
142
|
xmlSetExternalEntityLoader(old_loader);
|
140
143
|
}
|
141
144
|
|
142
145
|
xmlSetStructuredErrorFunc(NULL, NULL);
|
143
|
-
xmlSchemaFreeParserCtxt(
|
146
|
+
xmlSchemaFreeParserCtxt(c_parser_context);
|
144
147
|
|
145
|
-
if (NULL ==
|
146
|
-
|
148
|
+
if (NULL == c_schema) {
|
149
|
+
xmlErrorConstPtr error = xmlGetLastError();
|
147
150
|
if (error) {
|
148
151
|
Nokogiri_error_raise(NULL, error);
|
149
152
|
} else {
|
@@ -153,118 +156,94 @@ read_memory(int argc, VALUE *argv, VALUE klass)
|
|
153
156
|
return Qnil;
|
154
157
|
}
|
155
158
|
|
156
|
-
rb_schema =
|
157
|
-
rb_iv_set(rb_schema, "@errors",
|
158
|
-
rb_iv_set(rb_schema, "@parse_options",
|
159
|
+
rb_schema = TypedData_Wrap_Struct(klass, &xml_schema_type, c_schema);
|
160
|
+
rb_iv_set(rb_schema, "@errors", rb_errors);
|
161
|
+
rb_iv_set(rb_schema, "@parse_options", rb_parse_options);
|
159
162
|
|
160
163
|
return rb_schema;
|
161
164
|
}
|
162
165
|
|
163
|
-
/*
|
164
|
-
*
|
165
|
-
*
|
166
|
-
*
|
166
|
+
/*
|
167
|
+
* call-seq:
|
168
|
+
* read_memory(string) → Nokogiri::XML::Schema
|
169
|
+
*
|
170
|
+
* Create a new schema parsed from the contents of +string+
|
171
|
+
*
|
172
|
+
* [Parameters]
|
173
|
+
* - +string+: String containing XML to be parsed as a schema
|
174
|
+
*
|
175
|
+
* [Returns] Nokogiri::XML::Schema
|
167
176
|
*/
|
168
|
-
static
|
169
|
-
|
177
|
+
static VALUE
|
178
|
+
read_memory(int argc, VALUE *argv, VALUE klass)
|
170
179
|
{
|
171
|
-
|
180
|
+
VALUE rb_content;
|
181
|
+
VALUE rb_parse_options;
|
182
|
+
xmlSchemaParserCtxtPtr c_parser_context;
|
172
183
|
|
173
|
-
|
174
|
-
return 0;
|
175
|
-
}
|
184
|
+
rb_scan_args(argc, argv, "11", &rb_content, &rb_parse_options);
|
176
185
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
if (xmlIsBlankNode(node)) {
|
182
|
-
return 1;
|
183
|
-
}
|
184
|
-
}
|
186
|
+
c_parser_context = xmlSchemaNewMemParserCtxt(
|
187
|
+
(const char *)StringValuePtr(rb_content),
|
188
|
+
(int)RSTRING_LEN(rb_content)
|
189
|
+
);
|
185
190
|
|
186
|
-
return
|
191
|
+
return xml_schema_parse_schema(klass, c_parser_context, rb_parse_options);
|
187
192
|
}
|
188
193
|
|
189
194
|
/*
|
190
195
|
* call-seq:
|
191
|
-
*
|
196
|
+
* from_document(document) → Nokogiri::XML::Schema
|
192
197
|
*
|
193
|
-
* Create a new
|
198
|
+
* Create a new schema parsed from the +document+.
|
199
|
+
*
|
200
|
+
* [Parameters]
|
201
|
+
* - +document+: Nokogiri::XML::Document to be parsed
|
202
|
+
*
|
203
|
+
* [Returns] Nokogiri::XML::Schema
|
194
204
|
*/
|
195
205
|
static VALUE
|
196
|
-
|
206
|
+
rb_xml_schema_s_from_document(int argc, VALUE *argv, VALUE klass)
|
197
207
|
{
|
198
|
-
VALUE
|
199
|
-
VALUE
|
200
|
-
int parse_options_int;
|
201
|
-
xmlDocPtr doc;
|
202
|
-
xmlSchemaParserCtxtPtr ctx;
|
203
|
-
xmlSchemaPtr schema;
|
204
|
-
VALUE errors;
|
208
|
+
VALUE rb_document;
|
209
|
+
VALUE rb_parse_options;
|
205
210
|
VALUE rb_schema;
|
206
|
-
|
207
|
-
|
211
|
+
xmlDocPtr c_document;
|
212
|
+
xmlSchemaParserCtxtPtr c_parser_context;
|
213
|
+
int defensive_copy_p = 0;
|
208
214
|
|
209
|
-
|
215
|
+
rb_scan_args(argc, argv, "11", &rb_document, &rb_parse_options);
|
210
216
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
parse_options = rb_const_get_at(rb_const_get_at(mNokogiriXml, rb_intern("ParseOptions")), rb_intern("DEFAULT_SCHEMA"));
|
217
|
+
if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlNode)) {
|
218
|
+
rb_raise(rb_eTypeError,
|
219
|
+
"expected parameter to be a Nokogiri::XML::Document, received %"PRIsVALUE,
|
220
|
+
rb_obj_class(rb_document));
|
216
221
|
}
|
217
|
-
parse_options_int = (int)NUM2INT(rb_funcall(parse_options, rb_intern("to_i"), 0));
|
218
222
|
|
219
|
-
if (
|
220
|
-
|
223
|
+
if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlDocument)) {
|
224
|
+
xmlNodePtr deprecated_node_type_arg;
|
225
|
+
NOKO_WARN_DEPRECATION("Passing a Node as the first parameter to Schema.from_document is deprecated. Please pass a Document instead. This will become an error in Nokogiri v1.17.0."); // TODO: deprecated in v1.15.3, remove in v1.17.0
|
226
|
+
Noko_Node_Get_Struct(rb_document, xmlNode, deprecated_node_type_arg);
|
227
|
+
c_document = deprecated_node_type_arg->doc;
|
228
|
+
} else {
|
229
|
+
c_document = noko_xml_document_unwrap(rb_document);
|
221
230
|
}
|
222
231
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
#ifdef HAVE_XMLSCHEMASETPARSERSTRUCTUREDERRORS
|
229
|
-
xmlSchemaSetParserStructuredErrors(
|
230
|
-
ctx,
|
231
|
-
Nokogiri_error_array_pusher,
|
232
|
-
(void *)errors
|
233
|
-
);
|
234
|
-
#endif
|
235
|
-
|
236
|
-
if (parse_options_int & XML_PARSE_NONET) {
|
237
|
-
old_loader = xmlGetExternalEntityLoader();
|
238
|
-
xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
|
232
|
+
if (noko_xml_document_has_wrapped_blank_nodes_p(c_document)) {
|
233
|
+
// see https://github.com/sparklemotion/nokogiri/pull/2001
|
234
|
+
c_document = xmlCopyDoc(c_document, 1);
|
235
|
+
defensive_copy_p = 1;
|
239
236
|
}
|
240
237
|
|
241
|
-
|
238
|
+
c_parser_context = xmlSchemaNewDocParserCtxt(c_document);
|
239
|
+
rb_schema = xml_schema_parse_schema(klass, c_parser_context, rb_parse_options);
|
242
240
|
|
243
|
-
if (
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
xmlSetStructuredErrorFunc(NULL, NULL);
|
248
|
-
xmlSchemaFreeParserCtxt(ctx);
|
249
|
-
|
250
|
-
if (NULL == schema) {
|
251
|
-
xmlErrorPtr error = xmlGetLastError();
|
252
|
-
if (error) {
|
253
|
-
Nokogiri_error_raise(NULL, error);
|
254
|
-
} else {
|
255
|
-
rb_raise(rb_eRuntimeError, "Could not parse document");
|
256
|
-
}
|
257
|
-
|
258
|
-
return Qnil;
|
241
|
+
if (defensive_copy_p) {
|
242
|
+
xmlFreeDoc(c_document);
|
243
|
+
c_document = NULL;
|
259
244
|
}
|
260
245
|
|
261
|
-
rb_schema = Data_Wrap_Struct(klass, 0, dealloc, schema);
|
262
|
-
rb_iv_set(rb_schema, "@errors", errors);
|
263
|
-
rb_iv_set(rb_schema, "@parse_options", parse_options);
|
264
|
-
|
265
246
|
return rb_schema;
|
266
|
-
|
267
|
-
return Qnil;
|
268
247
|
}
|
269
248
|
|
270
249
|
void
|
@@ -275,7 +254,7 @@ noko_init_xml_schema(void)
|
|
275
254
|
rb_undef_alloc_func(cNokogiriXmlSchema);
|
276
255
|
|
277
256
|
rb_define_singleton_method(cNokogiriXmlSchema, "read_memory", read_memory, -1);
|
278
|
-
rb_define_singleton_method(cNokogiriXmlSchema, "from_document",
|
257
|
+
rb_define_singleton_method(cNokogiriXmlSchema, "from_document", rb_xml_schema_s_from_document, -1);
|
279
258
|
|
280
259
|
rb_define_private_method(cNokogiriXmlSchema, "validate_document", validate_document, 1);
|
281
260
|
rb_define_private_method(cNokogiriXmlSchema, "validate_file", validate_file, 1);
|
@@ -26,7 +26,7 @@ Nokogiri_structured_error_func_restore(libxmlStructuredErrorHandlerState *handle
|
|
26
26
|
}
|
27
27
|
|
28
28
|
void
|
29
|
-
Nokogiri_error_array_pusher(void *ctx,
|
29
|
+
Nokogiri_error_array_pusher(void *ctx, xmlErrorConstPtr error)
|
30
30
|
{
|
31
31
|
VALUE list = (VALUE)ctx;
|
32
32
|
Check_Type(list, T_ARRAY);
|
@@ -34,13 +34,13 @@ Nokogiri_error_array_pusher(void *ctx, xmlErrorPtr error)
|
|
34
34
|
}
|
35
35
|
|
36
36
|
void
|
37
|
-
Nokogiri_error_raise(void *ctx,
|
37
|
+
Nokogiri_error_raise(void *ctx, xmlErrorConstPtr error)
|
38
38
|
{
|
39
39
|
rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
|
40
40
|
}
|
41
41
|
|
42
42
|
VALUE
|
43
|
-
Nokogiri_wrap_xml_syntax_error(
|
43
|
+
Nokogiri_wrap_xml_syntax_error(xmlErrorConstPtr error)
|
44
44
|
{
|
45
45
|
VALUE msg, e, klass;
|
46
46
|
|
data/ext/nokogiri/xml_text.c
CHANGED
@@ -9,25 +9,38 @@ VALUE cNokogiriXmlText ;
|
|
9
9
|
* Create a new Text element on the +document+ with +content+
|
10
10
|
*/
|
11
11
|
static VALUE
|
12
|
-
|
12
|
+
rb_xml_text_s_new(int argc, VALUE *argv, VALUE klass)
|
13
13
|
{
|
14
|
-
xmlDocPtr
|
15
|
-
xmlNodePtr
|
16
|
-
VALUE
|
17
|
-
VALUE
|
18
|
-
VALUE
|
14
|
+
xmlDocPtr c_document;
|
15
|
+
xmlNodePtr c_node;
|
16
|
+
VALUE rb_string;
|
17
|
+
VALUE rb_document;
|
18
|
+
VALUE rb_rest;
|
19
19
|
VALUE rb_node;
|
20
20
|
|
21
|
-
rb_scan_args(argc, argv, "2*", &
|
21
|
+
rb_scan_args(argc, argv, "2*", &rb_string, &rb_document, &rb_rest);
|
22
22
|
|
23
|
-
|
23
|
+
if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlNode)) {
|
24
|
+
rb_raise(rb_eTypeError,
|
25
|
+
"expected second parameter to be a Nokogiri::XML::Document, received %"PRIsVALUE,
|
26
|
+
rb_obj_class(rb_document));
|
27
|
+
}
|
24
28
|
|
25
|
-
|
26
|
-
|
29
|
+
if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlDocument)) {
|
30
|
+
xmlNodePtr deprecated_node_type_arg;
|
31
|
+
NOKO_WARN_DEPRECATION("Passing a Node as the second parameter to Text.new is deprecated. Please pass a Document instead. This will become an error in Nokogiri v1.17.0."); // TODO: deprecated in v1.15.3, remove in v1.17.0
|
32
|
+
Noko_Node_Get_Struct(rb_document, xmlNode, deprecated_node_type_arg);
|
33
|
+
c_document = deprecated_node_type_arg->doc;
|
34
|
+
} else {
|
35
|
+
c_document = noko_xml_document_unwrap(rb_document);
|
36
|
+
}
|
27
37
|
|
28
|
-
|
38
|
+
c_node = xmlNewText((xmlChar *)StringValueCStr(rb_string));
|
39
|
+
c_node->doc = c_document;
|
29
40
|
|
30
|
-
|
41
|
+
noko_xml_document_pin_node(c_node);
|
42
|
+
|
43
|
+
rb_node = noko_xml_node_wrap(klass, c_node) ;
|
31
44
|
rb_obj_call_init(rb_node, argc, argv);
|
32
45
|
|
33
46
|
if (rb_block_given_p()) { rb_yield(rb_node); }
|
@@ -44,5 +57,5 @@ noko_init_xml_text(void)
|
|
44
57
|
*/
|
45
58
|
cNokogiriXmlText = rb_define_class_under(mNokogiriXml, "Text", cNokogiriXmlCharacterData);
|
46
59
|
|
47
|
-
rb_define_singleton_method(cNokogiriXmlText, "new",
|
60
|
+
rb_define_singleton_method(cNokogiriXmlText, "new", rb_xml_text_s_new, -1);
|
48
61
|
}
|