[librsvg] bgo#787895 - Use xmlCreateIOParserCtxt() for I/O callbacks instead of a push parser



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]