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,12 +241,13 @@ void parseSWF_GLYPHENTRY (FILE * f, SWF_GLYPHENTRY *gerec, int glyphbits, int advancebits) { - int i; + unsigned int i; size_t nmalloc = ( glyphbits < 1 ? 1 : ((glyphbits+31)/32) ) * sizeof(UI32); gerec->GlyphIndex = malloc(nmalloc); gerec->GlyphIndex[0] = 0; /* for glyphbits == 0 */ for( i=0; glyphbits; i++ ) { + if (i < (nmalloc / sizeof(UI32))) { if( glyphbits > 32 ) { gerec->GlyphIndex[i] = readBits(f, 32); glyphbits -= 32; @@ -250,12 +254,16 @@ gerec->GlyphIndex[i] = readBits(f, glyphbits); glyphbits = 0; } + } else { + SWF_error("unexpected end of file"); + } } nmalloc = ( advancebits < 1 ? 1 : ((advancebits+31)/32) ) * sizeof(UI32); gerec->GlyphAdvance = malloc(nmalloc); gerec->GlyphAdvance[0] = 0; /* for advancebits == 0 */ 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; };