[librsvg] rsvg_handle_acquire_stream(): Move to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] rsvg_handle_acquire_stream(): Move to Rust
- Date: Tue, 27 Nov 2018 00:24:38 +0000 (UTC)
commit 87622ba01abf46aae07139d0574edf101a557728
Author: Federico Mena Quintero <federico gnome org>
Date: Mon Nov 26 17:41:36 2018 -0600
rsvg_handle_acquire_stream(): Move to Rust
This completely moves allow_load() and the realpath() machinery to
Rust. Yay!
librsvg/rsvg-handle.c | 142 +------------------------------------------
librsvg/rsvg-load.c | 2 +-
librsvg/rsvg-private.h | 9 +--
rsvg_internals/src/handle.rs | 40 +++++++++---
rsvg_internals/src/io.rs | 35 +++--------
rsvg_internals/src/lib.rs | 3 +-
6 files changed, 48 insertions(+), 183 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index b10fec49..ec6bbc51 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -1016,7 +1016,7 @@ rsvg_handle_load_extern (RsvgHandle *handle, const char *uri)
RsvgHandle *res = NULL;
GInputStream *stream;
- stream = _rsvg_handle_acquire_stream (handle, uri, NULL);
+ stream = rsvg_handle_acquire_stream (handle, uri, NULL);
if (stream) {
GFile *file = g_file_new_for_uri (uri);
@@ -1578,152 +1578,12 @@ rsvg_handle_resolve_uri (RsvgHandle *handle,
return resolved_uri;
}
-#ifdef G_OS_WIN32
-static char *
-rsvg_realpath_utf8 (const char *filename, const char *unused)
-{
- wchar_t *wfilename;
- wchar_t *wfull;
- char *full;
-
- wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
- if (!wfilename)
- return NULL;
-
- wfull = _wfullpath (NULL, wfilename, 0);
- g_free (wfilename);
- if (!wfull)
- return NULL;
-
- full = g_utf16_to_utf8 (wfull, -1, NULL, NULL, NULL);
- free (wfull);
-
- if (!full)
- return NULL;
-
- return full;
-}
-
-#define realpath(a,b) rsvg_realpath_utf8 (a, b)
-#endif
-
-static gboolean
-allow_load (RsvgHandle *handle, const char *uri, GError **error)
-{
- GFile *base_gfile;
- GFile *base;
- char *path, *dir;
- char *scheme = NULL, *cpath = NULL, *cdir = NULL;
-
- g_assert (error == NULL || *error == NULL);
-
- base_gfile = rsvg_handle_rust_get_base_gfile (handle->priv->rust_handle);
-
- scheme = g_uri_parse_scheme (uri);
-
- /* Not a valid URI */
- if (scheme == NULL)
- goto deny;
-
- /* Allow loads of data: from any location */
- if (g_str_equal (scheme, "data"))
- goto allow;
-
- /* No base to compare to? */
- if (base_gfile == NULL)
- goto deny;
-
- /* Deny loads from differing URI schemes */
- if (!g_file_has_uri_scheme (base_gfile, scheme))
- goto deny;
-
- /* resource: is allowed to load anything from other resources */
- if (g_str_equal (scheme, "resource"))
- goto allow;
-
- /* Non-file: isn't allowed to load anything */
- if (!g_str_equal (scheme, "file"))
- goto deny;
-
- base = g_file_get_parent (base_gfile);
- if (base == NULL)
- goto deny;
-
- dir = g_file_get_path (base);
- g_object_unref (base);
-
- cdir = realpath (dir, NULL);
- g_free (dir);
- if (cdir == NULL)
- goto deny;
-
- path = g_filename_from_uri (uri, NULL, NULL);
- if (path == NULL)
- goto deny;
-
- cpath = realpath (path, NULL);
- g_free (path);
-
- if (cpath == NULL)
- goto deny;
-
- /* Now check that @cpath is below @cdir */
- if (!g_str_has_prefix (cpath, cdir) ||
- cpath[strlen (cdir)] != G_DIR_SEPARATOR)
- goto deny;
-
- /* Allow load! */
-
- allow:
- g_object_unref (base_gfile);
- g_free (scheme);
- free (cpath);
- free (cdir);
- return TRUE;
-
- deny:
- g_object_unref (base_gfile);
- g_free (scheme);
- free (cpath);
- free (cdir);
-
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
- "File may not link to URI \"%s\"", uri);
- return FALSE;
-}
-
GCancellable *
rsvg_handle_get_cancellable (RsvgHandle *handle)
{
return handle->priv->cancellable;
}
-/* Implemented in rsvg_internals/src/io.rs */
-G_GNUC_INTERNAL
-GInputStream *rsvg_io_acquire_stream (const char *uri,
- GCancellable *cancellable,
- GError **error);
-
-GInputStream *
-_rsvg_handle_acquire_stream (RsvgHandle *handle,
- const char *href,
- GError **error)
-{
- char *uri;
- GInputStream *stream;
-
- uri = rsvg_handle_resolve_uri (handle, href);
-
- if (allow_load (handle, uri, error)) {
- stream = rsvg_io_acquire_stream (uri, handle->priv->cancellable, error);
- } else {
- stream = NULL;
- }
-
- g_free (uri);
- return stream;
-}
-
#ifdef HAVE_PANGOFT2
static void
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index 85f057f6..caf5678d 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -276,7 +276,7 @@ rsvg_load_handle_xml_xinclude (RsvgHandle *handle, const char *href)
g_assert (handle->priv->load != NULL);
- stream = _rsvg_handle_acquire_stream (handle, href, NULL);
+ stream = rsvg_handle_acquire_stream (handle, href, NULL);
if (stream) {
gboolean success = FALSE;
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index 11b42403..d612dfcc 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -297,12 +297,13 @@ char *rsvg_handle_acquire_data (RsvgHandle *handle,
G_GNUC_INTERNAL
GCancellable *rsvg_handle_get_cancellable (RsvgHandle *handle);
+/* Implemented in rsvg_internals/src/handle.rs */
G_GNUC_INTERNAL
-GInputStream *_rsvg_handle_acquire_stream (RsvgHandle *handle,
- const char *href,
- GError **error);
+GInputStream *rsvg_handle_acquire_stream (RsvgHandle *handle,
+ const char *href,
+ GError **error);
-#define rsvg_return_if_fail(expr, error) G_STMT_START{ \
+#define rsvg_return_if_fail(expr, error) G_STMT_START{ \
if G_LIKELY(expr) { } else \
{ \
rsvg_return_if_fail_warning (G_STRFUNC, \
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index d26891ef..e3a62c00 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -128,17 +128,13 @@ pub fn acquire_data(handle: *mut RsvgHandle, href: &str) -> Result<BinaryData, g
}
pub fn acquire_stream(handle: *mut RsvgHandle, href: &str) -> Result<InputStream, glib::Error> {
- unsafe {
- let mut error = ptr::null_mut();
+ let rhandle = get_rust_handle(handle);
- let stream = _rsvg_handle_acquire_stream(handle, href.to_glib_none().0, &mut error);
+ let aurl = AllowedUrl::from_href(href, rhandle.base_url.borrow().as_ref())
+ .map_err(|_| glib::Error::new(RsvgError, "FIXME"))?;
- if stream.is_null() {
- Err(from_glib_full(error))
- } else {
- Ok(from_glib_full(stream))
- }
- }
+ io::acquire_stream(&aurl, get_cancellable(handle).as_ref())
+ .map_err(|_| glib::Error::new(RsvgError, "FIXME"))
}
fn keep_image_data(handle: *const RsvgHandle) -> bool {
@@ -333,3 +329,29 @@ pub unsafe extern "C" fn rsvg_handle_acquire_data(
}
}
}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_acquire_stream(
+ handle: *mut RsvgHandle,
+ href: *const libc::c_char,
+ error: *mut *mut glib_sys::GError,
+) -> *mut gio_sys::GInputStream {
+ assert!(!href.is_null());
+
+ let href: String = from_glib_none(href);
+
+ match acquire_stream(handle, &href) {
+ Ok(stream) => {
+ if !error.is_null() {
+ *error = ptr::null_mut();
+ }
+
+ stream.to_glib_full()
+ }
+
+ Err(_) => {
+ set_gerror(error, 0, "Could not acquire stream");
+ ptr::null_mut()
+ }
+ }
+}
diff --git a/rsvg_internals/src/io.rs b/rsvg_internals/src/io.rs
index 4ac24ce1..905a326d 100644
--- a/rsvg_internals/src/io.rs
+++ b/rsvg_internals/src/io.rs
@@ -150,11 +150,13 @@ pub unsafe fn rsvg_get_input_stream_for_loading(
}
}
-/// Returns an input stream. The uri can be a data: URL or a plain URI
-fn acquire_stream(
- uri: &str,
- cancellable: Option<Cancellable>,
+/// Returns an input stream. The url can be a data: URL or a plain URI
+pub fn acquire_stream(
+ aurl: &AllowedUrl,
+ cancellable: Option<&Cancellable>,
) -> Result<InputStream, LoadingError> {
+ let uri = aurl.url().as_str();
+
if uri.starts_with("data:") {
let BinaryData { data, .. } = decode_data_uri(uri)?;
@@ -162,34 +164,13 @@ fn acquire_stream(
Ok(stream.upcast::<InputStream>())
} else {
let file = GFile::new_for_uri(uri);
- let stream = file.read(cancellable.as_ref())?;
+ let stream = file.read(cancellable)?;
Ok(stream.upcast::<InputStream>())
}
}
-#[no_mangle]
-pub unsafe fn rsvg_io_acquire_stream(
- uri: *const libc::c_char,
- cancellable: *mut gio_sys::GCancellable,
- error: *mut *mut glib_sys::GError,
-) -> *mut gio_sys::GInputStream {
- assert!(!uri.is_null());
-
- let uri: String = from_glib_none(uri);
- let cancellable = from_glib_borrow(cancellable);
-
- match acquire_stream(&uri, cancellable) {
- Ok(stream) => stream.to_glib_full(),
-
- Err(_e) => {
- set_gerror(error, 0, "Could not acquire stream");
-
- ptr::null_mut()
- }
- }
-}
-
+/// Returns a chunk of data. The url can be a data: URL or a plain URI
pub fn acquire_data(
aurl: &AllowedUrl,
cancellable: Option<&Cancellable>,
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index d0eafd58..fe5850c0 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -48,6 +48,7 @@ pub use drawing_ctx::{
pub use handle::{
rsvg_handle_acquire_data,
+ rsvg_handle_acquire_stream,
rsvg_handle_load_css,
rsvg_handle_rust_free,
rsvg_handle_rust_get_base_gfile,
@@ -55,7 +56,7 @@ pub use handle::{
rsvg_handle_rust_set_base_url,
};
-pub use io::{rsvg_decode_data_uri, rsvg_get_input_stream_for_loading, rsvg_io_acquire_stream};
+pub use io::{rsvg_decode_data_uri, rsvg_get_input_stream_for_loading};
pub use node::rsvg_node_unref;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]