[librsvg] bgo#787895 - Use xmlCreateIOParserCtxt() for I/O callbacks instead of a push parser
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] bgo#787895 - Use xmlCreateIOParserCtxt() for I/O callbacks instead of a push parser
- Date: Wed, 4 Oct 2017 00:53:39 +0000 (UTC)
commit dee021ebd02a6b976e416cfdd36c4271018252d5
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Oct 3 19:43:08 2017 -0500
bgo#787895 - Use xmlCreateIOParserCtxt() for I/O callbacks instead of a push parser
We were using libxml2 incorrectly since 2010 (!). We have to use
xmlCreatePushParserCtxt() with xmlParseChunk(), *OR*
xmlCreateIOParserCtxt(io_callbacks) with xmlParseDocument().
https://bugzilla.gnome.org/show_bug.cgi?id=787895
rsvg-base.c | 42 +++++++++++++++++++-----------------------
rsvg-xml.c | 45 +++++++++++++++++++++++++++------------------
rsvg-xml.h | 11 ++++++++---
3 files changed, 54 insertions(+), 44 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index 603bc31..8632c43 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -750,32 +750,26 @@ rsvg_start_xinclude (RsvgHandle * ctx, RsvgPropertyBag * atts)
GInputStream *stream;
GError *err = NULL;
xmlParserCtxtPtr xml_parser;
- xmlParserInputBufferPtr buffer;
- xmlParserInputPtr input;
stream = _rsvg_handle_acquire_stream (ctx, href, NULL, NULL);
if (stream == NULL)
goto fallback;
- xml_parser = create_xml_parser (ctx, NULL);
+ xml_parser = rsvg_create_xml_parser_from_stream (&rsvgSAXHandlerStruct,
+ ctx,
+ stream,
+ NULL, /* cancellable */
+ &err);
+ rsvg_set_xml_parse_options (xml_parser, ctx);
- buffer = _rsvg_xml_input_buffer_new_from_stream (stream, NULL /* cancellable */, &err);
g_object_unref (stream);
- input = xmlNewIOInputStream (xml_parser, buffer /* adopts */, XML_CHAR_ENCODING_NONE);
-
- if (xmlPushInput (xml_parser, input) < 0) {
- g_clear_error (&err);
- xmlFreeInputStream (input);
+ if (xml_parser) {
+ (void) xmlParseDocument (xml_parser);
xml_parser = rsvg_free_xml_parser_and_doc (xml_parser);
- goto fallback;
}
- (void) xmlParseDocument (xml_parser);
-
- xml_parser = rsvg_free_xml_parser_and_doc (xml_parser);
-
g_clear_error (&err);
}
@@ -2036,8 +2030,6 @@ rsvg_handle_read_stream_sync (RsvgHandle *handle,
GError **error)
{
RsvgHandlePrivate *priv;
- xmlParserInputBufferPtr buffer;
- xmlParserInputPtr input;
int result;
GError *err = NULL;
gboolean res = FALSE;
@@ -2085,14 +2077,18 @@ rsvg_handle_read_stream_sync (RsvgHandle *handle,
priv->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
g_assert (handle->priv->ctxt == NULL);
- handle->priv->ctxt = create_xml_parser (handle, rsvg_handle_get_base_uri (handle));
-
- buffer = _rsvg_xml_input_buffer_new_from_stream (stream, cancellable, &err);
- input = xmlNewIOInputStream (priv->ctxt, buffer, XML_CHAR_ENCODING_NONE);
+ handle->priv->ctxt = rsvg_create_xml_parser_from_stream (&rsvgSAXHandlerStruct,
+ handle,
+ stream,
+ cancellable,
+ &err);
+ rsvg_set_xml_parse_options (handle->priv->ctxt, handle);
+
+ if (!handle->priv->ctxt) {
+ if (err) {
+ g_propagate_error (error, err);
+ }
- if (xmlPushInput (priv->ctxt, input) < 0) {
- rsvg_set_error (error, priv->ctxt);
- xmlFreeInputStream (input);
goto out;
}
diff --git a/rsvg-xml.c b/rsvg-xml.c
index 452a0cb..6b1f1de 100644
--- a/rsvg-xml.c
+++ b/rsvg-xml.c
@@ -1,3 +1,5 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 sts=4 expandtab: */
/*
* Copyright © 2010 Christian Persch
*
@@ -19,6 +21,7 @@
#include "config.h"
+#include "rsvg-private.h"
#include "rsvg-xml.h"
typedef struct {
@@ -29,10 +32,11 @@ typedef struct {
/* this should use gsize, but libxml2 is borked */
static int
-context_read (RsvgXmlInputStreamContext *context,
+context_read (void *data,
char *buffer,
int len)
{
+ RsvgXmlInputStreamContext *context = data;
gssize n_read;
if (*(context->error))
@@ -48,8 +52,9 @@ context_read (RsvgXmlInputStreamContext *context,
}
static int
-context_close (RsvgXmlInputStreamContext *context)
+context_close (void *data)
{
+ RsvgXmlInputStreamContext *context = data;
gboolean ret;
/* Don't overwrite a previous error */
@@ -64,20 +69,14 @@ context_close (RsvgXmlInputStreamContext *context)
return ret ? 0 : -1;
}
-/**
- * _rsvg_xml_input_buffer_new_from_stream:
- * @context: a #xmlParserCtxtPtr
- * @input_stream: a #GInputStream
- *
- * Returns: a new #xmlParserInputPtr wrapping @input_stream
- */
-xmlParserInputBufferPtr
-_rsvg_xml_input_buffer_new_from_stream (GInputStream *stream,
- GCancellable *cancellable,
- GError **error)
-
+xmlParserCtxtPtr rsvg_create_xml_parser_from_stream (xmlSAXHandlerPtr sax,
+ void *sax_user_data,
+ GInputStream *stream,
+ GCancellable *cancellable,
+ GError **error)
{
RsvgXmlInputStreamContext *context;
+ xmlParserCtxtPtr parser;
g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
@@ -88,8 +87,18 @@ _rsvg_xml_input_buffer_new_from_stream (GInputStream *stream,
context->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
context->error = error;
- return xmlParserInputBufferCreateIO ((xmlInputReadCallback) context_read,
- (xmlInputCloseCallback) context_close,
- context,
- XML_CHAR_ENCODING_NONE);
+ parser = xmlCreateIOParserCtxt (sax,
+ sax_user_data,
+ context_read,
+ context_close,
+ context,
+ XML_CHAR_ENCODING_NONE);
+
+ if (!parser) {
+ g_set_error (error, rsvg_error_quark (), 0, _("Error creating XML parser"));
+
+ /* on error, xmlCreateIOParserCtxt() frees our context via the context_close function */
+ }
+
+ return parser;
}
diff --git a/rsvg-xml.h b/rsvg-xml.h
index c295f77..2f5039a 100644
--- a/rsvg-xml.h
+++ b/rsvg-xml.h
@@ -1,3 +1,5 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 sts=4 expandtab: */
/*
* Copyright © 2010 Christian Persch
*
@@ -25,9 +27,12 @@
G_BEGIN_DECLS
-xmlParserInputBufferPtr _rsvg_xml_input_buffer_new_from_stream (GInputStream *stream,
- GCancellable *cancellable,
- GError **error);
+G_GNUC_INTERNAL
+xmlParserCtxtPtr rsvg_create_xml_parser_from_stream (xmlSAXHandlerPtr sax,
+ void *sax_user_data,
+ GInputStream *stream,
+ GCancellable *cancellable,
+ GError **error);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]