[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

ming security update for Wheezy LTS



Hi,

I have prepared the update for Wheezy using the upstream patches I wrote
and I also enabled hardening to make exploiting the remaining
vulnerabilities harder.

I know it is more than the usual minimal patches for fixing CVEs but in
case of ming's codebase enabling hardening is worth the risk of
regressions IMO.

I have rebuilt all the reverse build dependencies and performed manual
testing but a second look at the patch and at the packages is welcome.

Please see the diff to previous version attached.

Changes:
 ming (1:0.4.4-1.1+deb7u1) wheezy-security; urgency=medium
 .
   * LTS Team upload
   * Fix security vulnerabilites (Closes: #843928):
     - listswf: heap-based buffer overflow in parseSWF_RGBA (parser.c)
       (CVE-2016-9831)
     - listswf: heap-based buffer overflow in parseSWF_DEFINEFONT (parser.c)
     - (CVE-2016-9829)
     - listswf: NULL pointer dereference in dumpBuffer (read.c)
       (CVE-2016-9828)
     - listswf: heap-based buffer overflow in _iprintf (outputtxt.c)
       (CVE-2016-9827)
     - left shift in listmp3.c (CVE-2016-9266)
     - divide-by-zero in printMP3Headers (listmp3.c) (CVE-2016-9265)
     - global-buffer-overflow in printMP3Headers (listmp3.c) (CVE-2016-9264)
   * Enable tests during build
   * Enable all hardening build flags
   * Build-depend on dpkg-dev (>= 1.16.1~), it is needed for hardening flags

I plan uploading the package tomorrow around 22:00 UTC.

The binary packages for amd64 are also available for testing here:

 deb https://people.debian.org/~rbalint/ppa/wheezy-lts UNRELEASED/

I have filed #851275 to remove ming from security support as I wrote in
my previous email [1].

Cheers,
Balint

[1] https://lists.debian.org/debian-lts/2017/01/msg00021.html
diff -u ming-0.4.4/debian/changelog ming-0.4.4/debian/changelog
--- ming-0.4.4/debian/changelog
+++ ming-0.4.4/debian/changelog
@@ -1,3 +1,24 @@
+ming (1:0.4.4-1.1+deb7u1) wheezy-security; urgency=medium
+
+  * LTS Team upload
+  * Fix security vulnerabilites (Closes: #843928):
+    - listswf: heap-based buffer overflow in parseSWF_RGBA (parser.c)
+      (CVE-2016-9831)
+    - listswf: heap-based buffer overflow in parseSWF_DEFINEFONT (parser.c)
+    - (CVE-2016-9829)
+    - listswf: NULL pointer dereference in dumpBuffer (read.c)
+      (CVE-2016-9828)
+    - listswf: heap-based buffer overflow in _iprintf (outputtxt.c)
+      (CVE-2016-9827)
+    - left shift in listmp3.c (CVE-2016-9266)
+    - divide-by-zero in printMP3Headers (listmp3.c) (CVE-2016-9265)
+    - global-buffer-overflow in printMP3Headers (listmp3.c) (CVE-2016-9264)
+  * Enable tests during build
+  * Enable all hardening build flags
+  * Build-depend on dpkg-dev (>= 1.16.1~), it is needed for hardening flags
+
+ -- Balint Reczey <balint@balintreczey.hu>  Fri, 13 Jan 2017 17:25:31 +0100
+
 ming (1:0.4.4-1.1) unstable; urgency=low
 
   * Non-maintainer upload.
diff -u ming-0.4.4/debian/control ming-0.4.4/debian/control
--- ming-0.4.4/debian/control
+++ ming-0.4.4/debian/control
@@ -2,7 +2,7 @@
 Section: libs
 Priority: optional
 Maintainer: Stuart R. Anderson <anderson@netsweng.com>
-Build-Depends: debhelper (>= 5.0.37.2), docbook-to-man, swig, python-all-dev (>= 2.3.5-11), libgif-dev, libpng12-dev, libz-dev, perl (>= 5.10.0), autotools-dev, flex, bison, libfreetype6-dev, ttf-dejavu, ttf-opensymbol, python-central (>= 0.5), php5-dev, php5-cli, automake1.10, autoconf2.59, quilt, chrpath
+Build-Depends: debhelper (>= 5.0.37.2), docbook-to-man, swig, python-all-dev (>= 2.3.5-11), libgif-dev, libpng12-dev, libz-dev, perl (>= 5.10.0), autotools-dev, flex, bison, libfreetype6-dev, ttf-dejavu, ttf-opensymbol, python-central (>= 0.5), php5-dev, php5-cli, automake1.10, autoconf2.59, quilt, chrpath, dpkg-dev (>= 1.16.1~)
 XS-Python-Version: all
 Standards-Version: 3.8.4
 Homepage: http://ming.sourceforge.net/
diff -u ming-0.4.4/debian/rules ming-0.4.4/debian/rules
--- ming-0.4.4/debian/rules
+++ ming-0.4.4/debian/rules
@@ -25,13 +25,10 @@
 PYDEF=$(shell pyversions -d)
 PYVERS=$(shell pyversions -r)
 
-CFLAGS = -Wall -g
-
-ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
-	CFLAGS += -O0
-else
-	CFLAGS += -O2
-endif
+# enable all hardening options
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+DPKG_EXPORT_BUILDFLAGS = 1
+include /usr/share/dpkg/buildflags.mk
 
 configure: configure-stamp
 configure-stamp:
@@ -47,7 +44,7 @@
 endif
 	./autogen.sh
 
-	CFLAGS="$(CFLAGS)" ./configure \
+	./configure \
 		--host=$(DEB_HOST_GNU_TYPE) \
 		--build=$(DEB_BUILD_GNU_TYPE) \
 		--prefix=/usr \
@@ -69,7 +66,7 @@
 	$(MAKE)
 
 	# Some tests are missing upstream, so this fails
-	#$(MAKE) check
+	-$(MAKE) check
 
 	touch build-arch-stamp
 
diff -u ming-0.4.4/debian/patches/03_py_ext ming-0.4.4/debian/patches/03_py_ext
--- ming-0.4.4/debian/patches/03_py_ext
+++ ming-0.4.4/debian/patches/03_py_ext
@@ -1,6 +1,6 @@
 --- a/py_ext/Makefile.am
 +++ b/py_ext/Makefile.am
-@@ -18,7 +18,7 @@ clean-local:
+@@ -18,7 +18,7 @@
  	rm -Rf test.swf build
  
  install:
diff -u ming-0.4.4/debian/patches/series ming-0.4.4/debian/patches/series
--- ming-0.4.4/debian/patches/series
+++ ming-0.4.4/debian/patches/series
@@ -7,0 +8,10 @@
+0001-Fix-division-by-zero-sample-rate-due-to-global-buffe.patch
+0002-Fix-using-EOF-marker-1-value-as-a-valid-flag-byte.patch
+0003-Exit-immediately-when-unexpected-EOF-is-by-fgetc-in-.patch
+0004-Return-EOF-when-reading-unsigned-values-hits-end-of-.patch
+0005-Make-readString-stop-reading-string-past-buffer-s-en.patch
+0006-Check-values-before-deriving-malloc-parameters-from-.patch
+0007-Parse-Protect-tag-s-Password-as-string.patch
+0008-Don-t-try-printing-unknown-block.patch
+0009-Avoid-division-by-zero-in-listmp3-when-no-valid-fram.patch
+10-revert-pie-for-shared-libs
only in patch2:
unchanged:
--- ming-0.4.4.orig/debian/patches/0001-Fix-division-by-zero-sample-rate-due-to-global-buffe.patch
+++ ming-0.4.4/debian/patches/0001-Fix-division-by-zero-sample-rate-due-to-global-buffe.patch
@@ -0,0 +1,46 @@
+From 08400cfcd1a39c12b9f8894f6b4b2146029eab2f Mon Sep 17 00:00:00 2001
+From: Balint Reczey <balint@balintreczey.hu>
+Date: Sat, 31 Dec 2016 01:20:25 +0100
+Subject: [PATCH 1/8] Fix division by zero sample rate due to global buffer
+ overflow.
+
+Also known as CVE-2016-9264 and CVE-2016-9265.
+
+Fixes: #51, #52
+---
+ util/listmp3.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/util/listmp3.c b/util/listmp3.c
+index b7f0619..80947d9 100644
+--- a/util/listmp3.c
++++ b/util/listmp3.c
+@@ -39,10 +39,11 @@ int mp2l23_bitrate_table[] = { 0,    8,  16,  24,  32,  40,  48,  56,
+ 
+ #define MP3_SAMPLERATE       0x00000C00
+ #define MP3_SAMPLERATE_SHIFT 10
++#define MP3_SAMPLERATE_IDX_MAX 2
+ 
+-int mp1_samplerate_table[] = { 44100, 48000, 32000 };
+-int mp2_samplerate_table[] = { 22050, 24000, 16000 }; /* is this right?? */
+-int mp25_samplerate_table[] = { 11025, 12000, 8000 }; /* fewer samples?? */
++int mp1_samplerate_table[MP3_SAMPLERATE_IDX_MAX + 1] = { 44100, 48000, 32000 };
++int mp2_samplerate_table[MP3_SAMPLERATE_IDX_MAX + 1] = { 22050, 24000, 16000 }; /* is this right?? */
++int mp25_samplerate_table[MP3_SAMPLERATE_IDX_MAX + 1] = { 11025, 12000, 8000 }; /* fewer samples?? */
+ 
+ #define MP3_PADDING          0x00000200 /* if set, add an extra slot - 4 bytes
+ 					   for layer 1, 1 byte for 2+3 */
+@@ -103,6 +104,10 @@ void printMP3Headers(FILE *f)
+ 
+     bitrate_idx = (flags & MP3_BITRATE) >> MP3_BITRATE_SHIFT;
+     samplerate_idx = (flags & MP3_SAMPLERATE) >> MP3_SAMPLERATE_SHIFT;
++    if (samplerate_idx < 0 || samplerate_idx > MP3_SAMPLERATE_IDX_MAX)
++    {
++      error("invalid samplerate index");
++    }
+ 
+     channels = ((flags & MP3_CHANNEL) == MP3_CHANNEL_MONO) ? 1 : 2;
+ 
+-- 
+2.1.4
+
only in patch2:
unchanged:
--- ming-0.4.4.orig/debian/patches/0002-Fix-using-EOF-marker-1-value-as-a-valid-flag-byte.patch
+++ ming-0.4.4/debian/patches/0002-Fix-using-EOF-marker-1-value-as-a-valid-flag-byte.patch
@@ -0,0 +1,44 @@
+From 1b901d77aada2480bc01b8439b9dc71c9f1a1b50 Mon Sep 17 00:00:00 2001
+From: Balint Reczey <balint@balintreczey.hu>
+Date: Sat, 31 Dec 2016 01:52:30 +0100
+Subject: [PATCH 2/8] Fix using EOF marker -1 value as a valid flag byte
+
+Also known as CVE-2016-9266
+
+Fixes: #53
+---
+ util/listmp3.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/util/listmp3.c
++++ b/util/listmp3.c
+@@ -74,6 +74,8 @@
+ 
+   for(;;)
+   {
++    int flags_char;
++    int i;
+     /* get 4-byte header, bigendian */
+     if((flags = fgetc(f)) == EOF)
+       break;
+@@ -92,9 +94,17 @@
+       break;
+ 
+     flags <<= 24;
+-    flags += fgetc(f) << 16;
+-    flags += fgetc(f) << 8;
+-    flags += fgetc(f);
++    for (i = 2; i >= 0; --i)
++    {
++      if ((flags_char = fgetc(f)) == EOF)
++      {
++        error("truncated file");
++      }
++      else
++      {
++        flags += flags_char << (i * 8);
++      }
++    }
+ 
+     if((flags & MP3_FRAME_SYNC) != MP3_FRAME_SYNC)
+       break;
only in patch2:
unchanged:
--- ming-0.4.4.orig/debian/patches/0003-Exit-immediately-when-unexpected-EOF-is-by-fgetc-in-.patch
+++ ming-0.4.4/debian/patches/0003-Exit-immediately-when-unexpected-EOF-is-by-fgetc-in-.patch
@@ -0,0 +1,149 @@
+From 059933c07418ed6c6c272074d8065b02e585407a Mon Sep 17 00:00:00 2001
+From: Balint Reczey <balint@balintreczey.hu>
+Date: Mon, 2 Jan 2017 21:28:17 +0100
+Subject: [PATCH 3/8] Exit immediately when unexpected EOF is by fgetc() in
+ utility programs
+
+Fixes CVE-2016-9831
+
+Fixes: #58
+---
+ util/listfdb.c     | 24 +++++++++++++++++++++++-
+ util/listjpeg.c    | 13 ++++++++-----
+ util/old/listswf.c |  5 +++++
+ util/old/read.c    | 32 +++++++++++++++++++++++++++++---
+ util/read.c        | 32 +++++++++++++++++++++++++++++---
+ 5 files changed, 94 insertions(+), 12 deletions(-)
+
+--- a/util/listfdb.c
++++ b/util/listfdb.c
+@@ -71,12 +71,24 @@
+     {
+       ret <<= 8;
+       ret += fgetc(f);
++      if (feof(f))
++      {
++        fprintf(stderr, "truncated file\n");
++        exit(-1);
++      }
++
+       ++fileOffset;
+       number -= 8;
+     }
+ 
+     ++fileOffset;
+     buffer = fgetc(f);
++    if (feof(f))
++    {
++      fprintf(stderr, "truncated file\n");
++      exit(-1);
++    }
++
+ 
+     if(number>0)
+     {
+@@ -108,9 +120,19 @@
+ 
+ int readUInt8(FILE *f)
+ {
++  int tmp_char = fgetc(f);
++  // the rest of the code does not handle errors and use EOF as a valid unsigned char value
++  if (tmp_char == EOF)
++  {
++    // exit here instead of crashing elswhere
++    fprintf(stderr, "truncated file\n");
++    exit(-1);
++  }
++
+   bufbits = 0;
+   ++fileOffset;
+-  return fgetc(f);
++
++  return tmp_char;
+ }
+ 
+ int readSInt8(FILE *f)
+--- a/util/listjpeg.c
++++ b/util/listjpeg.c
+@@ -52,11 +52,14 @@
+ 
+     if(c != JPEG_SOI && c != JPEG_EOI)
+     {
+-      l = (fgetc(f)<<8) + fgetc(f);
+-      printf("%i bytes\n", l);
++      int tmp_char = fgetc(f);
++      if (!feof(f)) {
++        l = (tmp_char << 8) + fgetc(f);
++        printf("%i bytes\n", l);
+ 
+-      for(l-=2; l>0; --l)
+-	fgetc(f);
++        for(l-=2; l>0; --l)
++          fgetc(f);
++      }
+     }
+   }
+ }
+--- a/util/read.c
++++ b/util/read.c
+@@ -23,6 +23,7 @@
+ int readBits(FILE *f, int number)
+ {
+   int ret = buffer;
++  int tmp_char;
+ 
+   if(number == bufbits)
+   {
+@@ -37,14 +38,30 @@
+ 
+     while(number>8)
+     {
++      tmp_char = fgetc(f);
++      if (tmp_char == EOF)
++      {
++        // exit here instead of crashing elswhere
++        fprintf(stderr, "truncated file\n");
++        exit(-1);
++      }
++
+       ret <<= 8;
+-      ret += fgetc(f);
++      ret += tmp_char;
+       ++fileOffset;
+       number -= 8;
+     }
+ 
+     ++fileOffset;
+-    buffer = fgetc(f);
++    tmp_char = fgetc(f);
++    if (tmp_char == EOF)
++    {
++      // exit here instead of crashing elswhere
++      fprintf(stderr, "truncated file\n");
++      exit(-1);
++    }
++
++    buffer = tmp_char;
+ 
+     if(number>0)
+     {
+@@ -88,9 +105,18 @@
+ 
+ int readUInt8(FILE *f)
+ {
++  int tmp_char = fgetc(f);
++  // the rest of the code does not handle errors and use EOF as a valid unsigned char value
++  if (tmp_char == EOF)
++  {
++    // exit here instead of crashing elswhere
++    fprintf(stderr, "truncated file\n");
++    exit(-1);
++  }
++
+   bufbits = 0;
+   ++fileOffset;
+-  return fgetc(f);
++  return tmp_char;
+ }
+ 
+ int readSInt8(FILE *f)
only in patch2:
unchanged:
--- ming-0.4.4.orig/debian/patches/0004-Return-EOF-when-reading-unsigned-values-hits-end-of-.patch
+++ ming-0.4.4/debian/patches/0004-Return-EOF-when-reading-unsigned-values-hits-end-of-.patch
@@ -0,0 +1,50 @@
+From d63684662299279973ac16671dbee80337926bff Mon Sep 17 00:00:00 2001
+From: Balint Reczey <balint@balintreczey.hu>
+Date: Wed, 4 Jan 2017 11:26:05 +0100
+Subject: [PATCH 4/8] Return EOF when reading unsigned values hits end of
+ memory backed buffer
+
+---
+ src/actioncompiler/listaction.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/src/actioncompiler/listaction.c b/src/actioncompiler/listaction.c
+index 3177956..a24fccf 100644
+--- a/src/actioncompiler/listaction.c
++++ b/src/actioncompiler/listaction.c
+@@ -30,6 +30,10 @@ int fileOffset = 0;
+ 
+ int readUInt8(Buffer f)
+ {
++  if (f->buffersize <= fileOffset)
++  {
++    return EOF;
++  }
+   return f->buffer[fileOffset++];
+ }
+ 
+@@ -45,6 +49,10 @@ int readSInt16(Buffer f)
+ 
+ int readUInt16(Buffer f)
+ {
++  if(f->buffersize <= fileOffset + 1)
++  {
++    return EOF;
++  }
+   return readUInt8(f) + (readUInt8(f)<<8);
+ }
+ 
+@@ -55,6 +63,10 @@ long readSInt32(Buffer f)
+ 
+ unsigned long readUInt32(Buffer f)
+ {
++  if(f->buffersize <= fileOffset + 3)
++  {
++    return EOF;
++  }
+   return (unsigned long)(readUInt8(f) + (readUInt8(f)<<8) + (readUInt8(f)<<16) + (readUInt8(f)<<24));
+ }
+ 
+-- 
+2.1.4
+
only in patch2:
unchanged:
--- ming-0.4.4.orig/debian/patches/0005-Make-readString-stop-reading-string-past-buffer-s-en.patch
+++ ming-0.4.4/debian/patches/0005-Make-readString-stop-reading-string-past-buffer-s-en.patch
@@ -0,0 +1,45 @@
+From 21d196cf155e9c2ceb1f2d25cbbc3e8140bb313c Mon Sep 17 00:00:00 2001
+From: Balint Reczey <balint@balintreczey.hu>
+Date: Wed, 4 Jan 2017 11:29:34 +0100
+Subject: [PATCH 5/8] Make readString() stop reading string past buffer's end
+
+---
+ src/actioncompiler/listaction.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/src/actioncompiler/listaction.c b/src/actioncompiler/listaction.c
+index a24fccf..dfac8bc 100644
+--- a/src/actioncompiler/listaction.c
++++ b/src/actioncompiler/listaction.c
+@@ -89,13 +89,14 @@ double readDouble(Buffer f)
+ 
+ char *readString(Buffer f)
+ {
+-  int len = 0, buflen = 256;
+-  char c, *buf, *p;
++  int len = 0, buflen = 256, tmp_char;
++  char *buf, *p;
+ 
+   buf = (char *)malloc(sizeof(char)*256);
+   p = buf;
+ 
+-  while((c=(char)readUInt8(f)) != '\0')
++  tmp_char = readUInt8(f);
++  while(tmp_char != EOF && tmp_char != '\0')
+   {
+     if(len==buflen)
+     {
+@@ -104,8 +105,9 @@ char *readString(Buffer f)
+       p = buf+len;
+     }
+ 
+-    *(p++) = c;
++    *(p++) = (char)tmp_char;
+     ++len;
++    tmp_char = readUInt8(f);
+   }
+ 
+   *p = 0;
+-- 
+2.1.4
+
only in patch2:
unchanged:
--- ming-0.4.4.orig/debian/patches/0006-Check-values-before-deriving-malloc-parameters-from-.patch
+++ ming-0.4.4/debian/patches/0006-Check-values-before-deriving-malloc-parameters-from-.patch
@@ -0,0 +1,607 @@
+From 585267d16a233846bc1fa98563dfaf759e535295 Mon Sep 17 00:00:00 2001
+From: Balint Reczey <balint@balintreczey.hu>
+Date: Thu, 5 Jan 2017 15:34:58 +0100
+Subject: [PATCH 6/8] Check values before deriving malloc parameters from them
+ in parser.c
+
+Fixes CVE-2016-9829.
+
+Fixes: #57
+---
+ util/parser.c   | 205 +++++++++++++++++++++++++++++++++++++++++++++++---------
+ util/swftypes.h |   2 +-
+ 2 files changed, 174 insertions(+), 33 deletions(-)
+
+--- a/util/parser.c
++++ b/util/parser.c
+@@ -18,9 +18,11 @@
+  *
+  ****************************************************************************/
+ 
++#include <stdint.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <sys/param.h>
+ #include "blocks/blocktypes.h"
+ #include "abctypes.h"
+ #include "action.h"
+@@ -239,10 +241,12 @@
+ void
+ parseSWF_GLYPHENTRY (FILE * f, SWF_GLYPHENTRY *gerec, int glyphbits, int advancebits)
+ {
+-  int i;
++  unsigned int i;
+ 
+-  gerec->GlyphIndex = malloc((glyphbits+31)/32 * sizeof(UI32) );
++  size_t nmalloc = ( glyphbits < 1 ? 1 : ((glyphbits+31)/32) ) * sizeof(UI32);
++  gerec->GlyphIndex = malloc(nmalloc);
+   for( i=0; glyphbits; i++ ) {
++    if (i < (nmalloc / sizeof(UI32))) {
+ 	  if( glyphbits > 32 ) {
+ 	  	gerec->GlyphIndex[i] = readBits(f, 32);
+ 	  	glyphbits -= 32;
+@@ -250,10 +254,15 @@
+ 	 	gerec->GlyphIndex[i] = readBits(f, glyphbits);
+ 	 	glyphbits = 0;
+   	}
++    } else {
++      SWF_error("unexpected end of file");
++    }
+   }
+ 
+-  gerec->GlyphAdvance = malloc((advancebits+31)/32 * sizeof(UI32) );
++  nmalloc = ( advancebits < 1 ? 1 : ((advancebits+31)/32) ) * sizeof(UI32);
++  gerec->GlyphAdvance = malloc(nmalloc);
+   for( i=0; advancebits; i++ ) {
++    if (i < (nmalloc / sizeof(UI32))) {
+ 	  if( advancebits > 32 ) {
+ 	  	gerec->GlyphAdvance[i] = readBits(f, 32);
+ 	  	advancebits -= 32;
+@@ -261,13 +270,16 @@
+ 	 	gerec->GlyphAdvance[i] = readBits(f, advancebits);
+ 	 	advancebits = 0;
+   	}
++    } else {
++      SWF_error("unexpected end of file");
++    }
+   }
+ }
+ 
+ int
+ parseSWF_TEXTRECORD (FILE * f, struct SWF_TEXTRECORD *brec, int glyphbits, int advancebits, int level)
+ {
+-  int i;
++  int i, glyph_count;
+ 
+   byteAlign ();
+ 
+@@ -293,13 +305,19 @@
+     brec->YOffset = readSInt16 (f);
+   if( brec->StyleFlagHasFont )
+     brec->TextHeight = readUInt16 (f);
+-  brec->GlyphCount = readUInt8 (f);
+-  brec->GlyphEntries = malloc(brec->GlyphCount * sizeof(SWF_GLYPHENTRY) );
+-  byteAlign ();
+-  for(i=0;i<brec->GlyphCount;i++)
+-	  parseSWF_GLYPHENTRY(f, &(brec->GlyphEntries[i]), glyphbits, advancebits );
++  glyph_count = readUInt8 (f);
++  if (glyph_count == EOF) {
++    SWF_error("unexpected end of file");
++    return 0;
++  } else {
++    brec->GlyphCount = glyph_count;
++    brec->GlyphEntries = malloc(brec->GlyphCount * sizeof(SWF_GLYPHENTRY) );
++    byteAlign ();
++    for(i=0;i<brec->GlyphCount;i++)
++            parseSWF_GLYPHENTRY(f, &(brec->GlyphEntries[i]), glyphbits, advancebits );
+ 
+-  return 1;
++    return 1;
++  }
+ }
+ 
+ int
+@@ -644,6 +662,11 @@
+     {
+       count = readUInt16(f);
+     }
++  if (count == EOF)
++  {
++    SWF_error("unexpected end of file");
++  }
++
+   linestyle->LineStyleCount = count;
+ 
+   if(level == 4)
+@@ -717,6 +740,10 @@
+       linestyle->LineStyleCountExtended = readUInt16 (f);
+       count = linestyle->LineStyleCountExtended;
+     }
++  if (count == EOF)
++  {
++    SWF_error("unexpected end of file");
++  }
+   if(version == 1)
+     linestyle->LineStyles =
+       (SWF_MORPHLINESTYLE *) malloc (count * sizeof (SWF_MORPHLINESTYLE));
+@@ -1082,10 +1109,15 @@
+ 		/* v5 actions */
+ 	case SWFACTION_CONSTANTPOOL:
+ 		{
+-		int i;
++		int i, count;
+ 		ACT_BEGIN(SWF_ACTIONCONSTANTPOOL)
+ 
+-		act->Count = readUInt16(f);
++		count = readUInt16(f);
++		if (count == EOF)
++                {
++                  SWF_error("unexpected end of file");
++                }
++		act->Count = count;
+ 		act->ConstantPool = malloc(act->Count*sizeof(char *));
+ 		for(i=0;i<act->Count;i++) {
+ 			act->ConstantPool[i] = readString(f);
+@@ -1094,11 +1126,16 @@
+ 		}
+ 	case SWFACTION_DEFINEFUNCTION:
+ 		{
+-		int i, end2;
++		int i, end2, num_params;
+ 		ACT_BEGIN(SWF_ACTIONDEFINEFUNCTION)
+ 
+ 		act->FunctionName = readString(f);
+-		act->NumParams = readSInt16(f);
++                num_params = readUInt16(f);
++                if (num_params == EOF) {
++                  SWF_error("unexpected end of file");
++                }
++		act->NumParams = num_params;
++
+ 		act->Params = (STRING *)malloc(act->NumParams*sizeof(char *));
+ 		for(i=0;i<act->NumParams;i++) {
+ 			act->Params[i] = readString(f);
+@@ -1147,11 +1184,15 @@
+ 		/* v7 actions */
+ 	case SWFACTION_DEFINEFUNCTION2:
+ 		{
+-		int i, end2;
++		int i, end2, num_params;
+ 		ACT_BEGIN(SWF_ACTIONDEFINEFUNCTION2)
+ 
+ 		act->FunctionName = readString(f);
+-		act->NumParams = readSInt16(f);
++		num_params = readUInt16(f);
++		if (num_params == EOF) {
++		  SWF_error("unexpected end of file");
++		}
++		act->NumParams = num_params;
+ 		act->RegisterCount = readSInt8(f);
+ 		act->PreloadParentFlag = readBits(f,1);
+ 		act->PreloadRootFlag = readBits(f,1);
+@@ -1297,9 +1338,13 @@
+ void 
+ parseSWF_GRADIENTFILTER(FILE *f, SWF_GRADIENTFILTER *filter)
+ {
+-	int i, size;
++	int i, size, num_colors;
+ 
+-	filter->NumColors = readUInt8(f);
++	num_colors = readUInt8(f);
++        if (num_colors == EOF) {
++          SWF_error("unexpected end of file");
++        }
++	filter->NumColors = num_colors;
+ 	size = filter->NumColors * sizeof(SWF_RGBA);
+ 	filter->GradientColors = (SWF_RGBA *)malloc(size);
+ 	for(i = 0; i < filter->NumColors; i++)
+@@ -1325,10 +1370,15 @@
+ void 
+ parseSWF_CONVOLUTIONFILTER(FILE *f, SWF_CONVOLUTIONFILTER *filter)
+ {
+-	int size, i;
++	int size, i, x, y;
+ 
+-	filter->MatrixX = readUInt8(f);
+-	filter->MatrixY = readUInt8(f);
++	x = readUInt8(f);
++	y = readUInt8(f);
++        if (x == EOF || y == EOF) {
++          SWF_error("unexpected end of file");
++        }
++	filter->MatrixX = x;
++	filter->MatrixY = y;
+ 	filter->Divisor = readUInt32(f);
+ 	filter->Bias = readUInt32(f);
+ 
+@@ -1391,8 +1441,14 @@
+ void 
+ parseSWF_FILTERLIST(FILE *f, SWF_FILTERLIST *list)
+ {
+-	int i, size;
+-	list->NumberOfFilters = readUInt8(f);
++	int i, size, number_of_filters;
++	number_of_filters = readUInt8(f);
++        if (number_of_filters == EOF) {
++          list->NumberOfFilters = 0;
++          SWF_error("unexpected end of file");
++          return;
++        }
++	list->NumberOfFilters = number_of_filters;
+ 	size = list->NumberOfFilters * sizeof(SWF_FILTER);
+ 	list->Filter = (SWF_FILTER *)malloc(size);
+ 
+@@ -1641,14 +1697,19 @@
+ parseSWF_DEFINEFONT (FILE * f, int length)
+ {
+   int i;
+-  UI16  firstOffset;
++  int  firstOffset;
+   PAR_BEGIN (SWF_DEFINEFONT);
+ 
+   parserrec->FontID = readUInt16 (f);
+   firstOffset = readUInt16 (f);
++  if (firstOffset == EOF) {
++    SWF_error("unexpected end of file");
++  }
++
+   parserrec->NumGlyphs = (firstOffset/2);
+   Movie_addFontInfo(&m, parserrec->FontID, parserrec->NumGlyphs);
+-  parserrec->OffsetTable = (UI16 *)malloc((firstOffset/2) * sizeof( UI16 ) );
++  // store at least a 0 in the first offset table element if there are no glyphs
++  parserrec->OffsetTable = (UI16 *)malloc(MAX(1, (firstOffset/2)) * sizeof( UI16 ) );
+   parserrec->OffsetTable[0] = firstOffset;
+   for(i=1;i<firstOffset/2;i++) {
+   	parserrec->OffsetTable[i] = readUInt16 (f);
+@@ -1668,7 +1729,7 @@
+ SWF_Parserstruct *
+ parseSWF_DEFINEFONT2 (FILE * f, int length)
+ {
+-  int i;
++  int i, num_glyphs;
+   PAR_BEGIN (SWF_DEFINEFONT2);
+ 
+   byteAlign ();
+@@ -1685,7 +1746,11 @@
+   parserrec->LanguageCode = readUInt8 (f);
+   parserrec->FontNameLen = readUInt8 (f);
+   parserrec->FontName = readSizedString (f, parserrec->FontNameLen);
+-  parserrec->NumGlyphs = readUInt16 (f);
++  num_glyphs = readUInt16 (f);
++  if (num_glyphs == EOF) {
++    SWF_error("unexpected end of file");
++  }
++  parserrec->NumGlyphs = num_glyphs;
+   Movie_addFontInfo(&m, parserrec->FontID, parserrec->NumGlyphs);
+   if (parserrec->FontFlagsWideOffsets)
+     {
+@@ -1755,6 +1820,7 @@
+     }
+ 
+   if( parserrec->FontFlagsHasLayout ) {
++	  int kerning_count;
+ 	  parserrec->FontAscent = readSInt16(f);
+ 	  parserrec->FontDecent = readSInt16(f);
+ 	  parserrec->FontLeading = readSInt16(f);
+@@ -1772,7 +1838,11 @@
+ 	  {
+ 	    parseSWF_RECT (f, &(parserrec->FontBoundsTable[i]));
+ 	  }
+-	  parserrec->KerningCount = readUInt16(f);
++	  kerning_count = readUInt16(f);
++          if (kerning_count == EOF) {
++            SWF_error("unexpected end of file");
++          }
++	  parserrec->KerningCount = kerning_count;
+ 	  /* FontKerningTable */
+ 	  parserrec->FontKerningTable =
+ 	     (struct SWF_KERNINGRECORD *) malloc (parserrec->KerningCount * sizeof (struct SWF_KERNINGRECORD));
+@@ -1795,7 +1865,7 @@
+ SWF_Parserstruct *
+ parseSWF_DEFINEFONT3 (FILE * f, int length)
+ {
+-  int i;
++  int i, num_glyphs;
+   PAR_BEGIN (SWF_DEFINEFONT3);
+ 
+   byteAlign ();
+@@ -1812,7 +1882,11 @@
+   parserrec->LanguageCode = readUInt8 (f);
+   parserrec->FontNameLen = readUInt8 (f);
+   parserrec->FontName = readSizedString (f, parserrec->FontNameLen);
+-  parserrec->NumGlyphs = readUInt16 (f);
++  num_glyphs = readUInt16 (f);
++  if (num_glyphs == EOF) {
++    SWF_error("unexpected end of file");
++  }
++  parserrec->NumGlyphs = num_glyphs;
+   Movie_addFontInfo(&m, parserrec->FontID, parserrec->NumGlyphs);
+   if (parserrec->FontFlagsWideOffsets)
+     {
+@@ -1882,6 +1956,7 @@
+     }
+ 
+   if( parserrec->FontFlagsHasLayout ) {
++	  int kerning_count;
+ 	  parserrec->FontAscent = readSInt16(f);
+ 	  parserrec->FontDecent = readSInt16(f);
+ 	  parserrec->FontLeading = readSInt16(f);
+@@ -1899,7 +1974,11 @@
+ 	  {
+ 	    parseSWF_RECT (f, &(parserrec->FontBoundsTable[i]));
+ 	  }
+-	  parserrec->KerningCount = readUInt16(f);
++	  kerning_count = readUInt16(f);
++          if (kerning_count == EOF) {
++            SWF_error("unexpected end of file");
++          }
++	  parserrec->KerningCount = kerning_count;
+ 	  /* FontKerningTable */
+ 	  parserrec->FontKerningTable =
+ 	     (struct SWF_KERNINGRECORD *) malloc (parserrec->KerningCount * sizeof (struct SWF_KERNINGRECORD));
+@@ -1941,6 +2020,9 @@
+   else
+ 	  parserrec->nGlyph = end-fileOffset;
+ 
++  if (parserrec->nGlyph < 0 || parserrec->nGlyph > (INT_MAX / sizeof(UI16))) {
++    SWF_error("invalid Glyph count");
++  }
+   parserrec->CodeTable = (UI16 *)malloc(parserrec->nGlyph*sizeof(UI16));
+   for(i=0;i<parserrec->nGlyph;i++)
+   if( parserrec->FontFlagsWideCodes )
+@@ -1970,6 +2052,9 @@
+   parserrec->FontFlagsWideCodes = readBits (f, 1);
+   parserrec->LanguageCode = readUInt8(f);
+   parserrec->nGlyph = (end-fileOffset)/2;
++  if (parserrec->nGlyph < 0 || parserrec->nGlyph > (INT_MAX / sizeof(UI16))) {
++    SWF_error("invalid Glyph count");
++  }
+ 
+   parserrec->CodeTable = (UI16 *)malloc(parserrec->nGlyph*sizeof(UI16));
+   for(i=0;i<parserrec->nGlyph;i++)
+@@ -2002,8 +2087,12 @@
+ void 
+ parseSWF_ZONERECORD(FILE *f, struct SWF_ZONERECORD *table)
+ {
+-  int i;
+-  table->NumZoneData = readUInt8(f);
++  int i, num_zone_data;
++  num_zone_data = readUInt8(f);
++  if (num_zone_data == EOF) {
++    SWF_error("unexpeced end of file");
++  }
++  table->NumZoneData = num_zone_data;
+   table->ZoneData = (struct SWF_ZONEDATA *)
+     malloc(table->NumZoneData * sizeof(struct SWF_ZONEDATA));
+   for(i = 0; i < table->NumZoneData; i++)
+@@ -3054,39 +3143,53 @@
+   size_t s;
+  
+   cpool->IntCount = readEncUInt30(f);
++  if (cpool->IntCount > INT_MAX / sizeof(S32))
++    SWF_error("value is too big");
+   cpool->Integers = malloc(cpool->IntCount * sizeof(S32));
+   for(i = 1; i < cpool->IntCount; i++)
+       cpool->Integers[i] = readEncSInt32(f);
+ 
+   cpool->UIntCount = readEncUInt30(f);
++  if (cpool->UIntCount > INT_MAX / sizeof(U32))
++    SWF_error("value is too big");
+   cpool->UIntegers = malloc(cpool->UIntCount * sizeof(U32));
+   for(i = 1; i < cpool->UIntCount; i++)
+     cpool->UIntegers[i] = readEncUInt32(f);
+ 
+   cpool->DoubleCount = readEncUInt30(f);
++  if (cpool->DoubleCount > INT_MAX / sizeof(DOUBLE))
++    SWF_error("value is too big");
+   cpool->Doubles = malloc(cpool->DoubleCount * sizeof(DOUBLE));
+   for(i = 1; i < cpool->DoubleCount; i++)
+     cpool->Doubles[i] = readDouble(f);
+ 
+   cpool->StringCount = readEncUInt30(f);
++  if (cpool->StringCount > INT_MAX / sizeof(struct ABC_STRING_INFO))
++    SWF_error("value is too big");
+   s = cpool->StringCount * sizeof(struct ABC_STRING_INFO);
+   cpool->Strings = malloc(s);
+   for(i = 1; i < cpool->StringCount; i++)
+     parseABC_STRING_INFO(cpool->Strings + i, f);
+ 
+   cpool->NamespaceCount = readEncUInt30(f); 
++  if (cpool->NamespaceCount > INT_MAX / sizeof(struct ABC_NS_INFO))
++    SWF_error("value is too big");
+   s = cpool->NamespaceCount * sizeof(struct ABC_NS_INFO);
+   cpool->Namespaces = malloc(s);
+   for(i = 1; i < cpool->NamespaceCount; i++)
+     parseABC_NS_INFO(cpool->Namespaces + i, f);
+ 
+   cpool->NamespaceSetCount = readEncUInt30(f);
++  if (cpool->NamespaceSetCount > INT_MAX / sizeof(struct ABC_NS_SET_INFO))
++    SWF_error("value is too big");
+   s = cpool->NamespaceSetCount * sizeof(struct ABC_NS_SET_INFO);
+   cpool->NsSets = malloc(s);
+   for(i = 1; i < cpool->NamespaceSetCount; i++)
+     parseABC_NS_SET_INFO(cpool->NsSets + i, f);
+ 
+   cpool->MultinameCount = readEncUInt30(f);
++  if (cpool->MultinameCount > INT_MAX / sizeof(struct ABC_MULTINAME_INFO))
++    SWF_error("value is too big");
+   s = cpool->MultinameCount * sizeof(struct ABC_MULTINAME_INFO);
+   cpool->Multinames = malloc(s);
+   for(i = 1; i < cpool->MultinameCount; i++)
+@@ -3097,6 +3200,8 @@
+ {
+   int i;
+   oinfo->OptionCount = readEncUInt30(f);
++  if (oinfo->OptionCount > INT_MAX / sizeof(struct ABC_OPTION_INFO))
++    SWF_error("%s: line %d: OptionCount is too big", __FUNCTION__, __LINE__);
+   oinfo->Option = malloc(sizeof(struct ABC_OPTION_INFO) * oinfo->OptionCount);
+   for(i = 0; i < oinfo->OptionCount; i++)
+   {
+@@ -3119,6 +3224,8 @@
+ 
+   method->ParamCount = readEncUInt30(f);
+   method->ReturnType = readEncUInt30(f);
++  if (method->ParamCount > INT_MAX / sizeof(U30))
++    SWF_error("parseABC_METHOD_INFO: ParamCount is too big");
+   method->ParamType = malloc(sizeof(U30) * method->ParamCount);
+   for(i = 0; i < method->ParamCount; i++)
+     method->ParamType[i] = readEncUInt30(f);
+@@ -3136,6 +3243,8 @@
+ 
+   meta->Name = readEncUInt30(f);
+   meta->ItemCount = readEncUInt30(f);
++  if (meta->ItemCount > INT_MAX / sizeof(struct ABC_ITEM_INFO))
++    SWF_error("parseABC_METADATA_INFO: ItemCount is too big");
+   meta->Items = malloc(sizeof(struct ABC_ITEM_INFO) * meta->ItemCount);
+   for(i = 0; i < meta->ItemCount; i++)
+   {
+@@ -3202,6 +3311,10 @@
+   if(trait->Attr & ABC_TRAIT_ATTR_METADATA)
+   {
+     trait->MetadataCount = readEncUInt30(f);
++    if (trait->MetadataCount > INT_MAX / sizeof(U30)) {
++      SWF_error("parseABC_TRAITS_INFO: MetadataCount is too big");
++      return;
++    }
+     trait->Metadata = malloc(trait->MetadataCount * sizeof(U30));
+     for(i = 0; i < trait->MetadataCount; i++)
+       trait->Metadata[i] = readEncUInt30(f);
+@@ -3214,6 +3327,8 @@
+ 
+   cinfo->CInit = readEncUInt30(f);
+   cinfo->TraitCount = readEncUInt30(f);
++  if (cinfo->TraitCount > INT_MAX / sizeof(struct ABC_TRAITS_INFO))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   cinfo->Traits = malloc(sizeof(struct ABC_TRAITS_INFO) * cinfo->TraitCount);
+   for(i = 0; i < cinfo->TraitCount; i++)
+     parseABC_TRAITS_INFO(cinfo->Traits + i, f);
+@@ -3225,6 +3340,8 @@
+ 
+   sinfo->Init = readEncUInt30(f);
+   sinfo->TraitCount = readEncUInt30(f);
++  if (sinfo->TraitCount > INT_MAX / sizeof(struct ABC_TRAITS_INFO))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   sinfo->Traits = malloc(sizeof(struct ABC_TRAITS_INFO) * sinfo->TraitCount);
+   for(i = 0; i < sinfo->TraitCount; i++)
+     parseABC_TRAITS_INFO(sinfo->Traits + i, f);
+@@ -3243,6 +3360,8 @@
+     inst->ProtectedNs = readEncUInt30(f);
+ 
+   inst->InterfaceCount = readEncUInt30(f);
++  if (inst->InterfaceCount > INT_MAX / sizeof(U30))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   inst->Interfaces = malloc(inst->InterfaceCount * sizeof(U30));
+   for(i = 0; i < inst->InterfaceCount; i++)
+     inst->Interfaces[i] = readEncUInt30(f);
+@@ -3250,6 +3369,8 @@
+   inst->IInit = readEncUInt30(f);
+ 
+   inst->TraitCount = readEncUInt30(f);
++  if (inst->TraitCount > INT_MAX / sizeof(struct ABC_TRAITS_INFO))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   inst->Traits = malloc(inst->TraitCount * sizeof(struct ABC_TRAITS_INFO));
+   for(i = 0; i < inst->TraitCount; i++)
+     parseABC_TRAITS_INFO(inst->Traits + i, f);
+@@ -3277,11 +3398,15 @@
+   minfo->Code = (UI8 *)readBytes(f, minfo->CodeLength);
+  
+   minfo->ExceptionCount = readEncUInt30(f);
++  if (minfo->ExceptionCount > INT_MAX / sizeof(struct ABC_EXCEPTION_INFO))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   minfo->Exceptions = malloc(minfo->ExceptionCount * sizeof(struct ABC_EXCEPTION_INFO));
+   for(i = 0; i < minfo->ExceptionCount; i++)
+     parseABC_EXCEPTION_INFO(minfo->Exceptions + i, f);
+ 
+   minfo->TraitCount = readEncUInt30(f);
++  if (minfo->TraitCount > INT_MAX / sizeof(struct ABC_TRAITS_INFO))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   minfo->Traits = malloc(sizeof(struct ABC_TRAITS_INFO) * minfo->TraitCount);
+   for(i = 0; i < minfo->TraitCount; i++)
+     parseABC_TRAITS_INFO(minfo->Traits + i, f);
+@@ -3298,20 +3423,28 @@
+   parseABC_CONSTANT_POOL(&abcFile->ConstantPool, f);
+    
+   abcFile->MethodCount = readEncUInt30(f);
++  if (abcFile->MethodCount > INT_MAX / sizeof(struct ABC_METHOD_INFO))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   size = abcFile->MethodCount * sizeof(struct ABC_METHOD_INFO);
+   abcFile->Methods = malloc(size);
+   for(i = 0; i < abcFile->MethodCount; i++)
+     parseABC_METHOD_INFO(abcFile->Methods + i, f);
+   
+   abcFile->MetadataCount = readEncUInt30(f);
++  if (abcFile->MetadataCount > INT_MAX / sizeof(struct ABC_METADATA_INFO))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   size = abcFile->MetadataCount * sizeof(struct ABC_METADATA_INFO);
+   abcFile->Metadata = malloc(size);
+   for(i = 0; i < abcFile->MetadataCount; i++)
+     parseABC_METADATA_INFO(abcFile->Metadata + i, f);
+ 
+   abcFile->ClassCount = readEncUInt30(f);
++  if (abcFile->ClassCount > INT_MAX / sizeof(struct ABC_INSTANCE_INFO))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   size = abcFile->ClassCount * sizeof(struct ABC_INSTANCE_INFO);
+   abcFile->Instances = malloc(size);
++  if (abcFile->ClassCount > INT_MAX / sizeof(struct ABC_CLASS_INFO))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   size = abcFile->ClassCount * sizeof(struct ABC_CLASS_INFO);
+   abcFile->Classes = malloc(size);
+   for(i = 0; i < abcFile->ClassCount; i++)
+@@ -3320,12 +3453,16 @@
+     parseABC_CLASS_INFO(abcFile->Classes + i, f);
+ 
+   abcFile->ScriptCount = readEncUInt30(f);
++  if (abcFile->ScriptCount > INT_MAX / sizeof(struct ABC_SCRIPT_INFO))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   size = abcFile->ScriptCount * sizeof(struct ABC_SCRIPT_INFO);
+   abcFile->Scripts = malloc(size);
+   for(i = 0; i < abcFile->ScriptCount; i++)
+     parseABC_SCRIPT_INFO(abcFile->Scripts + i, f);
+ 
+   abcFile->MethodBodyCount = readEncUInt30(f);
++  if (abcFile->MethodBodyCount > INT_MAX / sizeof(struct ABC_METHOD_BODY_INFO))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   size = abcFile->MethodBodyCount * sizeof(struct ABC_METHOD_BODY_INFO);
+   abcFile->MethodBodies = malloc(size);
+   for(i = 0; i < abcFile->MethodBodyCount; i++)
+@@ -3349,7 +3486,9 @@
+   PAR_BEGIN(SWF_SYMBOLCLASS);
+   count = readUInt16(f);
+   parserrec->SymbolCount = count;
+-  parserrec->SymbolList = malloc(count * sizeof(struct SWF_SYMBOLCLASS));
++  if (parserrec->SymbolCount > INT_MAX / sizeof(struct SWF_SYMBOLCLASS))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
++  parserrec->SymbolList = malloc(parserrec->SymbolCount * sizeof(struct SWF_SYMBOLCLASS));
+   for(i = 0; i < count; i++)
+   {
+      parserrec->SymbolList[i].SymbolId = readUInt16(f);
+@@ -3374,6 +3513,8 @@
+   int i;
+   PAR_BEGIN(SWF_DEFINESCENEANDFRAMEDATA);
+   parserrec->SceneCount = readEncUInt32(f);
++  if (parserrec->SceneCount > INT_MAX / sizeof(struct SCENE_DATA))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   parserrec->Scenes = malloc(sizeof(struct SCENE_DATA) * parserrec->SceneCount);
+   for(i = 0; i < parserrec->SceneCount; i++)
+   {
+@@ -3381,6 +3522,8 @@
+     parserrec->Scenes[i].Name = readString(f);
+   }
+   parserrec->FrameLabelCount = readEncUInt32(f);
++  if (parserrec->FrameLabelCount > INT_MAX / sizeof(struct FRAME_DATA))
++    SWF_error("%s: value is too big, ", __FUNCTION__);
+   parserrec->Frames = malloc(sizeof(struct FRAME_DATA) * parserrec->FrameLabelCount);
+   for(i = 0; i < parserrec->FrameLabelCount; i++)
+   {
+--- a/util/swftypes.h
++++ b/util/swftypes.h
+@@ -1135,7 +1135,7 @@
+ struct SWF_DEFINEFONT
+ {
+   UI16 FontID;
+-  int NumGlyphs;
++  UI16 NumGlyphs;
+   UI16 *OffsetTable;
+   SWF_SHAPE *GlyphShapeTable;
+ };
only in patch2:
unchanged:
--- ming-0.4.4.orig/debian/patches/0007-Parse-Protect-tag-s-Password-as-string.patch
+++ ming-0.4.4/debian/patches/0007-Parse-Protect-tag-s-Password-as-string.patch
@@ -0,0 +1,23 @@
+From aa3662559e66690c98bded8ebac48506dcb7bd8b Mon Sep 17 00:00:00 2001
+From: Balint Reczey <balint@balintreczey.hu>
+Date: Thu, 5 Jan 2017 15:51:11 +0100
+Subject: [PATCH 7/8] Parse Protect tag's Password as string
+
+Fixes CVE-2016-9827.
+
+Fixes: #59
+---
+ util/parser.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/util/parser.c
++++ b/util/parser.c
+@@ -2750,7 +2750,7 @@
+   PAR_BEGIN (SWF_PROTECT);
+ 
+   if( length != 0 ) {
+-  	parserrec->Password = readBytes (f, length);
++  	parserrec->Password = readString (f);
+   } else {
+   	parserrec->Password = NULL;
+   }
only in patch2:
unchanged:
--- ming-0.4.4.orig/debian/patches/0008-Don-t-try-printing-unknown-block.patch
+++ ming-0.4.4/debian/patches/0008-Don-t-try-printing-unknown-block.patch
@@ -0,0 +1,27 @@
+From 2a35928abcb0820520d0ae8115c8fb49c14bbcbc Mon Sep 17 00:00:00 2001
+From: Balint Reczey <balint@balintreczey.hu>
+Date: Thu, 5 Jan 2017 16:50:25 +0100
+Subject: [PATCH 8/8] Don't try printing unknown block.
+
+This fixes the crash also known as CVE-2016-9828.
+
+Fixes: #60
+---
+ util/outputtxt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/util/outputtxt.c b/util/outputtxt.c
+index 7783dd5..eabee84 100644
+--- a/util/outputtxt.c
++++ b/util/outputtxt.c
+@@ -2934,6 +2934,6 @@ outputBlock (int type, SWF_Parserstruct * blockp, FILE* stream)
+ 	  return;
+ 	}
+     }
+-  outputSWF_UNKNOWNBLOCK(blockp);
++  SWF_error("printing type:  %d (%s) is not implemented", type, blockName(type));
+   return;
+ }
+-- 
+2.1.4
+
only in patch2:
unchanged:
--- ming-0.4.4.orig/debian/patches/0009-Avoid-division-by-zero-in-listmp3-when-no-valid-fram.patch
+++ ming-0.4.4/debian/patches/0009-Avoid-division-by-zero-in-listmp3-when-no-valid-fram.patch
@@ -0,0 +1,27 @@
+From 6d99d09aa3731f5924d37df250d4b6698c1d401b Mon Sep 17 00:00:00 2001
+From: Balint Reczey <balint@balintreczey.hu>
+Date: Fri, 13 Jan 2017 19:38:47 +0100
+Subject: [PATCH 9/9] Avoid division by zero in listmp3 when no valid frame was
+ found
+
+---
+ util/listmp3.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/util/listmp3.c b/util/listmp3.c
+index ac6c773..de9d9f7 100644
+--- a/util/listmp3.c
++++ b/util/listmp3.c
+@@ -182,6 +182,9 @@ void printMP3Headers(FILE *f)
+     skipBytes(f, frameLen-4);
+   }
+ 
++  if (numFrames == 0)
++    error("no valid frame found");
++
+   putchar('\n');
+ 
+   length = numFrames*(samplerate > 3200 ? 1152 : 576)/samplerate;
+-- 
+2.1.4
+
only in patch2:
unchanged:
--- ming-0.4.4.orig/debian/patches/10-revert-pie-for-shared-libs
+++ ming-0.4.4/debian/patches/10-revert-pie-for-shared-libs
@@ -0,0 +1,16 @@
+Description: Fix compiling shared library for Python when PIE is enabled
+ Enabling PIE from d/rules injects PIE GCC and LD flags which override
+ -shared.
+ Appending -shared again disables PIE and enables building a shared lib
+ again.
+Author: Balint Reczey <balint@balintreczey.hu>
+Forwarded: not-needed
+--- ./py_ext/setup.py.in.orig	2017-01-23 12:53:18.371021829 +0100
++++ ./py_ext/setup.py.in	2017-01-23 12:53:51.582675263 +0100
+@@ -28,5 +28,6 @@
+       ext_modules = [Extension("_mingc", ["%s/ming_wrap.c" %srcdir],
+                      include_dirs=['/usr/local/include',os.path.join(os.path.join(curdir, '..'),'src')],
+                      library_dirs=['../src/.libs','/usr/local/lib/'],
++                     extra_link_args=['-shared'],
+                      libraries=mylibs)])
+ 

Reply to: