[librsvg] Add permission check before loading other files



commit a2e869cb700c13804056820fd4afa215e551b9c5
Author: Christian Persch <chpe gnome org>
Date:   Thu Jan 26 21:17:31 2012 +0100

    Add permission check before loading other files
    
    Wrap _rsvg_io_acquire_* in _rsvg_handle_acquire_* that first
    checks whether the load should be allowed. For the moment, always allow
    the load; more restricted policies will be introduced in a follow-up commit.

 rsvg-base.c    |   69 +++++++++++++++++++++++++++++++++++++++++--------------
 rsvg-defs.c    |   16 ++++---------
 rsvg-defs.h    |    6 ++--
 rsvg-filter.c  |    4 +-
 rsvg-gobject.c |    3 +-
 rsvg-image.c   |   10 ++++----
 rsvg-image.h   |    2 +-
 rsvg-io.h      |    2 -
 rsvg-private.h |   19 +++++++++++++++
 rsvg-styles.c  |    9 +++----
 10 files changed, 92 insertions(+), 48 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index d73bb4e..cf837f9 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -541,7 +541,7 @@ rsvg_start_xinclude (RsvgHandle * ctx, RsvgPropertyBag * atts)
         gsize data_len;
         const char *encoding;
 
-        data = _rsvg_io_acquire_data (href, rsvg_handle_get_base_uri (ctx), &data_len, NULL);
+        data = _rsvg_handle_acquire_data (ctx, href, &data_len, NULL);
         if (data == NULL)
             goto fallback;
 
@@ -571,7 +571,7 @@ rsvg_start_xinclude (RsvgHandle * ctx, RsvgPropertyBag * atts)
         xmlParserInputPtr input;
         int result;
 
-        stream = _rsvg_io_acquire_stream (href, rsvg_handle_get_base_uri (ctx), NULL);
+        stream = _rsvg_handle_acquire_stream (ctx, href, NULL);
         if (stream == NULL)
             goto fallback;
 
@@ -808,15 +808,15 @@ rsvg_entity_decl (void *data, const xmlChar * name, int type,
         gsize entity_data_len;
 
         if (systemId)
-            entity_data = _rsvg_io_acquire_data ((const char *) systemId,
-                                                 rsvg_handle_get_base_uri (ctx),
-                                                 &entity_data_len,
-                                                 NULL);
+            entity_data = _rsvg_handle_acquire_data (ctx,
+                                                     (const char *) systemId,
+                                                     &entity_data_len,
+                                                     NULL);
         else if (publicId)
-            entity_data = _rsvg_io_acquire_data ((const char *) publicId,
-                                                 rsvg_handle_get_base_uri (ctx),
-                                                 &entity_data_len,
-                                                 NULL);
+            entity_data = _rsvg_handle_acquire_data (ctx,
+                                                     (const char *) publicId,
+                                                     &entity_data_len,
+                                                     NULL);
         if (entity_data) {
             content = xmlCharStrndup (entity_data, entity_data_len);
             g_free (entity_data);
@@ -888,10 +888,10 @@ rsvg_processing_instruction (void *ctx, const xmlChar * target, const xmlChar *
                         guint8 *style_data;
                         gsize style_data_len;
 
-                        style_data = _rsvg_io_acquire_data (value,
-                                                            rsvg_handle_get_base_uri (handle),
-                                                            &style_data_len,
-                                                            NULL);
+                        style_data = _rsvg_handle_acquire_data (handle,
+                                                                value,
+                                                                &style_data_len,
+                                                                NULL);
                         if (style_data) {
                             rsvg_parse_cssbuffer (handle, (char *) style_data, style_data_len);
                             g_free (style_data);
@@ -1009,7 +1009,6 @@ rsvg_handle_set_base_uri (RsvgHandle * handle, const char *base_uri)
         if (handle->priv->base_uri)
             g_free (handle->priv->base_uri);
         handle->priv->base_uri = uri;
-        rsvg_defs_set_base_uri (handle->priv->defs, handle->priv->base_uri);
     }
 }
 
@@ -1039,11 +1038,9 @@ rsvg_handle_set_base_gfile (RsvgHandle *handle,
     if (priv->base_gfile)
         g_object_unref (priv->base_gfile);
     priv->base_gfile = base_file;
-    
+
     g_free (priv->base_uri);
     priv->base_uri = g_file_get_uri (base_file);
-
-    rsvg_defs_set_base_uri (priv->defs, priv->base_uri);
 }
 
 /**
@@ -2129,3 +2126,39 @@ rsvg_return_if_fail_warning (const char *pretty_function, const char *expression
 {
     g_set_error (error, RSVG_ERROR, 0, _("%s: assertion `%s' failed"), pretty_function, expression);
 }
+
+static gboolean
+_rsvg_handle_allow_load (RsvgHandle *handle,
+                         const char *uri,
+                         GError **error)
+{
+    RsvgLoadPolicy policy = handle->priv->load_policy;
+
+    if (policy == RSVG_LOAD_POLICY_ALL_PERMISSIVE)
+        return TRUE;
+
+    return TRUE;
+}
+
+guint8* 
+_rsvg_handle_acquire_data (RsvgHandle *handle,
+                           const char *uri,
+                           gsize *len,
+                           GError **error)
+{
+    if (!_rsvg_handle_allow_load (handle, uri, error))
+        return NULL;
+
+    return _rsvg_io_acquire_data (uri, rsvg_handle_get_base_uri (handle), len, error);
+}
+
+GInputStream *
+_rsvg_handle_acquire_stream (RsvgHandle *handle,
+                             const char *uri,
+                             GError **error)
+{
+    if (!_rsvg_handle_allow_load (handle, uri, error))
+        return NULL;
+
+    return _rsvg_io_acquire_stream (uri, rsvg_handle_get_base_uri (handle), error);
+}
diff --git a/rsvg-defs.c b/rsvg-defs.c
index 0c3df9f..71678d7 100644
--- a/rsvg-defs.c
+++ b/rsvg-defs.c
@@ -36,8 +36,8 @@ struct _RsvgDefs {
     GHashTable *hash;
     GPtrArray *unnamed;
     GHashTable *externs;
-    gchar *base_uri;
     GSList *toresolve;
+    RsvgHandle *ctx;
 };
 
 typedef struct _RsvgResolutionPending RsvgResolutionPending;
@@ -48,7 +48,7 @@ struct _RsvgResolutionPending {
 };
 
 RsvgDefs *
-rsvg_defs_new (void)
+rsvg_defs_new (RsvgHandle *handle)
 {
     RsvgDefs *result = g_new (RsvgDefs, 1);
 
@@ -56,18 +56,12 @@ rsvg_defs_new (void)
     result->externs =
         g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);
     result->unnamed = g_ptr_array_new ();
-    result->base_uri = NULL;
     result->toresolve = NULL;
+    result->ctx = handle; /* no need to take a ref here */
 
     return result;
 }
 
-void
-rsvg_defs_set_base_uri (RsvgDefs * self, gchar * base_uri)
-{
-    self->base_uri = base_uri;
-}
-
 static int
 rsvg_defs_load_extern (const RsvgDefs * defs, const char *name)
 {
@@ -76,9 +70,9 @@ rsvg_defs_load_extern (const RsvgDefs * defs, const char *name)
     guint8 *data;
     gsize data_len;
 
-    filename = rsvg_get_file_path (name, defs->base_uri);
+    filename = rsvg_get_file_path (name, rsvg_handle_get_base_uri (defs->ctx));
 
-    data = _rsvg_io_acquire_data (name, defs->base_uri, &data_len, NULL);
+    data = _rsvg_handle_acquire_data (defs->ctx, name, &data_len, NULL);
 
     if (data) {
         handle = rsvg_handle_new ();
diff --git a/rsvg-defs.h b/rsvg-defs.h
index 9a0fdfa..e7a2e9c 100644
--- a/rsvg-defs.h
+++ b/rsvg-defs.h
@@ -31,10 +31,12 @@
 
 #include <glib.h>
 
+#include "rsvg.h"
+
 G_BEGIN_DECLS 
 
 G_GNUC_INTERNAL
-RsvgDefs    *rsvg_defs_new		(void);
+RsvgDefs    *rsvg_defs_new		(RsvgHandle *handle);
 /* for some reason this one's public... */
 RsvgNode    *rsvg_defs_lookup		(const RsvgDefs * defs, const char *name);
 G_GNUC_INTERNAL
@@ -42,8 +44,6 @@ void	     rsvg_defs_set		(RsvgDefs * defs, const char *name, RsvgNode * val);
 G_GNUC_INTERNAL
 void	     rsvg_defs_free		(RsvgDefs * defs);
 G_GNUC_INTERNAL
-void	     rsvg_defs_set_base_uri	(RsvgDefs * self, gchar * base_uri);
-G_GNUC_INTERNAL
 void	     rsvg_defs_add_resolver	(RsvgDefs * defs, RsvgNode ** tochange, const gchar * name);
 G_GNUC_INTERNAL
 void	     rsvg_defs_resolve_all	(RsvgDefs * defs);
diff --git a/rsvg-filter.c b/rsvg-filter.c
index f16c3d4..53e0f59 100644
--- a/rsvg-filter.c
+++ b/rsvg-filter.c
@@ -3556,8 +3556,8 @@ rsvg_filter_primitive_image_render_ext (RsvgFilterPrimitive * self, RsvgFilterCo
     if (width == 0 || height == 0)
         return NULL;
 
-    img = rsvg_cairo_surface_new_from_href (upself->href->str,
-                                            rsvg_handle_get_base_uri (upself->ctx), 
+    img = rsvg_cairo_surface_new_from_href (upself->ctx,
+                                            upself->href->str,
                                             NULL);
     if (!img)
         return NULL;
diff --git a/rsvg-gobject.c b/rsvg-gobject.c
index 4628e09..3945a5c 100644
--- a/rsvg-gobject.c
+++ b/rsvg-gobject.c
@@ -68,7 +68,8 @@ rsvg_handle_init (RsvgHandle * self)
     self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, RSVG_TYPE_HANDLE, RsvgHandlePrivate);
 
     self->priv->flags = RSVG_HANDLE_FLAGS_NONE;
-    self->priv->defs = rsvg_defs_new ();
+    self->priv->load_policy = RSVG_LOAD_POLICY_DEFAULT;
+    self->priv->defs = rsvg_defs_new (self);
     self->priv->handler_nest = 0;
     self->priv->entities = g_hash_table_new_full (g_str_hash, 
                                                   g_str_equal,
diff --git a/rsvg-image.c b/rsvg-image.c
index 9c4a3f9..2d0f93b 100644
--- a/rsvg-image.c
+++ b/rsvg-image.c
@@ -37,8 +37,8 @@
 #include "rsvg-io.h"
 
 cairo_surface_t *
-rsvg_cairo_surface_new_from_href (const char *href, 
-                                  const char *base_uri, 
+rsvg_cairo_surface_new_from_href (RsvgHandle *handle,
+                                  const char *href,
                                   GError **error)
 {
     guint8 *data;
@@ -48,7 +48,7 @@ rsvg_cairo_surface_new_from_href (const char *href,
     int res;
     cairo_surface_t *surface;
 
-    data = _rsvg_io_acquire_data (href, base_uri, &data_len, error);
+    data = _rsvg_handle_acquire_data (handle, href, &data_len, error);
     if (data == NULL)
         return NULL;
 
@@ -190,8 +190,8 @@ rsvg_node_image_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
         /* path is used by some older adobe illustrator versions */
         if ((value = rsvg_property_bag_lookup (atts, "path"))
             || (value = rsvg_property_bag_lookup (atts, "xlink:href"))) {
-            image->surface = rsvg_cairo_surface_new_from_href (value, 
-                                                               rsvg_handle_get_base_uri (ctx), 
+            image->surface = rsvg_cairo_surface_new_from_href (ctx,
+                                                               value, 
                                                                NULL);
 
             if (!image->surface) {
diff --git a/rsvg-image.h b/rsvg-image.h
index d9c28f8..aa66dac 100644
--- a/rsvg-image.h
+++ b/rsvg-image.h
@@ -54,7 +54,7 @@ void rsvg_preserve_aspect_ratio (unsigned int aspect_ratio, double width,
 G_GNUC_INTERNAL
 gchar *rsvg_get_file_path (const gchar * filename, const gchar * basedir);
 G_GNUC_INTERNAL
-cairo_surface_t *rsvg_cairo_surface_new_from_href (const char *href, const char *base_uri, GError ** error);
+cairo_surface_t *rsvg_cairo_surface_new_from_href (RsvgHandle *handle, const char *href, GError ** error);
 
 G_END_DECLS
 
diff --git a/rsvg-io.h b/rsvg-io.h
index da99791..be3db8c 100644
--- a/rsvg-io.h
+++ b/rsvg-io.h
@@ -26,13 +26,11 @@
 #include <glib.h>
 #include <gio/gio.h>
 
-G_GNUC_INTERNAL
 guint8* _rsvg_io_acquire_data (const char *uri,
                                const char *base_uri,
                                gsize *len,
                                GError **error);
 
-G_GNUC_INTERNAL
 GInputStream *_rsvg_io_acquire_stream (const char *uri,
                                        const char *base_uri,
                                        GError **error);
diff --git a/rsvg-private.h b/rsvg-private.h
index 142e732..b79e871 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -122,9 +122,17 @@ struct RsvgSaxHandler {
     void (*characters) (RsvgSaxHandler * self, const char *ch, int len);
 };
 
+typedef enum {
+    RSVG_LOAD_POLICY_ALL_PERMISSIVE
+} RsvgLoadPolicy;
+
+#define RSVG_LOAD_POLICY_DEFAULT (RSVG_LOAD_POLICY_ALL_PERMISSIVE)
+
 struct RsvgHandlePrivate {
     RsvgHandleFlags flags;
 
+    RsvgLoadPolicy load_policy;
+
     gboolean is_disposed;
     gboolean is_closed;
 
@@ -395,6 +403,17 @@ G_GNUC_INTERNAL
 void rsvg_return_if_fail_warning (const char *pretty_function,
                                   const char *expression, GError ** error);
 
+G_GNUC_INTERNAL
+guint8* _rsvg_handle_acquire_data (RsvgHandle *handle,
+                                   const char *uri,
+                                   gsize *len,
+                                   GError **error);
+G_GNUC_INTERNAL
+GInputStream *_rsvg_handle_acquire_stream (RsvgHandle *handle,
+                                           const char *uri,
+                                           GError **error);
+
+
 #define rsvg_return_if_fail(expr, error)    G_STMT_START{			\
      if G_LIKELY(expr) { } else                                     \
        {                                                            \
diff --git a/rsvg-styles.c b/rsvg-styles.c
index eed23e8..60119b0 100644
--- a/rsvg-styles.c
+++ b/rsvg-styles.c
@@ -32,7 +32,6 @@
 #include "rsvg-private.h"
 #include "rsvg-filter.h"
 #include "rsvg-css.h"
-#include "rsvg-io.h"
 #include "rsvg-styles.h"
 #include "rsvg-shapes.h"
 #include "rsvg-mask.h"
@@ -1169,10 +1168,10 @@ ccss_import_style (CRDocHandler * a_this,
     if (a_uri == NULL)
         return;
 
-    stylesheet_data = _rsvg_io_acquire_data ((gchar *) cr_string_peek_raw_str (a_uri),
-                                             rsvg_handle_get_base_uri (user_data->ctx), 
-                                             &stylesheet_data_len,
-                                             NULL);
+    stylesheet_data = _rsvg_handle_acquire_data (user_data->ctx,
+                                                 (gchar *) cr_string_peek_raw_str (a_uri),
+                                                 &stylesheet_data_len,
+                                                 NULL);
     if (stylesheet_data == NULL)
         return;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]