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;