[librsvg] Add permission check before loading other files
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] Add permission check before loading other files
- Date: Thu, 26 Jan 2012 20:19:06 +0000 (UTC)
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]