[librsvg: 2/18] Notify the XmlState when libxml2 finds a parsing error
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 2/18] Notify the XmlState when libxml2 finds a parsing error
- Date: Fri, 23 Nov 2018 22:31:39 +0000 (UTC)
commit 48d26793711d630e20074c860b563f7650aac0f5
Author: Federico Mena Quintero <federico gnome org>
Date: Thu Nov 22 16:50:20 2018 -0600
Notify the XmlState when libxml2 finds a parsing error
It will then keep itself in a ContextKind::FatalError state, and no-op
if further XML events come in.
librsvg/rsvg-load.c | 5 ++++-
rsvg_internals/src/lib.rs | 1 +
rsvg_internals/src/xml.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 49 insertions(+), 1 deletion(-)
---
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index 35fea27e..92e7833d 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -58,7 +58,7 @@ extern void rsvg_xml_state_steal_result(RsvgXmlState *xml,
extern void rsvg_xml_state_start_element(RsvgXmlState *xml, RsvgHandle *handle, const char *name,
RsvgPropertyBag atts);
extern void rsvg_xml_state_end_element(RsvgXmlState *xml, RsvgHandle *handle, const char *name);
extern void rsvg_xml_state_characters(RsvgXmlState *xml, const char *unterminated_text, gsize len);
-
+extern void rsvg_xml_state_error(RsvgXmlState *xml, const char *msg);
/* Holds the XML parsing state */
typedef struct {
@@ -435,6 +435,7 @@ sax_get_parameter_entity_cb (void *data, const xmlChar * name)
static void
sax_error_cb (void *data, const char *msg, ...)
{
+ RsvgLoad *load = data;
va_list args;
char *buf;
@@ -442,6 +443,8 @@ sax_error_cb (void *data, const char *msg, ...)
g_vasprintf (&buf, msg, args);
va_end (args);
+ rsvg_xml_state_error (load->xml.rust_state, buf);
+
g_free (buf);
}
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index ffd5dd9a..0bdc2679 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -68,6 +68,7 @@ pub use structure::rsvg_node_svg_get_size;
pub use xml::{
rsvg_xml_state_characters,
rsvg_xml_state_end_element,
+ rsvg_xml_state_error,
rsvg_xml_state_free,
rsvg_xml_state_new,
rsvg_xml_state_start_element,
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index a5cec38a..20ca7c84 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -1,5 +1,6 @@
use encoding::label::encoding_from_whatwg_label;
use encoding::DecoderTrap;
+use glib::translate::*;
use libc;
use std;
use std::mem;
@@ -36,6 +37,9 @@ enum ContextKind {
// Insie <xi::fallback>
XIncludeFallback(XIncludeContext),
+
+ // An XML parsing error was found. We will no-op upon any further XML events.
+ FatalError,
}
#[derive(Clone)]
@@ -110,6 +114,10 @@ impl XmlState {
pub fn start_element(&mut self, handle: *mut RsvgHandle, name: &str, pbag: &PropertyBag) {
let context = self.context.clone();
+ if let ContextKind::FatalError = context.kind {
+ return;
+ }
+
let new_context = match context.kind {
ContextKind::Start => self.element_creation_start_element(handle, name, pbag),
ContextKind::ElementCreation => self.element_creation_start_element(handle, name, pbag),
@@ -118,6 +126,8 @@ impl XmlState {
ContextKind::XIncludeFallback(ref ctx) => {
self.xinclude_fallback_start_element(&ctx, handle, name, pbag)
}
+
+ ContextKind::FatalError => unreachable!(),
};
self.push_context(new_context);
@@ -126,6 +136,10 @@ impl XmlState {
pub fn end_element(&mut self, handle: *mut RsvgHandle, name: &str) {
let context = self.context.clone();
+ if let ContextKind::FatalError = context.kind {
+ return;
+ }
+
assert!(context.element_name == name);
match context.kind {
@@ -134,6 +148,7 @@ impl XmlState {
ContextKind::XInclude(_) => (),
ContextKind::UnsupportedXIncludeChild => (),
ContextKind::XIncludeFallback(_) => (),
+ ContextKind::FatalError => unreachable!(),
}
// We can unwrap since start_element() always adds a context to the stack
@@ -143,15 +158,31 @@ impl XmlState {
pub fn characters(&mut self, text: &str) {
let context = self.context.clone();
+ if let ContextKind::FatalError = context.kind {
+ return;
+ }
+
match context.kind {
ContextKind::Start => panic!("characters: XML handler stack is empty!?"),
ContextKind::ElementCreation => self.element_creation_characters(text),
ContextKind::XInclude(_) => (),
ContextKind::UnsupportedXIncludeChild => (),
ContextKind::XIncludeFallback(ref ctx) => self.xinclude_fallback_characters(&ctx, text),
+ ContextKind::FatalError => unreachable!(),
}
}
+ pub fn error(&mut self, msg: &str) {
+ // FIXME: aggregate the errors and expose them to the public result
+
+ println!("XML error: {}", msg);
+
+ self.push_context(Context {
+ element_name: "".to_string(),
+ kind: ContextKind::FatalError,
+ });
+ }
+
fn element_creation_start_element(
&mut self,
handle: *mut RsvgHandle,
@@ -473,3 +504,16 @@ pub extern "C" fn rsvg_xml_state_characters(
xml.characters(utf8);
}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_xml_state_error(xml: *mut RsvgXmlState, msg: *const libc::c_char) {
+ assert!(!xml.is_null());
+ let xml = &mut *(xml as *mut XmlState);
+
+ assert!(!msg.is_null());
+ // Unlike the functions that take UTF-8 validated strings from
+ // libxml2, I don't trust error messages to be validated.
+ let msg: String = from_glib_none(msg);
+
+ xml.error(&msg);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]