Crash in cairo_surface_get_mime_data()

Uli Schlachter <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
Hi,

attached is a test case which crashes on every cairo version since 1.10. First
it sets some mime data, then it removes that mime data again. The next
cairo_surface_get_mime_data() then dereferences a NULL pointer.

Also attached is a patch which fixes the issue for me.

I wonder if this really is a cairo bug or if I'm just using the API in a wrong
way. Could someone enlighten me?

Then I also wonder how this should be added to the test suite. The only thing
that currently calls cairo_surface_get_mime_data() is api-special-cases, but
this problem doesn't really fit into that test. Should this get its own test
case, looking something like the code below?

Cheers,
Uli

    const char *mimetype = "text/x-uri";
    const char *data = "http://www.cairographics.org";
    const unsigned char *data_ret;
    unsigned long length;
    cairo_status_t status;

    status = cairo_surface_set_mime_data (surface,
                                          mimetype,
                                          (const unsigned char *) data,
					  strlen (data),
                                          NULL, NULL);
    if (status)
	return CAIRO_TEST_ERROR;

    cairo_surface_get_mime_data (surface, mimetype, &data_ret, &length);
    if ((char *) data_ret != data || length != strlen (data))
	return CAIRO_TEST_ERROR;

    // Now check if unsetting mime data works
    status = cairo_surface_set_mime_data (surface,
                                          mimetype,
					  NULL, 0,
                                          NULL, NULL);
    if (status)
	return CAIRO_TEST_ERROR;

    cairo_surface_get_mime_data (surface, mimetype, &data_ret, &length);
    if (data_ret != NULL || length != 0)
	return CAIRO_TEST_ERROR;

    return CAIRO_TEST_SUCCESS;

-- 
- He made himself, me nothing, you nothing out of the dust
- Er machte sich mir nichts, dir nichts aus dem Staub

--
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
t.c (text/x-csrc, 482 B)
#include <stdio.h>
#include <cairo.h>

#define TYPE "foo"
int main()
{
  const unsigned char *data = "foo";
  size_t data_len = 3;
  const unsigned char *foo;
  unsigned long len;

  cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);
  cairo_surface_set_mime_data (surface, TYPE, data, data_len, NULL, NULL);
  cairo_surface_set_mime_data (surface, TYPE, NULL, 0, NULL, NULL);
  cairo_surface_get_mime_data (surface, TYPE, &foo, &len);

  return 0;
}
patch (text/plain, 588 B)
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 8488380..3be6d42 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1035,7 +1035,7 @@ cairo_surface_get_mime_data (cairo_surface_t		*surface,
     num_slots = surface->mime_data.num_elements;
     slots = _cairo_array_index (&surface->mime_data, 0);
     for (i = 0; i < num_slots; i++) {
-	if (strcmp ((char *) slots[i].key, mime_type) == 0) {
+	if (slots[i].key != NULL && strcmp ((char *) slots[i].key, mime_type) == 0) {
 	    cairo_mime_data_t *mime_data = slots[i].user_data;
 
 	    *data = mime_data->data;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.