summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeon Scroggins III <scroggo@google.com>2017-03-13 14:23:58 -0400
committergitbuildkicker <android-build@google.com>2017-03-23 16:07:13 -0700
commit6ad14c63e27268fd9d8d73f7cda086a984dd72b2 (patch)
treeb25a47f3bba6fdde29111b8250e99142b72961ff
parenta57aff106d30e39c782e681f8e4aa3aa612f81c3 (diff)
downloadgiflib-nougat-mr1-volantis-release.tar.gz
Bug:34697653 Also include <limits.h> in openbsd-reallocarray.c, which is where Android defines SIZE_MAX. Preserve Android modification in egif_lib.c, which changed "S_IREAD | S_IWRITE" to "S_IRUSR | S_IWUSR" Change-Id: If19d3f071fd96afa2d37fe08d196c5042856c41b (cherry picked from commit 7eb1d41f601998ea9be3e7c2034b262ff263b862)
-rw-r--r--Android.mk1
-rw-r--r--dgif_lib.c26
-rw-r--r--egif_lib.c4
-rw-r--r--gif_font.c51
-rw-r--r--gif_lib.h5
-rw-r--r--gifalloc.c27
-rw-r--r--openbsd-reallocarray.c39
7 files changed, 112 insertions, 41 deletions
diff --git a/Android.mk b/Android.mk
index 03a9355..437a8f7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -9,6 +9,7 @@ LOCAL_SRC_FILES := \
gifalloc.c \
gif_err.c \
gif_hash.c \
+ openbsd-reallocarray.c \
quantize.c
LOCAL_CFLAGS += -Wno-format -Wno-sign-compare -Wno-unused-parameter -DHAVE_CONFIG_H
diff --git a/dgif_lib.c b/dgif_lib.c
index 320fdb9..66a1d6a 100644
--- a/dgif_lib.c
+++ b/dgif_lib.c
@@ -89,7 +89,7 @@ DGifOpenFileHandle(int FileHandle, int *Error)
GifFile->SavedImages = NULL;
GifFile->SColorMap = NULL;
- Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
+ Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
if (Private == NULL) {
if (Error != NULL)
*Error = D_GIF_ERR_NOT_ENOUGH_MEM;
@@ -97,6 +97,9 @@ DGifOpenFileHandle(int FileHandle, int *Error)
free((char *)GifFile);
return NULL;
}
+
+ /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
+
#ifdef _WIN32
_setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
#endif /* _WIN32 */
@@ -172,13 +175,14 @@ DGifOpen(void *userData, InputFunc readFunc, int *Error)
GifFile->SavedImages = NULL;
GifFile->SColorMap = NULL;
- Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
+ Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
if (!Private) {
if (Error != NULL)
*Error = D_GIF_ERR_NOT_ENOUGH_MEM;
free((char *)GifFile);
return NULL;
}
+ /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
GifFile->Private = (void *)Private;
Private->FileHandle = 0;
@@ -392,8 +396,8 @@ DGifGetImageDesc(GifFileType *GifFile)
if (GifFile->SavedImages) {
SavedImage* new_saved_images =
- (SavedImage *)realloc(GifFile->SavedImages,
- sizeof(SavedImage) * (GifFile->ImageCount + 1));
+ (SavedImage *)reallocarray(GifFile->SavedImages,
+ (GifFile->ImageCount + 1), sizeof(SavedImage));
if (new_saved_images == NULL) {
GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
return GIF_ERROR;
@@ -763,6 +767,12 @@ DGifSetupDecompress(GifFileType *GifFile)
}
BitsPerPixel = CodeSize;
+ /* this can only happen on a severely malformed GIF */
+ if (BitsPerPixel > 8) {
+ GifFile->Error = D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */
+ return GIF_ERROR; /* Failed to read Code size. */
+ }
+
Private->Buf[0] = 0; /* Input Buffer empty. */
Private->BitsPerPixel = BitsPerPixel;
Private->ClearCode = (1 << BitsPerPixel);
@@ -1098,7 +1108,7 @@ DGifSlurp(GifFileType *GifFile)
if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
return GIF_ERROR;
}
- sp->RasterBits = (unsigned char *)malloc(ImageSize *
+ sp->RasterBits = (unsigned char *)reallocarray(NULL, ImageSize,
sizeof(GifPixelType));
if (sp->RasterBits == NULL) {
@@ -1170,6 +1180,12 @@ DGifSlurp(GifFileType *GifFile)
}
} while (RecordType != TERMINATE_RECORD_TYPE);
+ /* Sanity check for corrupted file */
+ if (GifFile->ImageCount == 0) {
+ GifFile->Error = D_GIF_ERR_NO_IMAG_DSCR;
+ return(GIF_ERROR);
+ }
+
return (GIF_OK);
}
diff --git a/egif_lib.c b/egif_lib.c
index 754d914..3917ec6 100644
--- a/egif_lib.c
+++ b/egif_lib.c
@@ -105,6 +105,7 @@ EGifOpenFileHandle(const int FileHandle, int *Error)
*Error = E_GIF_ERR_NOT_ENOUGH_MEM;
return NULL;
}
+ /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
if ((Private->HashTable = _InitHashTable()) == NULL) {
free(GifFile);
free(Private);
@@ -123,6 +124,7 @@ EGifOpenFileHandle(const int FileHandle, int *Error)
Private->FileHandle = FileHandle;
Private->File = f;
Private->FileState = FILE_STATE_WRITE;
+ Private->gif89 = false;
Private->Write = (OutputFunc) 0; /* No user write routine (MRB) */
GifFile->UserData = (void *)NULL; /* No user write handle (MRB) */
@@ -159,6 +161,8 @@ EGifOpen(void *userData, OutputFunc writeFunc, int *Error)
return NULL;
}
+ memset(Private, '\0', sizeof(GifFilePrivateType));
+
Private->HashTable = _InitHashTable();
if (Private->HashTable == NULL) {
free (GifFile);
diff --git a/gif_font.c b/gif_font.c
index ba47b29..8a02b2d 100644
--- a/gif_font.c
+++ b/gif_font.c
@@ -5,6 +5,7 @@ gif_font.c - utility font handling and simple drawing for the GIF library
****************************************************************************/
#include <string.h>
+#include <stdlib.h>
#include "gif_lib.h"
@@ -209,8 +210,9 @@ GifDrawBoxedText8x8(SavedImage *Image,
const int border,
const int bg, const int fg)
{
- int i, j = 0, LineCount = 0, TextWidth = 0;
+ int j = 0, LineCount = 0, TextWidth = 0;
const char *cp;
+ char *dup;
/* compute size of text to box */
for (cp = legend; *cp; cp++)
@@ -225,28 +227,33 @@ GifDrawBoxedText8x8(SavedImage *Image,
if (j > TextWidth) /* last line might be longer than any previous */
TextWidth = j;
- /* fill the box */
- GifDrawRectangle(Image, x + 1, y + 1,
- border + TextWidth * GIF_FONT_WIDTH + border - 1,
- border + LineCount * GIF_FONT_HEIGHT + border - 1, bg);
-
/* draw the text */
- i = 0;
- cp = strtok((char *)legend, "\r\n");
- do {
- int leadspace = 0;
-
- if (cp[0] == '\t')
- leadspace = (TextWidth - strlen(++cp)) / 2;
-
- GifDrawText8x8(Image, x + border + (leadspace * GIF_FONT_WIDTH),
- y + border + (GIF_FONT_HEIGHT * i++), cp, fg);
- cp = strtok((char *)NULL, "\r\n");
- } while (cp);
-
- /* outline the box */
- GifDrawBox(Image, x, y, border + TextWidth * GIF_FONT_WIDTH + border,
- border + LineCount * GIF_FONT_HEIGHT + border, fg);
+ dup = malloc(strlen(legend)+1);
+ /* FIXME: should return bad status, but that would require API change */
+ if (dup != NULL) {
+ int i = 0;
+ /* fill the box */
+ GifDrawRectangle(Image, x + 1, y + 1,
+ border + TextWidth * GIF_FONT_WIDTH + border - 1,
+ border + LineCount * GIF_FONT_HEIGHT + border - 1, bg);
+ (void)strcpy(dup, (char *)legend);
+ cp = strtok((char *)dup, "\r\n");
+ do {
+ int leadspace = 0;
+
+ if (cp[0] == '\t')
+ leadspace = (TextWidth - strlen(++cp)) / 2;
+
+ GifDrawText8x8(Image, x + border + (leadspace * GIF_FONT_WIDTH),
+ y + border + (GIF_FONT_HEIGHT * i++), cp, fg);
+ cp = strtok((char *)NULL, "\r\n");
+ } while (cp);
+ (void)free((void *)dup);
+
+ /* outline the box */
+ GifDrawBox(Image, x, y, border + TextWidth * GIF_FONT_WIDTH + border,
+ border + LineCount * GIF_FONT_HEIGHT + border, fg);
+ }
}
/* end */
diff --git a/gif_lib.h b/gif_lib.h
index ac0307d..078930c 100644
--- a/gif_lib.h
+++ b/gif_lib.h
@@ -13,7 +13,7 @@ extern "C" {
#define GIFLIB_MAJOR 5
#define GIFLIB_MINOR 1
-#define GIFLIB_RELEASE 1
+#define GIFLIB_RELEASE 4
#define GIF_ERROR 0
#define GIF_OK 1
@@ -244,6 +244,9 @@ extern ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
GifPixelType ColorTransIn2[]);
extern int GifBitSize(int n);
+extern void *
+reallocarray(void *optr, size_t nmemb, size_t size);
+
/******************************************************************************
Support for the in-core structures allocation (slurp mode).
******************************************************************************/
diff --git a/gifalloc.c b/gifalloc.c
index f4118d6..3b51868 100644
--- a/gifalloc.c
+++ b/gifalloc.c
@@ -188,8 +188,8 @@ GifUnionColorMap(const ColorMapObject *ColorIn1,
/* perhaps we can shrink the map? */
if (RoundUpTo < ColorUnion->ColorCount) {
- GifColorType *new_map = (GifColorType *)realloc(Map,
- sizeof(GifColorType) * RoundUpTo);
+ GifColorType *new_map = (GifColorType *)reallocarray(Map,
+ RoundUpTo, sizeof(GifColorType));
if( new_map == NULL ) {
GifFreeMapObject(ColorUnion);
return ((ColorMapObject *) NULL);
@@ -232,9 +232,9 @@ GifAddExtensionBlock(int *ExtensionBlockCount,
if (*ExtensionBlocks == NULL)
*ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock));
else {
- ExtensionBlock* ep_new = (ExtensionBlock *)realloc(*ExtensionBlocks,
- sizeof(ExtensionBlock) *
- (*ExtensionBlockCount + 1));
+ ExtensionBlock* ep_new = (ExtensionBlock *)reallocarray
+ (*ExtensionBlocks, (*ExtensionBlockCount + 1),
+ sizeof(ExtensionBlock));
if( ep_new == NULL )
return (GIF_ERROR);
*ExtensionBlocks = ep_new;
@@ -325,8 +325,8 @@ GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
if (GifFile->SavedImages == NULL)
GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
else
- GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
- sizeof(SavedImage) * (GifFile->ImageCount + 1));
+ GifFile->SavedImages = (SavedImage *)reallocarray(GifFile->SavedImages,
+ (GifFile->ImageCount + 1), sizeof(SavedImage));
if (GifFile->SavedImages == NULL)
return ((SavedImage *)NULL);
@@ -355,9 +355,10 @@ GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
}
/* next, the raster */
- sp->RasterBits = (unsigned char *)malloc(sizeof(GifPixelType) *
- CopyFrom->ImageDesc.Height *
- CopyFrom->ImageDesc.Width);
+ sp->RasterBits = (unsigned char *)reallocarray(NULL,
+ (CopyFrom->ImageDesc.Height *
+ CopyFrom->ImageDesc.Width),
+ sizeof(GifPixelType));
if (sp->RasterBits == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
@@ -368,9 +369,9 @@ GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
/* finally, the extension blocks */
if (sp->ExtensionBlocks != NULL) {
- sp->ExtensionBlocks = (ExtensionBlock *)malloc(
- sizeof(ExtensionBlock) *
- CopyFrom->ExtensionBlockCount);
+ sp->ExtensionBlocks = (ExtensionBlock *)reallocarray(NULL,
+ CopyFrom->ExtensionBlockCount,
+ sizeof(ExtensionBlock));
if (sp->ExtensionBlocks == NULL) {
FreeLastSavedImage(GifFile);
return (SavedImage *)(NULL);
diff --git a/openbsd-reallocarray.c b/openbsd-reallocarray.c
new file mode 100644
index 0000000..41a3326
--- /dev/null
+++ b/openbsd-reallocarray.c
@@ -0,0 +1,39 @@
+/* $OpenBSD: reallocarray.c,v 1.1 2014/05/08 21:43:49 deraadt Exp $ */
+/*
+ * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <limits.h>
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+reallocarray(void *optr, size_t nmemb, size_t size)
+{
+ if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+ nmemb > 0 && SIZE_MAX / nmemb < size) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ return realloc(optr, size * nmemb);
+}