[librsvg/librsvg-2.44] (#385): Don't crash if there is no rsvg_handle_write() before close()
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/librsvg-2.44] (#385): Don't crash if there is no rsvg_handle_write() before close()
- Date: Tue, 27 Nov 2018 22:36:39 +0000 (UTC)
commit 2e039102235acf95b41506ba634ff134d9112f52
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Nov 27 16:25:33 2018 -0600
(#385): Don't crash if there is no rsvg_handle_write() before close()
rsvg_handle_close() was not checking for all the handle's states in which
it can be called.
Fixes https://gitlab.gnome.org/GNOME/librsvg/issues/385
librsvg/rsvg-handle.c | 29 +++++++++++++++++++++++------
tests/api.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+), 6 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index ecdffdfb..3339d3d3 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -735,21 +735,38 @@ rsvg_handle_close (RsvgHandle *handle, GError **error)
{
RsvgHandlePrivate *priv;
gboolean read_successfully;
- gboolean result;
+ gboolean result = FALSE;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
rsvg_return_val_if_fail (handle, FALSE, error);
priv = handle->priv;
- if (priv->hstate == RSVG_HANDLE_STATE_CLOSED_OK
- || priv->hstate == RSVG_HANDLE_STATE_CLOSED_ERROR) {
+ switch (priv->hstate) {
+ case RSVG_HANDLE_STATE_START:
+ g_set_error (error, RSVG_ERROR, RSVG_ERROR_FAILED, _("no data passed to parser"));
+ priv->hstate = RSVG_HANDLE_STATE_CLOSED_ERROR;
+ result = FALSE;
+ break;
+
+ case RSVG_HANDLE_STATE_LOADING:
+ g_assert (priv->load != NULL);
+ read_successfully = rsvg_load_close (priv->load, error);
+ result = finish_load (handle, read_successfully, error);
+ break;
+
+ case RSVG_HANDLE_STATE_CLOSED_OK:
+ case RSVG_HANDLE_STATE_CLOSED_ERROR:
/* closing is idempotent */
- return TRUE;
+ result = TRUE;
+ break;
+
+ default:
+ g_assert_not_reached ();
}
- read_successfully = rsvg_load_close (priv->load, error);
- result = finish_load (handle, read_successfully, error);
+ g_assert (priv->hstate == RSVG_HANDLE_STATE_CLOSED_OK
+ || priv->hstate == RSVG_HANDLE_STATE_CLOSED_ERROR);
return result;
}
diff --git a/tests/api.c b/tests/api.c
index 9ea3ae97..c6e8daf0 100644
--- a/tests/api.c
+++ b/tests/api.c
@@ -578,6 +578,38 @@ render_cairo_sub (void)
cairo_destroy (cr);
}
+/* https://gitlab.gnome.org/GNOME/librsvg/issues/385 */
+static void
+no_write_before_close (void)
+{
+ RsvgHandle *handle = rsvg_handle_new();
+ GError *error = NULL;
+
+ g_assert (rsvg_handle_close (handle, &error) == FALSE);
+ g_assert_error (error, RSVG_ERROR, RSVG_ERROR_FAILED);
+ g_error_free (error);
+
+ g_object_unref (handle);
+}
+
+static void
+empty_write_close (void)
+{
+ RsvgHandle *handle = rsvg_handle_new();
+ GError *error = NULL;
+ guchar buf = 0;
+
+ g_assert (rsvg_handle_write (handle, &buf, 0, &error) == TRUE);
+ g_assert_no_error (error);
+
+ g_assert (rsvg_handle_close (handle, &error) == FALSE);
+ g_assert_error (error, RSVG_ERROR, RSVG_ERROR_FAILED);
+
+ g_error_free (error);
+
+ g_object_unref (handle);
+}
+
int
main (int argc, char **argv)
{
@@ -607,6 +639,8 @@ main (int argc, char **argv)
g_test_add_func ("/api/detects_cairo_context_in_error", detects_cairo_context_in_error);
g_test_add_func ("/api/can_draw_to_non_image_surface", can_draw_to_non_image_surface);
g_test_add_func ("/api/render_cairo_sub", render_cairo_sub);
+ g_test_add_func ("/api/no_write_before_close", no_write_before_close);
+ g_test_add_func ("/api/empty_write_close", empty_write_close);
return g_test_run ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]