[cairo-commit] 10 commits - boilerplate/cairo-boilerplate.c src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-scaled-font-subsets.c src/cairo-svg-surface.c src/cairo-truetype-subset.c src/cairo-type1-fallback.c test/cairo-test.c
Chris Wilson
ickle at kemper.freedesktop.org
Tue Mar 31 04:16:14 PDT 2009
boilerplate/cairo-boilerplate.c | 16 +++++++++++++---
src/cairo-pdf-surface.c | 27 +++++++++++++++++----------
src/cairo-ps-surface.c | 5 +++++
src/cairo-scaled-font-subsets.c | 6 +++++-
src/cairo-svg-surface.c | 2 ++
src/cairo-truetype-subset.c | 13 +++++++++----
src/cairo-type1-fallback.c | 6 +++---
test/cairo-test.c | 35 +++++++++++++++++++++++++++++++++++
8 files changed, 89 insertions(+), 21 deletions(-)
New commits:
commit e46c1d7fa34b4ba89fc3e0fe6f3042a6fa8c0398
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Mar 31 10:39:46 2009 +0100
[scaled-font-subset] Cleanup after failure to convert to utf16.
Avoid leaking the local hashtable and strings after failing to convert the
string to utf16.
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 1d16e4a..44e850e 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -1025,7 +1025,7 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
if (utf8 && *utf8) {
status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len);
if (unlikely (status))
- return status; /* FIXME */
+ goto CLEANUP_HASH;
}
if (utf16_len == 1) {
commit 180b964aac4e058e6783778d33772f08e13b3669
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Mar 31 10:37:44 2009 +0100
[scaled-font-subset] Propagate error from scaled-font to collection.
Don't attempt to collect the sub_font if it is in error.
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index c802c31..1d16e4a 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -542,6 +542,10 @@ _cairo_sub_font_collect (void *entry, void *closure)
if (collection->status)
return;
+ collection->status = sub_font->scaled_font->status;
+ if (collection->status)
+ return;
+
for (i = 0; i <= sub_font->current_subset; i++) {
collection->subset_id = i;
collection->num_glyphs = 0;
commit 8362c6f726979abc43ad9f7303bd45fcb03f83b3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Mar 31 10:36:08 2009 +0100
[type1] Fixup error path during write_charstrings()
On the common error path we attempted to unlock a mutex that was not
always held, so reorder the error paths appropriately.
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index 2b6768d..1023bbd 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -449,14 +449,14 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
/* four "random" bytes required by encryption algorithm */
status = _cairo_array_append_multiple (&data, zeros, 4);
if (unlikely (status))
- goto fail;
+ break;
status = cairo_type1_font_create_charstring (font, i,
font->scaled_font_subset->glyphs[i],
CAIRO_CHARSTRING_TYPE1,
&data);
if (unlikely (status))
- goto fail;
+ break;
charstring_encrypt (&data);
length = _cairo_array_num_elements (&data);
@@ -474,9 +474,9 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
length);
_cairo_output_stream_printf (encrypted_output, " ND\n");
}
+ _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
fail:
- _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
_cairo_array_fini (&data);
return status;
}
commit 88956cd42e9cc03cb8b4ec730062993eaaf3938d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Mar 31 10:35:24 2009 +0100
[ps] Check for error during stroking.
Add a missing error status check that caused errors during stroke to be
masked.
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index dfdc785..0037905 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -3317,6 +3317,9 @@ _cairo_ps_surface_stroke (void *abstract_surface,
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
return CAIRO_STATUS_SUCCESS;
+ if (unlikely (status))
+ return status;
+
return _cairo_pdf_operators_stroke (&surface->pdf_operators,
path,
style,
commit 043352aa8d1e3aeacf3b877f45e1bc451a676e15
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Mar 31 10:34:41 2009 +0100
[pdf] Prevent leak of pad_image on error path.
Ensure that the local pad_image is destroyed after an error.
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 04be7e9..886dd6b 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1797,7 +1797,7 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
if (unlikely (status))
- goto BAIL;
+ return status;
pad_image = &image->base;
if (cairo_pattern_get_extend (&pattern->base) == CAIRO_EXTEND_PAD) {
@@ -1847,10 +1847,10 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
*origin_x = x;
*origin_y = y;
+BAIL:
if (pad_image != &image->base)
cairo_surface_destroy (pad_image);
-BAIL:
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
return status;
commit b0689f56118dd8ccda6f29901d41cf8f80983aa0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Mar 31 10:27:15 2009 +0100
Check for errors during get_mime_data()
cairo_surface_get_mime_data() may raise an error on the surface, so we
need to check lest it goes unnoticed and we generate a corrupt file.
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 94da4ae..04be7e9 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1728,6 +1728,8 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
&mime_data, &mime_data_length);
+ if (unlikely (source->status))
+ return source->status;
if (mime_data == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 346bb88..dfdc785 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -2138,6 +2138,8 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
&mime_data, &mime_data_length);
+ if (unlikely (source->status))
+ return source->status;
if (mime_data == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index db554a1..7a35fab 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -1025,6 +1025,8 @@ _cairo_surface_base64_encode_png (cairo_surface_t *surface,
cairo_surface_get_mime_data (surface, CAIRO_MIME_TYPE_PNG,
&mime_data, &mime_data_length);
+ if (unlikely (surface->status))
+ return surface->status;
if (mime_data == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
commit 9f63cbb870892253f363ddb7aac908263672c8dc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Mar 30 19:09:13 2009 +0100
[pdf] Free compressed stream after error.
Ensure that the compressed stream is destroyed after encountering an
error.
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 2faa942..94da4ae 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1015,18 +1015,21 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
static cairo_status_t
_cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
{
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_status_t status;
long length;
if (! surface->pdf_stream.active)
return CAIRO_STATUS_SUCCESS;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
- if (unlikely (status))
- return status;
if (surface->pdf_stream.compressed) {
- status = _cairo_output_stream_destroy (surface->output);
+ cairo_status_t status2;
+
+ status2 = _cairo_output_stream_destroy (surface->output);
+ if (likely (status == CAIRO_STATUS_SUCCESS))
+ status = status2;
+
surface->output = surface->pdf_stream.old_output;
_cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output);
surface->pdf_stream.old_output = NULL;
@@ -1051,7 +1054,7 @@ _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
surface->pdf_stream.active = FALSE;
- if (status == CAIRO_STATUS_SUCCESS)
+ if (likely (status == CAIRO_STATUS_SUCCESS))
status = _cairo_output_stream_get_status (surface->output);
return status;
commit ba1a0fa601a817ff489bc5373af57977e41eb99f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Mar 30 19:08:41 2009 +0100
[truetype] Free local names on failure.
Ensure that all local allocations are freed on the error path.
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 31e3971..8d1b597 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -1329,8 +1329,8 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font,
tt_name_record_t *record;
unsigned long size;
int i, j;
- char *ps_name;
- char *font_name;
+ char *ps_name = NULL;
+ char *font_name = NULL;
backend = scaled_font->backend;
if (!backend->load_truetype_table)
@@ -1360,8 +1360,6 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font,
* name. It should be extended to use any suitable font name in
* the name table.
*/
- ps_name = NULL;
- font_name = NULL;
for (i = 0; i < be16_to_cpu(name->num_records); i++) {
record = &(name->records[i]);
if ((be16_to_cpu (record->platform) == 1) &&
@@ -1415,6 +1413,13 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font,
fail:
free (name);
+
+ if (ps_name != NULL)
+ free (ps_name);
+
+ if (font_name != NULL)
+ free (font_name);
+
*ps_name_out = NULL;
*font_name_out = NULL;
commit edce97a750acf4368bd7249ec6b9a195f8584cdf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Mar 30 16:50:51 2009 +0100
[pdf] Remove false assertion.
The stream itself may be in an error state, so an error could be raised.
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index f562e3f..2faa942 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1324,10 +1324,12 @@ _cairo_pdf_surface_finish (void *abstract_surface)
"%%%%EOF\n",
offset);
- status2 = _cairo_pdf_operators_fini (&surface->pdf_operators);
/* pdf_operators has already been flushed when the last stream was
- * closed so we should never be writing anything here. */
- assert(status2 == CAIRO_STATUS_SUCCESS);
+ * closed so we should never be writing anything here - however,
+ * the stream may itself be in an error state. */
+ status2 = _cairo_pdf_operators_fini (&surface->pdf_operators);
+ if (status == CAIRO_STATUS_SUCCESS)
+ status = status2;
/* close any active streams still open due to fatal errors */
status2 = _cairo_pdf_surface_close_stream (surface);
commit b580a4a8d6c056ba8b47be32ea8c5b9a1d90d01e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Mar 30 16:50:10 2009 +0100
[test] Improve fault injection coverage
In order to exercise the meta-surfaces, we need to inject faults into
cairo_surface_finish().
diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index b6c2c80..fcc05b8 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -76,6 +76,7 @@
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
+#include <errno.h>
#if HAVE_UNISTD_H && HAVE_FCNTL_H && HAVE_SIGNAL_H && HAVE_SYS_STAT_H && HAVE_SYS_SOCKET_H && HAVE_SYS_UN_H
#include <unistd.h>
@@ -170,6 +171,9 @@ _cairo_boilerplate_get_image_surface (cairo_surface_t *src,
cairo_surface_t *surface;
cairo_t *cr;
+ if (cairo_surface_status (src))
+ return cairo_surface_reference (src);
+
#if 0
if (cairo_surface_get_type (src) == CAIRO_SURFACE_TYPE_IMAGE) {
int ww = cairo_image_surface_get_width (src);
@@ -973,7 +977,7 @@ cairo_boilerplate_image_surface_create_from_ppm_stream (FILE *file)
goto FAIL;
}
if (cairo_surface_status (image))
- goto FAIL;
+ return image;
data = cairo_image_surface_get_data (image);
stride = cairo_image_surface_get_stride (image);
@@ -1017,8 +1021,14 @@ cairo_boilerplate_convert_to_image (const char *filename, int page)
RETRY:
file = cairo_boilerplate_open_any2ppm (filename, page, flags);
- if (file == NULL)
- return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR);
+ if (file == NULL) {
+ switch (errno) {
+ case ENOMEM:
+ return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
+ default:
+ return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR);
+ }
+ }
image = cairo_boilerplate_image_surface_create_from_ppm_stream (file);
ret = pclose (file);
diff --git a/test/cairo-test.c b/test/cairo-test.c
index 264fed5..568d8f8 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -910,7 +910,42 @@ REPEAT:
cairo_status_t diff_status;
if (target->finish_surface != NULL) {
+#if HAVE_MEMFAULT
+ /* We need to re-enable faults as most meta-surface processing
+ * is done during cairo_surface_finish().
+ */
+ VALGRIND_CLEAR_FAULTS ();
+ last_fault_count = VALGRIND_COUNT_FAULTS ();
+ VALGRIND_ENABLE_FAULTS ();
+#endif
+
diff_status = target->finish_surface (surface);
+
+#if HAVE_MEMFAULT
+ VALGRIND_DISABLE_FAULTS ();
+
+ if (ctx->malloc_failure &&
+ VALGRIND_COUNT_FAULTS () - last_fault_count > 0 &&
+ diff_status == CAIRO_STATUS_NO_MEMORY)
+ {
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+ if (target->cleanup)
+ target->cleanup (closure);
+ if (ctx->thread == 0) {
+ cairo_debug_reset_static_data ();
+#if HAVE_FCFINI
+ FcFini ();
+#endif
+ if (VALGRIND_COUNT_LEAKS () > 0) {
+ VALGRIND_PRINT_FAULTS ();
+ VALGRIND_PRINT_LEAKS ();
+ }
+ }
+
+ goto REPEAT;
+ }
+#endif
if (diff_status) {
cairo_test_log (ctx, "Error: Failed to finish surface: %s\n",
cairo_status_to_string (diff_status));
More information about the cairo-commit
mailing list