diff --git a/coverity.patch b/coverity.patch new file mode 100644 index 0000000..98a4c04 --- /dev/null +++ b/coverity.patch @@ -0,0 +1,260 @@ +diff --git a/configure.ac b/configure.ac +index a274546..f282400 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -138,7 +138,7 @@ AC_REPLACE_FUNCS([strerror]) + AC_CHECK_FUNCS([strtoul mkstemp]) + AC_SEARCH_LIBS([pow], [m], [AC_DEFINE([HAVE_POW], [1], [Define to 1 if you have the `pow' function.])]) + +-AC_CHECK_HEADERS([sys/select.h inttypes.h unistd.h]) ++AC_CHECK_HEADERS([sys/select.h sys/stat.h inttypes.h unistd.h]) + + + dnl +diff --git a/src/gifdiff.c b/src/gifdiff.c +index 790ed31..317c5df 100644 +--- a/src/gifdiff.c ++++ b/src/gifdiff.c +@@ -118,11 +118,10 @@ apply_image(int is_second, Gif_Stream *gfs, int imageno, uint16_t background) + Gif_Colormap *gfcm = gfi->local ? gfi->local : gfs->global; + + /* set up colormap */ +- for (i = 0; i < 256; i++) ++ for (i = 0; i < gfcm->ncol; ++i) ++ map[i] = gfcm->col[i].pixel; ++ for (i = gfcm->ncol; i < 256; ++i) + map[i] = 1; +- if (gfs) +- for (i = 0; i < gfcm->ncol; i++) +- map[i] = gfcm->col[i].pixel; + if (gfi->transparent >= 0 && gfi->transparent < 256) + map[gfi->transparent] = TRANSP; + +@@ -458,7 +457,7 @@ gifread_error(Gif_Stream* gfs, Gif_Image* gfi, + static int same_error_count = 0; + int which_image = Gif_ImageNumber(gfs, gfi); + const char *filename = gfs->landmark; +- if (gfs && which_image < 0) ++ if (which_image < 0) + which_image = gfs->nimages; + + if (gifread_error_count == 0) { +diff --git a/src/giffunc.c b/src/giffunc.c +index 5564326..71d8b74 100644 +--- a/src/giffunc.c ++++ b/src/giffunc.c +@@ -87,8 +87,10 @@ Gif_Colormap * + Gif_NewFullColormap(int count, int capacity) + { + Gif_Colormap *gfcm = Gif_New(Gif_Colormap); +- if (!gfcm || capacity <= 0 || count < 0) ++ if (!gfcm || capacity <= 0 || count < 0) { ++ Gif_Delete(gfcm); + return 0; ++ } + if (count > capacity) + capacity = count; + gfcm->ncol = count; +diff --git a/src/gifread.c b/src/gifread.c +index 363fa24..bcab1e3 100644 +--- a/src/gifread.c ++++ b/src/gifread.c +@@ -548,7 +548,7 @@ Gif_FullUncompressImage(Gif_Stream* gfs, Gif_Image* gfi, + gfc.handler = h; + gfc.errors[0] = gfc.errors[1] = 0; + +- if (gfi && gfc.prefix && gfc.suffix && gfc.length && gfi->compressed) { ++ if (gfc.prefix && gfc.suffix && gfc.length && gfi->compressed) { + make_data_reader(&grr, gfi->compressed, gfi->compressed_len); + ok = uncompress_image(&gfc, gfi, &grr); + } +@@ -802,7 +802,6 @@ read_gif(Gif_Reader *grr, int read_flags, + + gfs = Gif_NewStream(); + gfi = Gif_NewImage(); +- gfs->landmark = landmark; + + gfc.stream = gfs; + gfc.prefix = Gif_NewArray(Gif_Code, GIF_MAX_CODE); +@@ -814,6 +813,7 @@ read_gif(Gif_Reader *grr, int read_flags, + + if (!gfs || !gfi || !gfc.prefix || !gfc.suffix || !gfc.length) + goto done; ++ gfs->landmark = landmark; + + GIF_DEBUG(("\nGIF")); + if (!read_logical_screen_descriptor(gfs, grr)) +diff --git a/src/gifsicle.c b/src/gifsicle.c +index fdb44ed..b4cedbc 100644 +--- a/src/gifsicle.c ++++ b/src/gifsicle.c +@@ -513,8 +513,10 @@ gifread_error(Gif_Stream* gfs, Gif_Image* gfi, + if (last_message[0] == 0) + different_error_count++; + same_error_count++; +- strcpy(last_message, message); +- strcpy(last_landmark, landmark); ++ strncpy(last_message, message, sizeof(last_message)); ++ last_message[sizeof(last_message) - 1] = 0; ++ strncpy(last_landmark, landmark, sizeof(last_landmark)); ++ last_landmark[sizeof(last_landmark) - 1] = 0; + last_is_error = is_error; + if (different_error_count == 11) { + if (!(gfi && gfi->user_flags)) +@@ -618,7 +620,7 @@ close_giffile(FILE *f, int final) + void + input_stream(const char *name) + { +- static char *component_namebuf = 0; ++ char* component_namebuf; + FILE *f; + Gif_Stream *gfs; + int i; +@@ -651,11 +653,11 @@ input_stream(const char *name) + /* change filename for component files */ + componentno++; + if (componentno > 1) { +- free(component_namebuf); + component_namebuf = (char*) malloc(strlen(main_name) + 10); + sprintf(component_namebuf, "%s~%d", main_name, componentno); + name = component_namebuf; +- } ++ } else ++ component_namebuf = 0; + + /* check for empty file */ + i = getc(f); +@@ -664,8 +666,7 @@ input_stream(const char *name) + lerror(name, "empty file"); + else if (nextfile) + lerror(name, "no more images in file"); +- close_giffile(f, 1); +- return; ++ goto error; + } + ungetc(i, f); + +@@ -685,8 +686,7 @@ input_stream(const char *name) + Gif_DeleteStream(gfs); + if (verbosing) + verbose_close('>'); +- close_giffile(f, 1); +- return; ++ goto error; + } + + /* special processing for components after the first */ +@@ -768,9 +768,15 @@ input_stream(const char *name) + gfs->refcount++; + + /* Read more files. */ ++ free(component_namebuf); + if ((gif_read_flags & GIF_READ_TRAILING_GARBAGE_OK) && !nextfile) + goto retry_file; + close_giffile(f, 0); ++ return; ++ ++ error: ++ free(component_namebuf); ++ close_giffile(f, 1); + } + + void +diff --git a/src/gifwrite.c b/src/gifwrite.c +index 38d6084..3d0dfc2 100644 +--- a/src/gifwrite.c ++++ b/src/gifwrite.c +@@ -304,7 +304,7 @@ write_compressed_data(Gif_Image *gfi, + unsigned ncap = bufcap * 2 + (24 << 3); + uint8_t *nbuf = Gif_NewArray(uint8_t, ncap >> 3); + if (!nbuf) +- return 0; ++ goto error; + memcpy(nbuf, buf, bufcap >> 3); + if (buf != stack_buffer) + Gif_DeleteArray(buf); +@@ -451,8 +451,12 @@ write_compressed_data(Gif_Image *gfi, + + if (buf != stack_buffer) + Gif_DeleteArray(buf); +- + return 1; ++ ++ error: ++ if (buf != stack_buffer) ++ Gif_DeleteArray(buf); ++ return 0; + } + + +diff --git a/src/gifx.c b/src/gifx.c +index 93eab8d..fb192dd 100644 +--- a/src/gifx.c ++++ b/src/gifx.c +@@ -842,8 +842,8 @@ Gif_DeleteXContext(Gif_XContext *gfx) + if (gfx->mask_gc) + XFreeGC(gfx->display, gfx->mask_gc); + Gif_DeleteArray(gfx->closest); +- Gif_Delete(gfx); + Gif_RemoveDeletionHook(GIF_T_COLORMAP, delete_colormap_hook, gfx); ++ Gif_Delete(gfx); + } + + +diff --git a/src/quantize.c b/src/quantize.c +index c07a9b9..dc780d5 100644 +--- a/src/quantize.c ++++ b/src/quantize.c +@@ -1690,7 +1690,7 @@ colormap_stream(Gif_Stream* gfs, Gif_Colormap* new_cm, Gt_OutputData* od) + } + + /* map the image data, transparencies, and background */ +- if (gfs->global && gfs->background < gfs->global->ncol) ++ if (gfs->background < gfs->global->ncol) + gfs->background = map[gfs->background]; + for (imagei = 0; imagei < gfs->nimages; imagei++) { + Gif_Image *gfi = gfs->images[imagei]; +diff --git a/src/xform.c b/src/xform.c +index 3173591..aa62c55 100644 +--- a/src/xform.c ++++ b/src/xform.c +@@ -20,6 +20,10 @@ + #if HAVE_UNISTD_H + # include + #endif ++#if HAVE_SYS_TYPES_H && HAVE_SYS_STAT_H ++# include ++# include ++#endif + #ifndef M_PI + /* -std=c89 does not define M_PI */ + # define M_PI 3.14159265358979323846 +@@ -152,8 +156,12 @@ pipe_color_transformer(Gif_Colormap *gfcm, void *thunk) + char *new_command; + + #ifdef HAVE_MKSTEMP +- if (mkstemp(tmp_file) < 0) +- fatal_error("can%,t create temporary file!"); ++ { ++ mode_t old_mode = umask(077); ++ if (mkstemp(tmp_file) < 0) ++ fatal_error("can%,t create temporary file!"); ++ umask(old_mode); ++ } + #else + if (!tmp_file) + fatal_error("can%,t create temporary file!"); +@@ -562,11 +570,11 @@ static void scale_image_output_row(scale_context* sctx, scale_color* sc, + + gfo->left]; + + for (xo = 0; xo != gfo->width; ++xo) +- if (sc[xo].a[3] <= KC_MAX / 4) ++ if (sc[xo].a[3] <= (int) (KC_MAX / 4)) + oscr[xo] = kac_transparent(); + else { + /* don't effectively mix partially transparent pixels with black */ +- if (sc[xo].a[3] <= KC_MAX * 31 / 32) ++ if (sc[xo].a[3] <= (int) (KC_MAX * 31 / 32)) + for (k = 0; k != 3; ++k) + sc[xo].a[k] *= KC_MAX / sc[xo].a[3]; + /* find closest color */ diff --git a/coverity2.patch b/coverity2.patch new file mode 100644 index 0000000..b9b462b --- /dev/null +++ b/coverity2.patch @@ -0,0 +1,20 @@ +diff --git a/src/gifsicle.c b/src/gifsicle.c +index b4cedbc..e326c84 100644 +--- a/src/gifsicle.c ++++ b/src/gifsicle.c +@@ -58,10 +58,11 @@ static int no_ignore_errors = 0; + #define CHANGED(next, flag) (((next) & (1<<(flag))) != 0) + #define UNCHECKED_MARK_CH(where, what) \ + next_##where |= 1< 1) fputs("\\000", f); break; +- default: fprintf(f, "\\%03o", *s); break; ++ default: fprintf(f, "\\%03o", (unsigned char) *s); break; + } + } + if (last_safe != s) { diff --git a/fix-out-of-bound.patch b/fix-out-of-bound.patch new file mode 100644 index 0000000..d580202 --- /dev/null +++ b/fix-out-of-bound.patch @@ -0,0 +1,60 @@ +From 1a29f8f5a0e19a2c671eea3604bb43ad0de8c467 Mon Sep 17 00:00:00 2001 +From: Eddie Kohler +Date: Fri, 7 Apr 2017 16:55:09 -0400 +Subject: [PATCH] Correct an out-of-bounds read found by @b0b0505 using afl. + +--- + src/merge.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +diff --git a/src/merge.c b/src/merge.c +index 699c8ca..47486b7 100644 +--- a/src/merge.c ++++ b/src/merge.c +@@ -257,6 +257,7 @@ merge_image(Gif_Stream *dest, Gif_Stream *src, Gif_Image *srci, + Gt_Frame* srcfr, int same_compressed_ok) + { + Gif_Colormap *imagecm; ++ int imagecm_ncol; + int i; + Gif_Colormap *localcm = 0; + Gif_Colormap *destcm = dest->global; +@@ -268,12 +269,14 @@ merge_image(Gif_Stream *dest, Gif_Stream *src, Gif_Image *srci, + uint8_t used[256]; /* used[output pixval K] == 1 iff K was used + in the image */ + ++ + Gif_Image *desti; + + /* mark colors that were actually used in this image */ + imagecm = srci->local ? srci->local : src->global; ++ imagecm_ncol = imagecm ? imagecm->ncol : 0; + merge_image_input_colors(inused, srci); +- for (i = imagecm ? imagecm->ncol : 0; i != 256; ++i) ++ for (i = imagecm_ncol; i != 256; ++i) + if (inused[i]) { + lwarning(srcfr->input_filename, "some colors undefined by colormap"); + break; +@@ -286,18 +289,14 @@ merge_image(Gif_Stream *dest, Gif_Stream *src, Gif_Image *srci, + /* Merge the colormap */ + if (merge_colormap_if_possible(dest->global, imagecm)) { + /* Create 'map' and 'used' for global colormap. */ +- for (i = 0; i != 256; ++i) +- if (inused[i]) { +- if (imagecm && i < imagecm->ncol) +- map[i] = imagecm->col[i].pixel; +- else +- map[i] = 0; +- } ++ for (i = 0; i != imagecm_ncol; ++i) ++ if (inused[i]) ++ map[i] = imagecm->col[i].pixel; + + } else { + /* Need a local colormap. */ + destcm = localcm = Gif_NewFullColormap(0, 256); +- for (i = 0; i != 256; ++i) ++ for (i = 0; i != imagecm_ncol; ++i) + if (inused[i]) { + map[i] = localcm->ncol; + localcm->col[localcm->ncol] = imagecm->col[i]; diff --git a/gifsicle.changes b/gifsicle.changes index 7cfb991..47fe42a 100644 --- a/gifsicle.changes +++ b/gifsicle.changes @@ -1,3 +1,25 @@ +------------------------------------------------------------------- +Mon Apr 10 16:40:40 CEST 2017 - manfred99@gmx.ch + +- add document-no-conserve-memory.patch: + upstream fix, commit f27a90731ef1152a106612c4293622736e20e6f8 +- fix-out-of-bound.patch: + upstream fix, commit 1a29f8f5a0e19a2c671eea3604bb43ad0de8c467 + +------------------------------------------------------------------- +Thu Sep 29 00:39:33 CEST 2016 - manfred99@gmx.ch + +- add coverity.patch: + upstream fix, commit f679917e8290804ea9ba2d954aedf9caa7e5f142 +- add coverity2.patch: + upstream fix, commit 9ca87d7b1f24e01d30eb41b2304b96131f6c3b53 + +------------------------------------------------------------------- +Wed Sep 28 10:25:38 CEST 2016 - manfred99@gmx.ch + +- add fix-escapes-in-info-mode.patch: + upstream fix for github issue #75, commit 2eff5e69e78b9fb28840508e8fc723be115a0167 + ------------------------------------------------------------------- Sun Jan 24 14:39:33 UTC 2016 - mpluskal@suse.com @@ -6,8 +28,10 @@ Sun Jan 24 14:39:33 UTC 2016 - mpluskal@suse.com ------------------------------------------------------------------- Fri Jan 22 16:01:36 CET 2016 - manfred99@gmx.ch + - update license indication in the spec file: it is GPL-2.0 (only) ------------------------------------------------------------------- Thu Jan 14 15:42:21 CET 2016 - manfred99@gmx.ch + - rpm packaging for OBS diff --git a/gifsicle.spec b/gifsicle.spec index ff25468..b53f09a 100644 --- a/gifsicle.spec +++ b/gifsicle.spec @@ -1,7 +1,7 @@ # # spec file for package gifsicle # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -24,9 +24,16 @@ License: GPL-2.0 Group: Productivity/Graphics/Other Url: https://www.lcdf.org/gifsicle/ Source: https://www.lcdf.org/gifsicle/%{name}-%{version}.tar.gz +Patch0: fix-escapes-in-info-mode.patch +Patch1: coverity.patch +Patch2: coverity2.patch +Patch3: document-no-conserve-memory.patch +Patch4: fix-out-of-bound.patch Obsoletes: ungifsicle < %{version} Provides: ungifsicle = %{version} BuildRoot: %{_tmppath}/%{name}-%{version}-build +BuildRequires: autoconf +BuildRequires: automake %if 0%{?suse_version} == 1110 BuildRequires: xorg-x11-libX11 BuildRequires: xorg-x11-libX11-devel @@ -57,6 +64,12 @@ GIF-manipulating software. %prep %setup -q +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +autoreconf %build %configure @@ -74,8 +87,8 @@ make install DESTDIR=%{buildroot} %{_bindir}/gifdiff %{_bindir}/gifsicle %{_bindir}/gifview -%{_mandir}/man1/gifdiff.1%{ext_man} -%{_mandir}/man1/gifsicle.1%{ext_man} -%{_mandir}/man1/gifview.1%{ext_man} +%{_mandir}/man1/gifdiff.1* +%{_mandir}/man1/gifsicle.1* +%{_mandir}/man1/gifview.1* %changelog