summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-01-06 11:56:46 +0000
committerRobin Watts <robin@ghostscript.com>2012-01-06 13:49:24 +0000
commit8c0b958c8cd04eae8a65803db700240123fd38be (patch)
tree96c330707d07b24c6095b421e5a2ddb0d413348b
parent09f1a3d3d863099c103100ed10c8cec82ea7aed3 (diff)
downloadmupdf-8c0b958c8cd04eae8a65803db700240123fd38be.tar.xz
Various memory leak fixes.
In error cases, ensure we free objects correctly. Thanks to Zeniko for finding the problems (and many of the solutions!)
-rw-r--r--fitz/filt_jbig2d.c2
-rw-r--r--fitz/res_font.c6
-rw-r--r--pdf/pdf_parse.c6
-rw-r--r--pdf/pdf_shade.c4
-rw-r--r--pdf/pdf_stream.c11
-rw-r--r--xps/xps_doc.c1
-rw-r--r--xps/xps_png.c77
7 files changed, 65 insertions, 42 deletions
diff --git a/fitz/filt_jbig2d.c b/fitz/filt_jbig2d.c
index 2d2e2eb9..3afcbcb0 100644
--- a/fitz/filt_jbig2d.c
+++ b/fitz/filt_jbig2d.c
@@ -112,10 +112,12 @@ fz_open_jbig2d(fz_stream *chain, fz_buffer *globals)
if (state->ctx)
jbig2_ctx_free(state->ctx);
}
+ fz_drop_buffer(ctx, globals);
fz_free(ctx, state);
fz_close(chain);
fz_rethrow(ctx);
}
+ fz_drop_buffer(ctx, globals);
return fz_new_stream(ctx, state, read_jbig2d, close_jbig2d);
}
diff --git a/fitz/res_font.c b/fitz/res_font.c
index 38d6fdf1..053b2a04 100644
--- a/fitz/res_font.c
+++ b/fitz/res_font.c
@@ -209,7 +209,10 @@ fz_new_font_from_file(fz_context *ctx, char *path, int index)
fterr = FT_New_Face(ctx->font->ftlib, path, index, &face);
if (fterr)
+ {
+ fz_finalize_freetype(ctx);
fz_throw(ctx, "freetype: cannot load font: %s", ft_error_string(fterr));
+ }
font = fz_new_font(ctx, face->family_name);
font->ft_face = face;
@@ -232,7 +235,10 @@ fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index
fterr = FT_New_Memory_Face(ctx->font->ftlib, data, len, index, &face);
if (fterr)
+ {
+ fz_finalize_freetype(ctx);
fz_throw(ctx, "freetype: cannot load font: %s", ft_error_string(fterr));
+ }
font = fz_new_font(ctx, face->family_name);
font->ft_face = face;
diff --git a/pdf/pdf_parse.c b/pdf/pdf_parse.c
index 4b658d08..b2f4fbf7 100644
--- a/pdf/pdf_parse.c
+++ b/pdf/pdf_parse.c
@@ -42,7 +42,7 @@ pdf_to_utf8(fz_context *ctx, fz_obj *src)
if (srclen >= 2 && srcptr[0] == 254 && srcptr[1] == 255)
{
- for (i = 2; i < srclen; i += 2)
+ for (i = 2; i + 1 < srclen; i += 2)
{
ucs = srcptr[i] << 8 | srcptr[i+1];
dstlen += runelen(ucs);
@@ -50,7 +50,7 @@ pdf_to_utf8(fz_context *ctx, fz_obj *src)
dstptr = dst = fz_malloc(ctx, dstlen + 1);
- for (i = 2; i < srclen; i += 2)
+ for (i = 2; i + 1 < srclen; i += 2)
{
ucs = srcptr[i] << 8 | srcptr[i+1];
dstptr += runetochar(dstptr, &ucs);
@@ -393,8 +393,6 @@ pdf_parse_dict(pdf_xref *xref, fz_stream *file, char *buf, int cap)
fz_throw(ctx, "invalid indirect reference in dict");
default:
- fz_drop_obj(key);
- fz_drop_obj(dict);
fz_throw(ctx, "unknown token in dict");
}
diff --git a/pdf/pdf_shade.c b/pdf/pdf_shade.c
index 0b7bd796..86894dc5 100644
--- a/pdf/pdf_shade.c
+++ b/pdf/pdf_shade.c
@@ -711,8 +711,8 @@ pdf_load_type5_shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict,
first = 0;
}
- free(ref);
- free(buf);
+ fz_free(ctx, ref);
+ fz_free(ctx, buf);
}
/* Type 6 & 7 -- Patch mesh shadings */
diff --git a/pdf/pdf_stream.c b/pdf/pdf_stream.c
index 413eee8f..bf9ccc70 100644
--- a/pdf/pdf_stream.c
+++ b/pdf/pdf_stream.c
@@ -89,17 +89,12 @@ build_filter(fz_stream *chain, pdf_xref * xref, fz_obj * f, fz_obj * p, int num,
else if (!strcmp(s, "JBIG2Decode"))
{
+ fz_buffer *globals = NULL;
fz_obj *obj = fz_dict_gets(p, "JBIG2Globals");
if (obj)
- {
- fz_buffer *globals;
globals = pdf_load_stream(xref, fz_to_num(obj), fz_to_gen(obj));
- /* RJW: "cannot load jbig2 global segments" */
- chain = fz_open_jbig2d(chain, globals);
- fz_drop_buffer(ctx, globals);
- return chain;
- }
- return fz_open_jbig2d(chain, NULL);
+ /* fz_open_jbig2d takes possession of globals */
+ return fz_open_jbig2d(chain, globals);
}
else if (!strcmp(s, "JPXDecode"))
diff --git a/xps/xps_doc.c b/xps/xps_doc.c
index b7bba194..c01b7561 100644
--- a/xps/xps_doc.c
+++ b/xps/xps_doc.c
@@ -159,6 +159,7 @@ xps_free_fixed_documents(xps_document *doc)
{
xps_fixdoc *next = fixdoc->next;
fz_free(doc->ctx, fixdoc->name);
+ fz_free(doc->ctx, fixdoc->outline);
fz_free(doc->ctx, fixdoc);
fixdoc = next;
}
diff --git a/xps/xps_png.c b/xps/xps_png.c
index 4ed9f121..f938c1bc 100644
--- a/xps/xps_png.c
+++ b/xps/xps_png.c
@@ -397,7 +397,7 @@ png_read_image(fz_context *ctx, struct info *info, unsigned char *p, int total)
info->size = passofs[7];
}
- info->samples = fz_malloc(info->ctx, info->size);
+ info->samples = fz_malloc(ctx, info->size);
stm.zalloc = zalloc;
stm.zfree = zfree;
@@ -408,42 +408,63 @@ png_read_image(fz_context *ctx, struct info *info, unsigned char *p, int total)
code = inflateInit(&stm);
if (code != Z_OK)
- fz_throw(info->ctx, "zlib error: %s", stm.msg);
-
- /* Read remaining chunks until IEND */
-
- while (total > 8)
{
- size = getint(p);
-
- if (size + 12 > total)
- fz_throw(info->ctx, "premature end of data in png image");
-
- if (!memcmp(p + 4, "PLTE", 4))
- png_read_plte(info, p + 8, size);
- if (!memcmp(p + 4, "tRNS", 4))
- png_read_trns(info, p + 8, size);
- if (!memcmp(p + 4, "pHYs", 4))
- png_read_phys(info, p + 8, size);
- if (!memcmp(p + 4, "IDAT", 4))
- png_read_idat(info, p + 8, size, &stm);
- if (!memcmp(p + 4, "IEND", 4))
- break;
+ fz_free(ctx, info->samples);
+ fz_throw(ctx, "zlib error: %s", stm.msg);
+ }
- p += size + 12;
- total -= size + 12;
+ fz_try(ctx)
+ {
+ /* Read remaining chunks until IEND */
+ while (total > 8)
+ {
+ size = getint(p);
+
+ if (size + 12 > total)
+ fz_throw(info->ctx, "premature end of data in png image");
+
+ if (!memcmp(p + 4, "PLTE", 4))
+ png_read_plte(info, p + 8, size);
+ if (!memcmp(p + 4, "tRNS", 4))
+ png_read_trns(info, p + 8, size);
+ if (!memcmp(p + 4, "pHYs", 4))
+ png_read_phys(info, p + 8, size);
+ if (!memcmp(p + 4, "IDAT", 4))
+ png_read_idat(info, p + 8, size, &stm);
+ if (!memcmp(p + 4, "IEND", 4))
+ break;
+
+ p += size + 12;
+ total -= size + 12;
+ }
+ }
+ fz_catch(ctx)
+ {
+ inflateEnd(&stm);
+ fz_free(ctx, info->samples);
+ fz_rethrow(ctx);
}
code = inflateEnd(&stm);
if (code != Z_OK)
+ {
+ fz_free(ctx, info->samples);
fz_throw(info->ctx, "zlib error: %s", stm.msg);
+ }
/* Apply prediction filter and deinterlacing */
-
- if (!info->interlace)
- png_predict(info->samples, info->width, info->height, info->n, info->depth);
- else
- png_deinterlace(info, passw, passh, passofs);
+ fz_try(ctx)
+ {
+ if (!info->interlace)
+ png_predict(info->samples, info->width, info->height, info->n, info->depth);
+ else
+ png_deinterlace(info, passw, passh, passofs);
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, info->samples);
+ fz_rethrow(ctx);
+ }
}
static fz_pixmap *