66 lines
1.9 KiB
Diff
66 lines
1.9 KiB
Diff
|
|
From 74abb4f2e73bb61b17d9f1a0ad717c881943b877 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Aaron Patterson <aaron.patterson@gmail.com>
|
||
|
|
Date: Wed, 26 Feb 2020 13:51:43 -0800
|
||
|
|
Subject: [PATCH] Work around a bug in libxml2
|
||
|
|
|
||
|
|
This commit works around a bug in libxml2 where parsing schemas can
|
||
|
|
result in dangling pointers which can lead to a segv.
|
||
|
|
|
||
|
|
Upstream bug is here: https://gitlab.gnome.org/GNOME/libxml2/issues/148
|
||
|
|
|
||
|
|
Fixes #1985
|
||
|
|
---
|
||
|
|
ext/nokogiri/xml_schema.c | 29 +++++++++++++++++++++++++++++
|
||
|
|
1 file changed, 29 insertions(+)
|
||
|
|
|
||
|
|
diff --git a/ext/nokogiri/xml_schema.c b/ext/nokogiri/xml_schema.c
|
||
|
|
index da2774b..439f721 100644
|
||
|
|
--- a/ext/nokogiri/xml_schema.c
|
||
|
|
+++ b/ext/nokogiri/xml_schema.c
|
||
|
|
@@ -133,6 +133,31 @@ static VALUE read_memory(VALUE klass, VALUE content)
|
||
|
|
return rb_schema;
|
||
|
|
}
|
||
|
|
|
||
|
|
+/* Schema creation will remove and deallocate "blank" nodes.
|
||
|
|
+ * If those blank nodes have been exposed to Ruby, they could get freed
|
||
|
|
+ * out from under the VALUE pointer. This function checks to see if any of
|
||
|
|
+ * those nodes have been exposed to Ruby, and if so we should raise an exception.
|
||
|
|
+ */
|
||
|
|
+static int has_blank_nodes_p(VALUE cache)
|
||
|
|
+{
|
||
|
|
+ long i;
|
||
|
|
+
|
||
|
|
+ if (NIL_P(cache)) {
|
||
|
|
+ return 0;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ for (i = 0; i < RARRAY_LEN(cache); i++) {
|
||
|
|
+ xmlNodePtr node;
|
||
|
|
+ VALUE element = rb_ary_entry(cache, i);
|
||
|
|
+ Data_Get_Struct(element, xmlNode, node);
|
||
|
|
+ if (xmlIsBlankNode(node)) {
|
||
|
|
+ return 1;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
/*
|
||
|
|
* call-seq:
|
||
|
|
* from_document(doc)
|
||
|
|
@@ -152,6 +177,10 @@ static VALUE from_document(VALUE klass, VALUE document)
|
||
|
|
/* In case someone passes us a node. ugh. */
|
||
|
|
doc = doc->doc;
|
||
|
|
|
||
|
|
+ if (has_blank_nodes_p(DOC_NODE_CACHE(doc))) {
|
||
|
|
+ rb_raise(rb_eArgError, "Creating a schema from a document that has blank nodes exposed to Ruby is dangerous");
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
ctx = xmlSchemaNewDocParserCtxt(doc);
|
||
|
|
|
||
|
|
errors = rb_ary_new();
|
||
|
|
--
|
||
|
|
2.23.0
|
||
|
|
|