nokogiri 1.16.0 → 1.18.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +14 -16
  3. data/LICENSE-DEPENDENCIES.md +6 -6
  4. data/README.md +8 -5
  5. data/dependencies.yml +9 -9
  6. data/ext/nokogiri/extconf.rb +188 -142
  7. data/ext/nokogiri/gumbo.c +69 -53
  8. data/ext/nokogiri/html4_document.c +10 -4
  9. data/ext/nokogiri/html4_element_description.c +18 -18
  10. data/ext/nokogiri/html4_sax_parser.c +40 -0
  11. data/ext/nokogiri/html4_sax_parser_context.c +48 -58
  12. data/ext/nokogiri/html4_sax_push_parser.c +25 -24
  13. data/ext/nokogiri/libxml2_polyfill.c +114 -0
  14. data/ext/nokogiri/nokogiri.c +9 -2
  15. data/ext/nokogiri/nokogiri.h +18 -33
  16. data/ext/nokogiri/xml_attr.c +1 -1
  17. data/ext/nokogiri/xml_cdata.c +2 -10
  18. data/ext/nokogiri/xml_comment.c +3 -8
  19. data/ext/nokogiri/xml_document.c +167 -156
  20. data/ext/nokogiri/xml_document_fragment.c +10 -25
  21. data/ext/nokogiri/xml_dtd.c +1 -1
  22. data/ext/nokogiri/xml_element_content.c +9 -9
  23. data/ext/nokogiri/xml_encoding_handler.c +4 -4
  24. data/ext/nokogiri/xml_namespace.c +6 -6
  25. data/ext/nokogiri/xml_node.c +141 -104
  26. data/ext/nokogiri/xml_node_set.c +46 -44
  27. data/ext/nokogiri/xml_reader.c +74 -57
  28. data/ext/nokogiri/xml_relax_ng.c +35 -56
  29. data/ext/nokogiri/xml_sax_parser.c +156 -88
  30. data/ext/nokogiri/xml_sax_parser_context.c +219 -131
  31. data/ext/nokogiri/xml_sax_push_parser.c +68 -49
  32. data/ext/nokogiri/xml_schema.c +50 -85
  33. data/ext/nokogiri/xml_syntax_error.c +19 -11
  34. data/ext/nokogiri/xml_text.c +2 -4
  35. data/ext/nokogiri/xml_xpath_context.c +103 -100
  36. data/ext/nokogiri/xslt_stylesheet.c +16 -11
  37. data/gumbo-parser/Makefile +3 -0
  38. data/gumbo-parser/src/ascii.c +2 -2
  39. data/gumbo-parser/src/error.c +76 -48
  40. data/gumbo-parser/src/error.h +5 -1
  41. data/gumbo-parser/src/nokogiri_gumbo.h +11 -2
  42. data/gumbo-parser/src/parser.c +66 -25
  43. data/gumbo-parser/src/tokenizer.c +6 -6
  44. data/lib/nokogiri/class_resolver.rb +1 -1
  45. data/lib/nokogiri/css/node.rb +6 -2
  46. data/lib/nokogiri/css/parser.rb +6 -4
  47. data/lib/nokogiri/css/parser.y +2 -2
  48. data/lib/nokogiri/css/parser_extras.rb +6 -66
  49. data/lib/nokogiri/css/selector_cache.rb +38 -0
  50. data/lib/nokogiri/css/tokenizer.rb +4 -4
  51. data/lib/nokogiri/css/tokenizer.rex +9 -8
  52. data/lib/nokogiri/css/xpath_visitor.rb +42 -6
  53. data/lib/nokogiri/css.rb +86 -20
  54. data/lib/nokogiri/decorators/slop.rb +3 -5
  55. data/lib/nokogiri/encoding_handler.rb +2 -2
  56. data/lib/nokogiri/html4/document.rb +44 -23
  57. data/lib/nokogiri/html4/document_fragment.rb +124 -12
  58. data/lib/nokogiri/html4/encoding_reader.rb +1 -1
  59. data/lib/nokogiri/html4/sax/parser.rb +23 -38
  60. data/lib/nokogiri/html4/sax/parser_context.rb +4 -9
  61. data/lib/nokogiri/html4.rb +9 -14
  62. data/lib/nokogiri/html5/builder.rb +40 -0
  63. data/lib/nokogiri/html5/document.rb +61 -30
  64. data/lib/nokogiri/html5/document_fragment.rb +130 -20
  65. data/lib/nokogiri/html5/node.rb +4 -4
  66. data/lib/nokogiri/html5.rb +114 -72
  67. data/lib/nokogiri/version/constant.rb +1 -1
  68. data/lib/nokogiri/xml/builder.rb +8 -1
  69. data/lib/nokogiri/xml/document.rb +70 -26
  70. data/lib/nokogiri/xml/document_fragment.rb +84 -13
  71. data/lib/nokogiri/xml/node.rb +82 -11
  72. data/lib/nokogiri/xml/node_set.rb +9 -7
  73. data/lib/nokogiri/xml/parse_options.rb +1 -1
  74. data/lib/nokogiri/xml/pp/node.rb +6 -1
  75. data/lib/nokogiri/xml/reader.rb +51 -17
  76. data/lib/nokogiri/xml/relax_ng.rb +57 -20
  77. data/lib/nokogiri/xml/sax/document.rb +174 -83
  78. data/lib/nokogiri/xml/sax/parser.rb +115 -41
  79. data/lib/nokogiri/xml/sax/parser_context.rb +116 -8
  80. data/lib/nokogiri/xml/sax/push_parser.rb +3 -0
  81. data/lib/nokogiri/xml/sax.rb +48 -0
  82. data/lib/nokogiri/xml/schema.rb +112 -45
  83. data/lib/nokogiri/xml/searchable.rb +38 -42
  84. data/lib/nokogiri/xml/syntax_error.rb +22 -0
  85. data/lib/nokogiri/xml/xpath_context.rb +14 -3
  86. data/lib/nokogiri/xml.rb +13 -24
  87. data/lib/nokogiri/xslt/stylesheet.rb +29 -7
  88. data/lib/nokogiri/xslt.rb +3 -9
  89. data/lib/xsd/xmlparser/nokogiri.rb +3 -4
  90. data/patches/libxml2/0019-xpath-Use-separate-static-hash-table-for-standard-fu.patch +244 -0
  91. data/ports/archives/libxml2-2.13.5.tar.xz +0 -0
  92. data/ports/archives/libxslt-1.1.42.tar.xz +0 -0
  93. metadata +13 -14
  94. data/ext/nokogiri/libxml2_backwards_compat.c +0 -121
  95. data/patches/libxml2/0003-libxml2.la-is-in-top_builddir.patch +0 -25
  96. data/ports/archives/libxml2-2.12.3.tar.xz +0 -0
  97. data/ports/archives/libxslt-1.1.39.tar.xz +0 -0
@@ -6,14 +6,16 @@ static void
6
6
  xml_sax_push_parser_free(void *data)
7
7
  {
8
8
  xmlParserCtxtPtr ctx = data;
9
- if (ctx != NULL) {
10
- NOKOGIRI_SAX_TUPLE_DESTROY(ctx->userData);
9
+ if (ctx->myDoc) {
10
+ xmlFreeDoc(ctx->myDoc);
11
+ }
12
+ if (ctx) {
11
13
  xmlFreeParserCtxt(ctx);
12
14
  }
13
15
  }
14
16
 
15
17
  static const rb_data_type_t xml_sax_push_parser_type = {
16
- .wrap_struct_name = "Nokogiri::XML::SAX::PushParser",
18
+ .wrap_struct_name = "xmlParserCtxt",
17
19
  .function = {
18
20
  .dfree = xml_sax_push_parser_free,
19
21
  },
@@ -21,7 +23,7 @@ static const rb_data_type_t xml_sax_push_parser_type = {
21
23
  };
22
24
 
23
25
  static VALUE
24
- allocate(VALUE klass)
26
+ xml_sax_push_parser_allocate(VALUE klass)
25
27
  {
26
28
  return TypedData_Wrap_Struct(klass, &xml_sax_push_parser_type, NULL);
27
29
  }
@@ -35,19 +37,15 @@ noko_xml_sax_push_parser_unwrap(VALUE rb_parser)
35
37
  }
36
38
 
37
39
  /*
38
- * call-seq:
39
- * native_write(chunk, last_chunk)
40
- *
41
40
  * Write +chunk+ to PushParser. +last_chunk+ triggers the end_document handle
42
41
  */
43
42
  static VALUE
44
- native_write(VALUE self, VALUE _chunk, VALUE _last_chunk)
43
+ noko_xml_sax_push_parser__native_write(VALUE self, VALUE _chunk, VALUE _last_chunk)
45
44
  {
46
45
  xmlParserCtxtPtr ctx;
47
46
  const char *chunk = NULL;
48
47
  int size = 0;
49
48
 
50
-
51
49
  ctx = noko_xml_sax_push_parser_unwrap(self);
52
50
 
53
51
  if (Qnil != _chunk) {
@@ -58,9 +56,9 @@ native_write(VALUE self, VALUE _chunk, VALUE _last_chunk)
58
56
  xmlSetStructuredErrorFunc(NULL, NULL);
59
57
 
60
58
  if (xmlParseChunk(ctx, chunk, size, Qtrue == _last_chunk ? 1 : 0)) {
61
- if (!(ctx->options & XML_PARSE_RECOVER)) {
59
+ if (!(xmlCtxtGetOptions(ctx) & XML_PARSE_RECOVER)) {
62
60
  xmlErrorConstPtr e = xmlCtxtGetLastError(ctx);
63
- Nokogiri_error_raise(NULL, e);
61
+ noko__error_raise(NULL, e);
64
62
  }
65
63
  }
66
64
 
@@ -74,13 +72,13 @@ native_write(VALUE self, VALUE _chunk, VALUE _last_chunk)
74
72
  * Initialize the push parser with +xml_sax+ using +filename+
75
73
  */
76
74
  static VALUE
77
- initialize_native(VALUE self, VALUE _xml_sax, VALUE _filename)
75
+ noko_xml_sax_push_parser__initialize_native(VALUE self, VALUE _xml_sax, VALUE _filename)
78
76
  {
79
77
  xmlSAXHandlerPtr sax;
80
78
  const char *filename = NULL;
81
79
  xmlParserCtxtPtr ctx;
82
80
 
83
- sax = noko_sax_handler_unwrap(_xml_sax);
81
+ sax = noko_xml_sax_parser_unwrap(_xml_sax);
84
82
 
85
83
  if (_filename != Qnil) { filename = StringValueCStr(_filename); }
86
84
 
@@ -95,32 +93,34 @@ initialize_native(VALUE self, VALUE _xml_sax, VALUE _filename)
95
93
  rb_raise(rb_eRuntimeError, "Could not create a parser context");
96
94
  }
97
95
 
98
- ctx->userData = NOKOGIRI_SAX_TUPLE_NEW(ctx, self);
96
+ ctx->userData = ctx;
97
+ ctx->_private = (void *)_xml_sax;
99
98
 
100
- ctx->sax2 = 1;
101
99
  DATA_PTR(self) = ctx;
102
100
  return self;
103
101
  }
104
102
 
105
103
  static VALUE
106
- get_options(VALUE self)
104
+ noko_xml_sax_push_parser__options_get(VALUE self)
107
105
  {
108
106
  xmlParserCtxtPtr ctx;
109
107
 
110
108
  ctx = noko_xml_sax_push_parser_unwrap(self);
111
109
 
112
- return INT2NUM(ctx->options);
110
+ return INT2NUM(xmlCtxtGetOptions(ctx));
113
111
  }
114
112
 
115
113
  static VALUE
116
- set_options(VALUE self, VALUE options)
114
+ noko_xml_sax_push_parser__options_set(VALUE self, VALUE options)
117
115
  {
116
+ int error;
118
117
  xmlParserCtxtPtr ctx;
119
118
 
120
119
  ctx = noko_xml_sax_push_parser_unwrap(self);
121
120
 
122
- if (xmlCtxtUseOptions(ctx, (int)NUM2INT(options)) != 0) {
123
- rb_raise(rb_eRuntimeError, "Cannot set XML parser context options");
121
+ error = xmlCtxtSetOptions(ctx, (int)NUM2INT(options));
122
+ if (error) {
123
+ rb_raise(rb_eRuntimeError, "Cannot set XML parser context options (%x)", error);
124
124
  }
125
125
 
126
126
  return Qnil;
@@ -128,43 +128,56 @@ set_options(VALUE self, VALUE options)
128
128
 
129
129
  /*
130
130
  * call-seq:
131
- * replace_entities
131
+ * replace_entities
132
+ *
133
+ * See Document@Entity+Handling for an explanation of the behavior controlled by this flag.
134
+ *
135
+ * [Returns] (Boolean) Value of the parse option. (Default +false+)
132
136
  *
133
- * Should this parser replace entities? & will get converted to '&' if
134
- * set to true
137
+ * This option is perhaps misnamed by the libxml2 author, since it controls resolution and not
138
+ * replacement.
135
139
  */
136
140
  static VALUE
137
- get_replace_entities(VALUE self)
141
+ noko_xml_sax_push_parser__replace_entities_get(VALUE self)
138
142
  {
139
- xmlParserCtxtPtr ctx;
140
-
141
- ctx = noko_xml_sax_push_parser_unwrap(self);
143
+ xmlParserCtxtPtr ctxt = noko_xml_sax_push_parser_unwrap(self);
142
144
 
143
- if (0 == ctx->replaceEntities) {
144
- return Qfalse;
145
- } else {
145
+ if (xmlCtxtGetOptions(ctxt) & XML_PARSE_NOENT) {
146
146
  return Qtrue;
147
+ } else {
148
+ return Qfalse;
147
149
  }
148
150
  }
149
151
 
150
152
  /*
151
153
  * call-seq:
152
- * replace_entities=(boolean)
154
+ * replace_entities=(value)
155
+ *
156
+ * See Document@Entity+Handling for an explanation of the behavior controlled by this flag.
157
+ *
158
+ * [Parameters]
159
+ * - +value+ (Boolean) Whether external parsed entities will be resolved.
153
160
  *
154
- * Should this parser replace entities? & will get converted to '&' if
155
- * set to true
161
+ * <b>It is UNSAFE to set this option to +true+</b> when parsing untrusted documents. The option
162
+ * defaults to +false+ for this reason.
163
+ *
164
+ * This option is perhaps misnamed by the libxml2 author, since it controls resolution and not
165
+ * replacement.
156
166
  */
157
167
  static VALUE
158
- set_replace_entities(VALUE self, VALUE value)
168
+ noko_xml_sax_push_parser__replace_entities_set(VALUE self, VALUE value)
159
169
  {
160
- xmlParserCtxtPtr ctx;
170
+ int error;
171
+ xmlParserCtxtPtr ctxt = noko_xml_sax_push_parser_unwrap(self);
161
172
 
162
- ctx = noko_xml_sax_push_parser_unwrap(self);
163
-
164
- if (Qfalse == value) {
165
- ctx->replaceEntities = 0;
173
+ if (RB_TEST(value)) {
174
+ error = xmlCtxtSetOptions(ctxt, xmlCtxtGetOptions(ctxt) | XML_PARSE_NOENT);
166
175
  } else {
167
- ctx->replaceEntities = 1;
176
+ error = xmlCtxtSetOptions(ctxt, xmlCtxtGetOptions(ctxt) & ~XML_PARSE_NOENT);
177
+ }
178
+
179
+ if (error) {
180
+ rb_raise(rb_eRuntimeError, "failed to set parser context options (%x)", error);
168
181
  }
169
182
 
170
183
  return value;
@@ -175,13 +188,19 @@ noko_init_xml_sax_push_parser(void)
175
188
  {
176
189
  cNokogiriXmlSaxPushParser = rb_define_class_under(mNokogiriXmlSax, "PushParser", rb_cObject);
177
190
 
178
- rb_define_alloc_func(cNokogiriXmlSaxPushParser, allocate);
179
-
180
- rb_define_method(cNokogiriXmlSaxPushParser, "options", get_options, 0);
181
- rb_define_method(cNokogiriXmlSaxPushParser, "options=", set_options, 1);
182
- rb_define_method(cNokogiriXmlSaxPushParser, "replace_entities", get_replace_entities, 0);
183
- rb_define_method(cNokogiriXmlSaxPushParser, "replace_entities=", set_replace_entities, 1);
184
-
185
- rb_define_private_method(cNokogiriXmlSaxPushParser, "initialize_native", initialize_native, 2);
186
- rb_define_private_method(cNokogiriXmlSaxPushParser, "native_write", native_write, 2);
191
+ rb_define_alloc_func(cNokogiriXmlSaxPushParser, xml_sax_push_parser_allocate);
192
+
193
+ rb_define_method(cNokogiriXmlSaxPushParser, "options",
194
+ noko_xml_sax_push_parser__options_get, 0);
195
+ rb_define_method(cNokogiriXmlSaxPushParser, "options=",
196
+ noko_xml_sax_push_parser__options_set, 1);
197
+ rb_define_method(cNokogiriXmlSaxPushParser, "replace_entities",
198
+ noko_xml_sax_push_parser__replace_entities_get, 0);
199
+ rb_define_method(cNokogiriXmlSaxPushParser, "replace_entities=",
200
+ noko_xml_sax_push_parser__replace_entities_set, 1);
201
+
202
+ rb_define_private_method(cNokogiriXmlSaxPushParser, "initialize_native",
203
+ noko_xml_sax_push_parser__initialize_native, 2);
204
+ rb_define_private_method(cNokogiriXmlSaxPushParser, "native_write",
205
+ noko_xml_sax_push_parser__native_write, 2);
187
206
  }
@@ -10,21 +10,15 @@ xml_schema_deallocate(void *data)
10
10
  }
11
11
 
12
12
  static const rb_data_type_t xml_schema_type = {
13
- .wrap_struct_name = "Nokogiri::XML::Schema",
13
+ .wrap_struct_name = "xmlSchema",
14
14
  .function = {
15
15
  .dfree = xml_schema_deallocate,
16
16
  },
17
17
  .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
18
18
  };
19
19
 
20
- /*
21
- * call-seq:
22
- * validate_document(document)
23
- *
24
- * Validate a Nokogiri::XML::Document against this Schema.
25
- */
26
20
  static VALUE
27
- validate_document(VALUE self, VALUE document)
21
+ noko_xml_schema__validate_document(VALUE self, VALUE document)
28
22
  {
29
23
  xmlDocPtr doc;
30
24
  xmlSchemaPtr schema;
@@ -43,29 +37,27 @@ validate_document(VALUE self, VALUE document)
43
37
  rb_raise(rb_eRuntimeError, "Could not create a validation context");
44
38
  }
45
39
 
46
- #ifdef HAVE_XMLSCHEMASETVALIDSTRUCTUREDERRORS
47
40
  xmlSchemaSetValidStructuredErrors(
48
41
  valid_ctxt,
49
- Nokogiri_error_array_pusher,
42
+ noko__error_array_pusher,
50
43
  (void *)errors
51
44
  );
52
- #endif
53
45
 
54
- xmlSchemaValidateDoc(valid_ctxt, doc);
46
+ int status = xmlSchemaValidateDoc(valid_ctxt, doc);
55
47
 
56
48
  xmlSchemaFreeValidCtxt(valid_ctxt);
57
49
 
50
+ if (status != 0) {
51
+ if (RARRAY_LEN(errors) == 0) {
52
+ rb_ary_push(errors, rb_str_new2("Could not validate document"));
53
+ }
54
+ }
55
+
58
56
  return errors;
59
57
  }
60
58
 
61
- /*
62
- * call-seq:
63
- * validate_file(filename)
64
- *
65
- * Validate a file against this Schema.
66
- */
67
59
  static VALUE
68
- validate_file(VALUE self, VALUE rb_filename)
60
+ noko_xml_schema__validate_file(VALUE self, VALUE rb_filename)
69
61
  {
70
62
  xmlSchemaPtr schema;
71
63
  xmlSchemaValidCtxtPtr valid_ctxt;
@@ -84,33 +76,34 @@ validate_file(VALUE self, VALUE rb_filename)
84
76
  rb_raise(rb_eRuntimeError, "Could not create a validation context");
85
77
  }
86
78
 
87
- #ifdef HAVE_XMLSCHEMASETVALIDSTRUCTUREDERRORS
88
79
  xmlSchemaSetValidStructuredErrors(
89
80
  valid_ctxt,
90
- Nokogiri_error_array_pusher,
81
+ noko__error_array_pusher,
91
82
  (void *)errors
92
83
  );
93
- #endif
94
84
 
95
- xmlSchemaValidateFile(valid_ctxt, filename, 0);
85
+ int status = xmlSchemaValidateFile(valid_ctxt, filename, 0);
96
86
 
97
87
  xmlSchemaFreeValidCtxt(valid_ctxt);
98
88
 
89
+ if (status != 0) {
90
+ if (RARRAY_LEN(errors) == 0) {
91
+ rb_ary_push(errors, rb_str_new2("Could not validate file."));
92
+ }
93
+ }
94
+
99
95
  return errors;
100
96
  }
101
97
 
102
98
  static VALUE
103
99
  xml_schema_parse_schema(
104
- VALUE klass,
100
+ VALUE rb_class,
105
101
  xmlSchemaParserCtxtPtr c_parser_context,
106
102
  VALUE rb_parse_options
107
103
  )
108
104
  {
109
- VALUE rb_errors;
110
- int parse_options_int;
111
- xmlSchemaPtr c_schema;
112
- xmlExternalEntityLoader old_loader = 0;
113
- VALUE rb_schema;
105
+ xmlExternalEntityLoader saved_loader = 0;
106
+ libxmlStructuredErrorHandlerState handler_state;
114
107
 
115
108
  if (NIL_P(rb_parse_options)) {
116
109
  rb_parse_options = rb_const_get_at(
@@ -118,45 +111,41 @@ xml_schema_parse_schema(
118
111
  rb_intern("DEFAULT_SCHEMA")
119
112
  );
120
113
  }
114
+ int c_parse_options = (int)NUM2INT(rb_funcall(rb_parse_options, rb_intern("to_i"), 0));
121
115
 
122
- rb_errors = rb_ary_new();
123
- xmlSetStructuredErrorFunc((void *)rb_errors, Nokogiri_error_array_pusher);
116
+ VALUE rb_errors = rb_ary_new();
117
+ noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher);
124
118
 
125
- #ifdef HAVE_XMLSCHEMASETPARSERSTRUCTUREDERRORS
126
119
  xmlSchemaSetParserStructuredErrors(
127
120
  c_parser_context,
128
- Nokogiri_error_array_pusher,
121
+ noko__error_array_pusher,
129
122
  (void *)rb_errors
130
123
  );
131
- #endif
132
124
 
133
- parse_options_int = (int)NUM2INT(rb_funcall(rb_parse_options, rb_intern("to_i"), 0));
134
- if (parse_options_int & XML_PARSE_NONET) {
135
- old_loader = xmlGetExternalEntityLoader();
125
+ if (c_parse_options & XML_PARSE_NONET) {
126
+ saved_loader = xmlGetExternalEntityLoader();
136
127
  xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
137
128
  }
138
129
 
139
- c_schema = xmlSchemaParse(c_parser_context);
130
+ xmlSchemaPtr c_schema = xmlSchemaParse(c_parser_context);
140
131
 
141
- if (old_loader) {
142
- xmlSetExternalEntityLoader(old_loader);
132
+ if (saved_loader) {
133
+ xmlSetExternalEntityLoader(saved_loader);
143
134
  }
144
135
 
145
- xmlSetStructuredErrorFunc(NULL, NULL);
146
136
  xmlSchemaFreeParserCtxt(c_parser_context);
137
+ noko__structured_error_func_restore(&handler_state);
147
138
 
148
139
  if (NULL == c_schema) {
149
- xmlErrorConstPtr error = xmlGetLastError();
150
- if (error) {
151
- Nokogiri_error_raise(NULL, error);
140
+ VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors);
141
+ if (RB_TEST(exception)) {
142
+ rb_exc_raise(exception);
152
143
  } else {
153
144
  rb_raise(rb_eRuntimeError, "Could not parse document");
154
145
  }
155
-
156
- return Qnil;
157
146
  }
158
147
 
159
- rb_schema = TypedData_Wrap_Struct(klass, &xml_schema_type, c_schema);
148
+ VALUE rb_schema = TypedData_Wrap_Struct(rb_class, &xml_schema_type, c_schema);
160
149
  rb_iv_set(rb_schema, "@errors", rb_errors);
161
150
  rb_iv_set(rb_schema, "@parse_options", rb_parse_options);
162
151
 
@@ -164,47 +153,24 @@ xml_schema_parse_schema(
164
153
  }
165
154
 
166
155
  /*
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
176
- */
177
- static VALUE
178
- read_memory(int argc, VALUE *argv, VALUE klass)
179
- {
180
- VALUE rb_content;
181
- VALUE rb_parse_options;
182
- xmlSchemaParserCtxtPtr c_parser_context;
183
-
184
- rb_scan_args(argc, argv, "11", &rb_content, &rb_parse_options);
185
-
186
- c_parser_context = xmlSchemaNewMemParserCtxt(
187
- (const char *)StringValuePtr(rb_content),
188
- (int)RSTRING_LEN(rb_content)
189
- );
190
-
191
- return xml_schema_parse_schema(klass, c_parser_context, rb_parse_options);
192
- }
193
-
194
- /*
195
- * call-seq:
196
- * from_document(document) → Nokogiri::XML::Schema
156
+ * :call-seq:
157
+ * from_document(input) → Nokogiri::XML::Schema
158
+ * from_document(input, parse_options) → Nokogiri::XML::Schema
197
159
  *
198
- * Create a new schema parsed from the +document+.
160
+ * Parse an \XSD schema definition from a Document to create a new Nokogiri::XML::Schema
199
161
  *
200
162
  * [Parameters]
201
- * - +document+: Nokogiri::XML::Document to be parsed
163
+ * - +input+ (XML::Document) A document containing the \XSD schema definition
164
+ * - +parse_options+ (Nokogiri::XML::ParseOptions)
165
+ * Defaults to Nokogiri::XML::ParseOptions::DEFAULT_SCHEMA
202
166
  *
203
167
  * [Returns] Nokogiri::XML::Schema
204
168
  */
205
169
  static VALUE
206
- rb_xml_schema_s_from_document(int argc, VALUE *argv, VALUE klass)
170
+ noko_xml_schema_s_from_document(int argc, VALUE *argv, VALUE rb_class)
207
171
  {
172
+ /* TODO: deprecate this method and put file-or-string logic into .new so that becomes the
173
+ * preferred entry point, and this can become a private method */
208
174
  VALUE rb_document;
209
175
  VALUE rb_parse_options;
210
176
  VALUE rb_schema;
@@ -236,7 +202,7 @@ rb_xml_schema_s_from_document(int argc, VALUE *argv, VALUE klass)
236
202
  }
237
203
 
238
204
  c_parser_context = xmlSchemaNewDocParserCtxt(c_document);
239
- rb_schema = xml_schema_parse_schema(klass, c_parser_context, rb_parse_options);
205
+ rb_schema = xml_schema_parse_schema(rb_class, c_parser_context, rb_parse_options);
240
206
 
241
207
  if (defensive_copy_p) {
242
208
  xmlFreeDoc(c_document);
@@ -253,9 +219,8 @@ noko_init_xml_schema(void)
253
219
 
254
220
  rb_undef_alloc_func(cNokogiriXmlSchema);
255
221
 
256
- rb_define_singleton_method(cNokogiriXmlSchema, "read_memory", read_memory, -1);
257
- rb_define_singleton_method(cNokogiriXmlSchema, "from_document", rb_xml_schema_s_from_document, -1);
222
+ rb_define_singleton_method(cNokogiriXmlSchema, "from_document", noko_xml_schema_s_from_document, -1);
258
223
 
259
- rb_define_private_method(cNokogiriXmlSchema, "validate_document", validate_document, 1);
260
- rb_define_private_method(cNokogiriXmlSchema, "validate_file", validate_file, 1);
224
+ rb_define_private_method(cNokogiriXmlSchema, "validate_document", noko_xml_schema__validate_document, 1);
225
+ rb_define_private_method(cNokogiriXmlSchema, "validate_file", noko_xml_schema__validate_file, 1);
261
226
  }
@@ -3,7 +3,7 @@
3
3
  VALUE cNokogiriXmlSyntaxError;
4
4
 
5
5
  void
6
- Nokogiri_structured_error_func_save(libxmlStructuredErrorHandlerState *handler_state)
6
+ noko__structured_error_func_save(libxmlStructuredErrorHandlerState *handler_state)
7
7
  {
8
8
  /* this method is tightly coupled to the implementation of xmlSetStructuredErrorFunc */
9
9
  handler_state->user_data = xmlStructuredErrorContext;
@@ -11,37 +11,40 @@ Nokogiri_structured_error_func_save(libxmlStructuredErrorHandlerState *handler_s
11
11
  }
12
12
 
13
13
  void
14
- Nokogiri_structured_error_func_save_and_set(libxmlStructuredErrorHandlerState *handler_state,
15
- void *user_data,
16
- xmlStructuredErrorFunc handler)
14
+ noko__structured_error_func_save_and_set(
15
+ libxmlStructuredErrorHandlerState *handler_state,
16
+ void *user_data,
17
+ xmlStructuredErrorFunc handler
18
+ )
17
19
  {
18
- Nokogiri_structured_error_func_save(handler_state);
20
+ noko__structured_error_func_save(handler_state);
19
21
  xmlSetStructuredErrorFunc(user_data, handler);
20
22
  }
21
23
 
22
24
  void
23
- Nokogiri_structured_error_func_restore(libxmlStructuredErrorHandlerState *handler_state)
25
+ noko__structured_error_func_restore(libxmlStructuredErrorHandlerState *handler_state)
24
26
  {
25
27
  xmlSetStructuredErrorFunc(handler_state->user_data, handler_state->handler);
26
28
  }
27
29
 
28
30
  void
29
- Nokogiri_error_array_pusher(void *ctx, xmlErrorConstPtr error)
31
+ noko__error_array_pusher(void *ctx, xmlErrorConstPtr error)
30
32
  {
31
33
  VALUE list = (VALUE)ctx;
32
34
  Check_Type(list, T_ARRAY);
33
- rb_ary_push(list, Nokogiri_wrap_xml_syntax_error(error));
35
+ rb_ary_push(list, noko_xml_syntax_error__wrap(error));
34
36
  }
35
37
 
36
38
  void
37
- Nokogiri_error_raise(void *ctx, xmlErrorConstPtr error)
39
+ noko__error_raise(void *ctx, xmlErrorConstPtr error)
38
40
  {
39
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
41
+ rb_exc_raise(noko_xml_syntax_error__wrap(error));
40
42
  }
41
43
 
42
44
  VALUE
43
- Nokogiri_wrap_xml_syntax_error(xmlErrorConstPtr error)
45
+ noko_xml_syntax_error__wrap(xmlErrorConstPtr error)
44
46
  {
47
+ xmlChar *c_path ;
45
48
  VALUE msg, e, klass;
46
49
 
47
50
  klass = cNokogiriXmlSyntaxError;
@@ -59,16 +62,21 @@ Nokogiri_wrap_xml_syntax_error(xmlErrorConstPtr error)
59
62
  );
60
63
 
61
64
  if (error) {
65
+ c_path = xmlGetNodePath(error->node);
66
+
62
67
  rb_iv_set(e, "@domain", INT2NUM(error->domain));
63
68
  rb_iv_set(e, "@code", INT2NUM(error->code));
64
69
  rb_iv_set(e, "@level", INT2NUM((short)error->level));
65
70
  rb_iv_set(e, "@file", RBSTR_OR_QNIL(error->file));
66
71
  rb_iv_set(e, "@line", INT2NUM(error->line));
72
+ rb_iv_set(e, "@path", RBSTR_OR_QNIL(c_path));
67
73
  rb_iv_set(e, "@str1", RBSTR_OR_QNIL(error->str1));
68
74
  rb_iv_set(e, "@str2", RBSTR_OR_QNIL(error->str2));
69
75
  rb_iv_set(e, "@str3", RBSTR_OR_QNIL(error->str3));
70
76
  rb_iv_set(e, "@int1", INT2NUM(error->int1));
71
77
  rb_iv_set(e, "@column", INT2NUM(error->int2));
78
+
79
+ xmlFree(c_path);
72
80
  }
73
81
 
74
82
  return e;
@@ -20,6 +20,7 @@ rb_xml_text_s_new(int argc, VALUE *argv, VALUE klass)
20
20
 
21
21
  rb_scan_args(argc, argv, "2*", &rb_string, &rb_document, &rb_rest);
22
22
 
23
+ Check_Type(rb_string, T_STRING);
23
24
  if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlNode)) {
24
25
  rb_raise(rb_eTypeError,
25
26
  "expected second parameter to be a Nokogiri::XML::Document, received %"PRIsVALUE,
@@ -35,11 +36,8 @@ rb_xml_text_s_new(int argc, VALUE *argv, VALUE klass)
35
36
  c_document = noko_xml_document_unwrap(rb_document);
36
37
  }
37
38
 
38
- c_node = xmlNewText((xmlChar *)StringValueCStr(rb_string));
39
- c_node->doc = c_document;
40
-
39
+ c_node = xmlNewDocText(c_document, (xmlChar *)StringValueCStr(rb_string));
41
40
  noko_xml_document_pin_node(c_node);
42
-
43
41
  rb_node = noko_xml_node_wrap(klass, c_node) ;
44
42
  rb_obj_call_init(rb_node, argc, argv);
45
43