1 /****************************************************************************
2  *
3  *  Copyright (C) 2005-2006 "Stuart R. Anderson" <anderson@netsweng.com>
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  ****************************************************************************/
20 
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/param.h>
26 #include "blocks/blocktypes.h"
27 #include "abctypes.h"
28 #include "action.h"
29 #include "decompile.h"
30 #include "parser.h"
31 #include "read.h"
32 #include "blocks/error.h"
33 
34 extern struct Movie m;
35 extern SWF_Parserstruct *blockParse (FILE *f, int length, SWFBlocktype header);
36 const char *blockName (SWFBlocktype header);
37 void silentSkipBytes(FILE *f, int length);
38 
39 #define PAR_BEGIN(block) 						\
40 	struct block *parserrec; 					\
41 	SWF_Parserstruct *pstruct; 					\
42 	pstruct = calloc(1, sizeof(SWF_Parserstruct)); 			\
43 	pstruct->length = length;					\
44 	pstruct->offset = fileOffset - ( (length >= 63 ) ? 6 : 2) ;	\
45 	parserrec= (struct block *)pstruct; 				\
46 
47 #define PAR_END \
48 	return (SWF_Parserstruct *)parserrec;
49 
50 #define SKIP \
51 	printf("skipping %i bytes\n", length); \
52         readBytes(f, length);
53 
54 /* Parse Basic Flash types */
55 
56 void
parseSWF_RGB(FILE * f,struct SWF_RGBA * rgb)57 parseSWF_RGB (FILE * f, struct SWF_RGBA *rgb)
58 {
59   rgb->red = readUInt8 (f);
60   rgb->green = readUInt8 (f);
61   rgb->blue = readUInt8 (f);
62   rgb->alpha = 255;
63 }
64 
65 void
parseSWF_RGBA(FILE * f,struct SWF_RGBA * rgb)66 parseSWF_RGBA (FILE * f, struct SWF_RGBA *rgb)
67 {
68   rgb->red = readUInt8 (f);
69   rgb->green = readUInt8 (f);
70   rgb->blue = readUInt8 (f);
71   rgb->alpha = readUInt8 (f);
72 }
73 
74 void
parseSWF_RECT(FILE * f,struct SWF_RECT * rect)75 parseSWF_RECT (FILE * f, struct SWF_RECT *rect)
76 {
77   byteAlign ();
78 
79   rect->Nbits = readBits (f, 5);
80   rect->Xmin = readSBits (f, rect->Nbits);
81   rect->Xmax = readSBits (f, rect->Nbits);
82   rect->Ymin = readSBits (f, rect->Nbits);
83   rect->Ymax = readSBits (f, rect->Nbits);
84 }
85 
86 void
parseSWF_MATRIX(FILE * f,struct SWF_MATRIX * matrix)87 parseSWF_MATRIX (FILE * f, struct SWF_MATRIX *matrix)
88 {
89   byteAlign ();
90 
91   matrix->HasScale = readBits (f, 1);
92   if (matrix->HasScale)
93     {
94       matrix->NScaleBits = readBits (f, 5);
95       matrix->ScaleX = (float) readSBits (f, matrix->NScaleBits) / 0x10000;
96       matrix->ScaleY = (float) readSBits (f, matrix->NScaleBits) / 0x10000;
97     }
98   matrix->HasRotate = readBits (f, 1);
99   if (matrix->HasRotate)
100     {
101       matrix->NRotateBits = readBits (f, 5);
102       matrix->RotateSkew0 =
103 	(float) readSBits (f, matrix->NRotateBits) / 0x10000;
104       matrix->RotateSkew1 =
105 	(float) readSBits (f, matrix->NRotateBits) / 0x10000;
106     }
107   matrix->NTranslateBits = readBits (f, 5);
108   matrix->TranslateX = readSBits (f, matrix->NTranslateBits);
109   matrix->TranslateY = readSBits (f, matrix->NTranslateBits);
110   byteAlign();
111 }
112 
113 void
114 parseSWF_FILTERLIST(FILE *f, SWF_FILTERLIST *list);
115 
116 int
parseSWF_BUTTONRECORD(FILE * f,struct SWF_BUTTONRECORD * brec,int level)117 parseSWF_BUTTONRECORD (FILE * f, struct SWF_BUTTONRECORD *brec, int level)
118 {
119   byteAlign ();
120 
121   brec->ButtonReserved = readBits (f, 2);
122   brec->ButtonHasBlendMode = readBits(f, 1);
123   brec->ButtonHasFilterList = readBits(f, 1);
124   brec->ButtonStateHitTest = readBits (f, 1);
125   brec->ButtonStateDown = readBits (f, 1);
126   brec->ButtonStateOver = readBits (f, 1);
127   brec->ButtonStateUp = readBits (f, 1);
128   if( brec->ButtonStateHitTest == 0 &&
129       brec->ButtonStateDown == 0 &&
130       brec->ButtonStateOver == 0 &&
131       brec->ButtonStateUp == 0 &&
132       brec->ButtonHasBlendMode == 0 &&
133       brec->ButtonHasFilterList == 0 &&
134       brec->ButtonReserved == 0)
135 	  return 0;  // CharacterEndFlag
136   brec->CharacterId = readUInt16 (f);
137   brec->PlaceDepth = readUInt16 (f);
138   parseSWF_MATRIX (f, &brec->PlaceMatrix);
139   if( level > 1 )
140   	parseSWF_CXFORMWITHALPHA (f, &brec->ColorTransform);
141   if ( brec->ButtonHasFilterList )
142 	parseSWF_FILTERLIST(f, &brec->FilterList);
143   if ( brec->ButtonHasBlendMode )
144 	brec->BlendMode = readUInt8(f);
145   return 1;
146 }
147 
148 int
parseSWF_BUTTONCONDACTION(FILE * f,struct SWF_BUTTONCONDACTION * bcarec,int end)149 parseSWF_BUTTONCONDACTION (FILE * f, struct SWF_BUTTONCONDACTION *bcarec, int end)
150 {
151   int actionEnd, start;
152   byteAlign ();
153 
154   start = fileOffset;
155   bcarec->CondActionSize = readUInt16 (f);
156   bcarec->CondIdleToOverDown = readBits (f, 1);
157   bcarec->CondOutDownToIdle = readBits (f, 1);
158   bcarec->CondOutDownToOverDown = readBits (f, 1);
159   bcarec->CondOverDownToOutDown = readBits (f, 1);
160   bcarec->CondOverDownToOverUp = readBits (f, 1);
161   bcarec->CondOverUpToOverDown = readBits (f, 1);
162   bcarec->CondOverUpToIdle = readBits (f, 1);
163   bcarec->CondIdleToOverUp = readBits (f, 1);
164   bcarec->CondKeyPress = readBits (f, 7);
165   bcarec->CondOverDownToIdle = readBits (f, 1);
166 
167   bcarec->Actions =
168     (SWF_ACTION *) calloc (1, sizeof (SWF_ACTION));
169   bcarec->numActions = 0;
170   while ( parseSWF_ACTIONRECORD (f, &(bcarec->numActions), bcarec->Actions) ) {
171       bcarec->Actions = (SWF_ACTION *) realloc (bcarec->Actions,
172 							 (++bcarec->
173 							  numActions +
174 							  1) *
175 							 sizeof
176 							 (SWF_ACTION));
177     }
178 
179   if(bcarec->CondActionSize > 0)
180 	actionEnd = start + bcarec->CondActionSize;
181   else
182 	actionEnd = end;
183 
184   if(fileOffset >= actionEnd)
185   {
186 	SWF_warn("parseSWF_BUTTONCONDACTION: expected actionEnd flag\n");
187   	return bcarec->CondActionSize;
188   }
189 
190   /* read end action flag only there are realy action records
191    * if there are no actionrecords parseSWF_ACTIONRECORD did already
192    * read end action
193    */
194   if(bcarec->numActions > 0)
195     readUInt8(f);
196   return bcarec->CondActionSize;
197 }
198 
199 void
parseSWF_CXFORM(FILE * f,struct SWF_CXFORM * cxform)200 parseSWF_CXFORM (FILE * f, struct SWF_CXFORM *cxform)
201 {
202   byteAlign ();
203 
204   cxform->HasAddTerms = readBits (f, 1);
205   cxform->HasMultTerms = readBits (f, 1);
206   cxform->Nbits = readBits (f, 4);
207   if( cxform->HasMultTerms ) {
208     cxform->RedMultTerm = readSBits(f, cxform->Nbits );
209     cxform->GreenMultTerm = readSBits(f, cxform->Nbits );
210     cxform->BlueMultTerm = readSBits(f, cxform->Nbits );
211   }
212   if( cxform->HasAddTerms ) {
213     cxform->RedAddTerm = readSBits(f, cxform->Nbits );
214     cxform->GreenAddTerm = readSBits(f, cxform->Nbits );
215     cxform->BlueAddTerm = readSBits(f, cxform->Nbits );
216   }
217 }
218 
219 void
parseSWF_CXFORMWITHALPHA(FILE * f,struct SWF_CXFORMWITHALPHA * cxform)220 parseSWF_CXFORMWITHALPHA (FILE * f, struct SWF_CXFORMWITHALPHA *cxform)
221 {
222   byteAlign ();
223 
224   cxform->HasAddTerms = readBits (f, 1);
225   cxform->HasMultTerms = readBits (f, 1);
226   cxform->Nbits = readBits (f, 4);
227   if( cxform->HasMultTerms ) {
228     cxform->RedMultTerm = readSBits(f, cxform->Nbits );
229     cxform->GreenMultTerm = readSBits(f, cxform->Nbits );
230     cxform->BlueMultTerm = readSBits(f, cxform->Nbits );
231     cxform->AlphaMultTerm = readSBits(f, cxform->Nbits );
232   }
233   if( cxform->HasAddTerms ) {
234     cxform->RedAddTerm = readSBits(f, cxform->Nbits );
235     cxform->GreenAddTerm = readSBits(f, cxform->Nbits );
236     cxform->BlueAddTerm = readSBits(f, cxform->Nbits );
237     cxform->AlphaAddTerm = readSBits(f, cxform->Nbits );
238   }
239 }
240 
241 void
parseSWF_GLYPHENTRY(FILE * f,SWF_GLYPHENTRY * gerec,int glyphbits,int advancebits)242 parseSWF_GLYPHENTRY (FILE * f, SWF_GLYPHENTRY *gerec, int glyphbits, int advancebits)
243 {
244   unsigned int i;
245 
246   size_t nmalloc = ( glyphbits < 1 ? 1 : ((glyphbits+31)/32) ) * sizeof(UI32);
247   gerec->GlyphIndex = malloc(nmalloc);
248   gerec->GlyphIndex[0] = 0; /* for glyphbits == 0 */
249   for( i=0; glyphbits; i++ ) {
250     if (i < (nmalloc / sizeof(UI32))) {
251 	  if( glyphbits > 32 ) {
252 	  	gerec->GlyphIndex[i] = readBits(f, 32);
253 	  	glyphbits -= 32;
254   	} else {
255 	 	gerec->GlyphIndex[i] = readBits(f, glyphbits);
256 	 	glyphbits = 0;
257   	}
258     } else {
259       SWF_error("unexpected end of file");
260     }
261   }
262 
263   nmalloc = ( advancebits < 1 ? 1 : ((advancebits+31)/32) ) * sizeof(UI32);
264   gerec->GlyphAdvance = malloc(nmalloc);
265   gerec->GlyphAdvance[0] = 0; /* for advancebits == 0 */
266   for( i=0; advancebits; i++ ) {
267     if (i < (nmalloc / sizeof(UI32))) {
268 	  if( advancebits > 32 ) {
269 	  	gerec->GlyphAdvance[i] = readBits(f, 32);
270 	  	advancebits -= 32;
271   	} else {
272 	 	gerec->GlyphAdvance[i] = readBits(f, advancebits);
273 	 	advancebits = 0;
274   	}
275     } else {
276       SWF_error("unexpected end of file");
277     }
278   }
279 }
280 
281 int
parseSWF_TEXTRECORD(FILE * f,struct SWF_TEXTRECORD * brec,int glyphbits,int advancebits,int level)282 parseSWF_TEXTRECORD (FILE * f, struct SWF_TEXTRECORD *brec, int glyphbits, int advancebits, int level)
283 {
284   int i, glyph_count;
285 
286   byteAlign ();
287 
288   brec->TextRecordType = readBits (f, 1);
289   brec->StyleFlagsReserved = readBits (f, 3);
290   brec->StyleFlagHasFont = readBits (f, 1);
291   brec->StyleFlagHasColor = readBits (f, 1);
292   brec->StyleFlagHasYOffset = readBits (f, 1);
293   brec->StyleFlagHasXOffset = readBits (f, 1);
294   if( brec->TextRecordType == 0 )
295 	  return 0;
296   if( brec->StyleFlagHasFont )
297     brec->FontID = readUInt16 (f);
298   if( brec->StyleFlagHasColor ) {
299     if( level > 1 )
300 	    parseSWF_RGBA(f, &brec->TextColor );
301     else
302 	    parseSWF_RGB(f, &brec->TextColor );
303   }
304   if( brec->StyleFlagHasXOffset )
305     brec->XOffset = readSInt16 (f);
306   if( brec->StyleFlagHasYOffset )
307     brec->YOffset = readSInt16 (f);
308   if( brec->StyleFlagHasFont )
309     brec->TextHeight = readUInt16 (f);
310   glyph_count = readUInt8 (f);
311   if (glyph_count == EOF) {
312     SWF_error("unexpected end of file");
313     return 0;
314   } else {
315     brec->GlyphCount = glyph_count;
316     brec->GlyphEntries = malloc(brec->GlyphCount * sizeof(SWF_GLYPHENTRY) );
317     byteAlign ();
318     for(i=0;i<brec->GlyphCount;i++)
319             parseSWF_GLYPHENTRY(f, &(brec->GlyphEntries[i]), glyphbits, advancebits );
320 
321     return 1;
322   }
323 }
324 
325 int
parseSWF_CLIPEVENTFLAGS(FILE * f,struct SWF_CLIPEVENTFLAGS * cflags)326 parseSWF_CLIPEVENTFLAGS (FILE * f, struct SWF_CLIPEVENTFLAGS *cflags)
327 {
328   byteAlign ();
329 
330   cflags->ClipEventKeyUp = readBits (f, 1);
331   cflags->ClipEventKeyDown = readBits (f, 1);
332   cflags->ClipEventMouseUp = readBits (f, 1);
333   cflags->ClipEventMouseDown = readBits (f, 1);
334   cflags->ClipEventMouseMove = readBits (f, 1);
335   cflags->ClipEventUnload = readBits (f, 1);
336   cflags->ClipEventEnterFrame = readBits (f, 1);
337   cflags->ClipEventLoad = readBits (f, 1);
338   cflags->ClipEventDragOver = readBits (f, 1);
339   cflags->ClipEventRollOut = readBits (f, 1);
340   cflags->ClipEventRollOver = readBits (f, 1);
341   cflags->ClipEventReleaseOutside = readBits (f, 1);
342   cflags->ClipEventRelease = readBits (f, 1);
343   cflags->ClipEventPress = readBits (f, 1);
344   cflags->ClipEventInitialize = readBits (f, 1);
345   cflags->ClipEventData = readBits (f, 1);
346   if( m.version >= 6 ) {
347     cflags->Reserved = readBits (f, 5);
348     cflags->ClipEventConstruct = readBits (f, 1);
349     cflags->ClipEventKeyPress = readBits (f, 1);
350     cflags->ClipEventDragOut = readBits (f, 1);
351     cflags->Reserved2 = readBits (f, 8);
352   } else {
353     cflags->Reserved = 0;
354     cflags->ClipEventConstruct = 0;
355     cflags->ClipEventKeyPress = 0;
356     cflags->ClipEventDragOut = 0;
357     cflags->Reserved2 = 0;
358   }
359 
360 
361   return cflags->ClipEventKeyUp|cflags->ClipEventKeyDown|cflags->ClipEventMouseUp|cflags->ClipEventMouseDown|cflags->ClipEventMouseMove|cflags->ClipEventUnload|cflags->ClipEventEnterFrame|cflags->ClipEventLoad|cflags->ClipEventDragOver|cflags->ClipEventRollOut|cflags->ClipEventRollOver|cflags->ClipEventReleaseOutside|cflags->ClipEventRelease|cflags->ClipEventPress|cflags->ClipEventInitialize|cflags->ClipEventData|cflags->ClipEventConstruct|cflags->ClipEventKeyPress|cflags->ClipEventDragOut;
362 }
363 
364 int
parseSWF_CLIPACTIONRECORD(FILE * f,struct SWF_CLIPACTIONRECORD * carec)365 parseSWF_CLIPACTIONRECORD (FILE * f, struct SWF_CLIPACTIONRECORD *carec)
366 {
367   int length,end;
368   byteAlign ();
369 
370   if( parseSWF_CLIPEVENTFLAGS( f, &(carec->EventFlag) ) == 0 )
371 	  return 0;
372   carec->ActionRecordSize = readUInt32 (f);
373   if( carec->EventFlag.ClipEventKeyPress ) {
374   	carec->KeyCode = readUInt8 (f);
375 	length = carec->ActionRecordSize-1;
376   } else {
377 	length = carec->ActionRecordSize;
378   }
379   end = fileOffset + length;
380   /* carec->Actions = decompile5Action (f, length, 1); */
381   carec->Actions =
382     (SWF_ACTION *) calloc (1, sizeof (SWF_ACTION));
383   carec->numActions = 0;
384 
385   while ( fileOffset < end ) {
386       parseSWF_ACTIONRECORD (f, &(carec->numActions), carec->Actions);
387       carec->Actions = (SWF_ACTION *) realloc (carec->Actions,
388 							 (++carec->
389 							  numActions +
390 							  1) *
391 							 sizeof
392 							 (SWF_ACTION));
393     }
394 
395   return 1;
396 }
397 
398 void
parseSWF_CLIPACTIONS(FILE * f,struct SWF_CLIPACTIONS * clipact,int end)399 parseSWF_CLIPACTIONS (FILE * f, struct SWF_CLIPACTIONS *clipact, int end)
400 {
401   byteAlign ();
402   clipact->Reserved = readUInt16 (f);
403   parseSWF_CLIPEVENTFLAGS( f, &(clipact->AllEventFlags) );
404 
405   clipact->ClipActionRecords =
406     (SWF_CLIPACTIONRECORD *) calloc (1, sizeof (SWF_CLIPACTIONRECORD));
407   clipact->NumClipRecords = 0;
408   while (parseSWF_CLIPACTIONRECORD
409 	 (f, &(clipact->ClipActionRecords[clipact->NumClipRecords++]) ) )
410   {
411     if(fileOffset >= end)
412       return;
413     clipact->ClipActionRecords = (SWF_CLIPACTIONRECORD *) realloc (clipact->ClipActionRecords,
414 							 (clipact->
415 							  NumClipRecords +
416 							  1) *
417 							 sizeof
418 							 (SWF_CLIPACTIONRECORD));
419   }
420   clipact->ClipActionEndFlag = readUInt16(f);
421 }
422 
423 void
parseSWF_GRADIENTRECORD(FILE * f,struct SWF_GRADIENTRECORD * gradientrec,int level)424 parseSWF_GRADIENTRECORD (FILE * f, struct SWF_GRADIENTRECORD *gradientrec, int level)
425 {
426   gradientrec->Ratio = readUInt8 (f);
427   if (level < 3)
428      parseSWF_RGB (f, &gradientrec->Color);
429   else
430      parseSWF_RGBA (f, &gradientrec->Color);
431 }
432 
433 void
parseSWF_FOCALGRADIENT(FILE * f,struct SWF_FOCALGRADIENT * gradient,int level)434 parseSWF_FOCALGRADIENT (FILE * f, struct SWF_FOCALGRADIENT *gradient, int level)
435 {
436   int i;
437   gradient->SpreadMode = readBits(f, 2);
438   gradient->InterpolationMode = readBits(f, 2);
439   gradient->NumGradients = readBits (f, 4);
440   if(gradient->NumGradients > 15) {
441 	  fprintf(stderr, "%d gradients in SWF_FOCALGRADIENT, expected a max of 15\n", gradient->NumGradients );
442 	  gradient->NumGradients = 15;
443 	  /*exit(1);*/
444   }
445 
446   for (i = 0; i < gradient->NumGradients; i++)
447     parseSWF_GRADIENTRECORD (f, &(gradient->GradientRecords[i]), level);
448 
449   gradient->FocalPoint = readUInt16(f);
450 }
451 
452 void
parseSWF_GRADIENT(FILE * f,struct SWF_GRADIENT * gradient,int level)453 parseSWF_GRADIENT (FILE * f, struct SWF_GRADIENT *gradient, int level)
454 {
455   int i;
456   gradient->SpreadMode = readBits(f, 2);
457   gradient->InterpolationMode = readBits(f, 2);
458   gradient->NumGradients = readBits (f, 4);
459   if((gradient->NumGradients > 8  && level < 4) || (gradient->NumGradients > 15  && level == 4)) {
460 	  fprintf(stderr, "%d gradients in SWF_GRADiENT, expected a max of %d\n", gradient->NumGradients, level<4 ? 8 : 15 );
461 	  gradient->NumGradients = 8;
462   }
463 
464   for (i = 0; i < gradient->NumGradients; i++)
465     parseSWF_GRADIENTRECORD (f, &(gradient->GradientRecords[i]), level);
466 }
467 
468 int
parseSWF_SHAPERECORD(FILE * f,SWF_SHAPERECORD * shape,int * fillBits,int * lineBits,int level)469 parseSWF_SHAPERECORD (FILE * f, SWF_SHAPERECORD * shape, int *fillBits,
470 		      int *lineBits, int level)
471 {
472   UI16 tmpbits;
473   memset (shape, 0, sizeof (SWF_SHAPERECORD));
474   shape->EndShape.TypeFlag = readBits (f, 1);
475   if (shape->EndShape.TypeFlag)
476     {
477       /* An Edge Record */
478       shape->StraightEdge.StraightEdge = readBits (f, 1);
479       if (shape->StraightEdge.StraightEdge == 1)
480 	{
481 	  /* A Straight Edge Record */
482 	  shape->StraightEdge.NumBits = readBits (f, 4);
483 	  shape->StraightEdge.GeneralLineFlag = readBits (f, 1);
484 	  if (shape->StraightEdge.GeneralLineFlag)
485 	    {
486 	      shape->StraightEdge.DeltaX =
487 		readSBits (f, shape->StraightEdge.NumBits + 2);
488 	      shape->StraightEdge.DeltaY =
489 		readSBits (f, shape->StraightEdge.NumBits + 2);
490 	    }
491 	  else
492 	    {
493 	      shape->StraightEdge.VertLineFlag = readBits (f, 1);
494 	      if (shape->StraightEdge.VertLineFlag)
495 		{
496 		  shape->StraightEdge.VLDeltaY =
497 		    readSBits (f, shape->StraightEdge.NumBits + 2);
498 		}
499 	      else
500 		{
501 		  shape->StraightEdge.VLDeltaX =
502 		    readSBits (f, shape->StraightEdge.NumBits + 2);
503 		}
504 	    }
505 	}
506       else
507 	{
508 	  /* A Curved Edge Record */
509 	  shape->CurvedEdge.NumBits = readBits (f, 4);
510 	  shape->CurvedEdge.ControlDeltaX =
511 	    readSBits (f, shape->CurvedEdge.NumBits + 2);
512 	  shape->CurvedEdge.ControlDeltaY =
513 	    readSBits (f, shape->CurvedEdge.NumBits + 2);
514 	  shape->CurvedEdge.AnchorDeltaX =
515 	    readSBits (f, shape->CurvedEdge.NumBits + 2);
516 	  shape->CurvedEdge.AnchorDeltaY =
517 	    readSBits (f, shape->CurvedEdge.NumBits + 2);
518 	}
519     }
520   else
521     {
522       /* A Non-Edge Record */
523       tmpbits = readBits (f, 5);
524       if (tmpbits == 0)
525 	{
526 	  /* EndShapeRecord */
527 	  shape->EndShape.EndOfShape = 0;
528 	  return 0;
529 	}
530       /* StyleChangeRecord - ie one or more of the next 5 bits are set */
531 
532       if (tmpbits & (1 << 4))
533 	shape->StyleChange.StateNewStyles = 1;
534       if (tmpbits & (1 << 3))
535 	shape->StyleChange.StateLineStyle = 1;
536       if (tmpbits & (1 << 2))
537 	shape->StyleChange.StateFillStyle1 = 1;
538       if (tmpbits & (1 << 1))
539 	shape->StyleChange.StateFillStyle0 = 1;
540       if (tmpbits & (1 << 0))
541 	shape->StyleChange.StateMoveTo = 1;
542 
543       if (shape->StyleChange.StateMoveTo)
544 	{
545 	  shape->StyleChange.MoveBits = readBits (f, 5);
546 	  shape->StyleChange.MoveDeltaX =
547 	    readSBits (f, shape->StyleChange.MoveBits);
548 	  shape->StyleChange.MoveDeltaY =
549 	    readSBits (f, shape->StyleChange.MoveBits);
550 	}
551       if (shape->StyleChange.StateFillStyle0)
552 	{
553 	  shape->StyleChange.FillStyle0 = readBits (f, *fillBits);
554 	}
555       if (shape->StyleChange.StateFillStyle1)
556 	{
557 	  shape->StyleChange.FillStyle1 = readBits (f, *fillBits);
558 	}
559       if (shape->StyleChange.StateLineStyle)
560 	{
561 	  shape->StyleChange.LineStyle = readBits (f, *lineBits);
562 	}
563       if (shape->StyleChange.StateNewStyles)
564 	{
565 	  parseSWF_FILLSTYLEARRAY (f, &(shape->StyleChange.FillStyles),
566 				   level);
567 	  parseSWF_LINESTYLEARRAY (f, &(shape->StyleChange.LineStyles),
568 				   level);
569 	  shape->StyleChange.NumFillBits = *fillBits = readBits (f, 4);
570 	  shape->StyleChange.NumLineBits = *lineBits = readBits (f, 4);
571 	}
572 
573     }
574   return 1;
575 }
576 
577 void
parseSWF_FILLSTYLE(FILE * f,SWF_FILLSTYLE * fillstyle,int level)578 parseSWF_FILLSTYLE (FILE * f, SWF_FILLSTYLE * fillstyle, int level)
579 {
580   fillstyle->FillStyleType = readUInt8 (f);
581   switch (fillstyle->FillStyleType)
582     {
583     case 0x00:			/* Solid Fill */
584       if (level < 3)
585 	parseSWF_RGB (f, &fillstyle->Color);
586       else
587 	parseSWF_RGBA (f, &fillstyle->Color);
588       break;
589     case 0x10:			/* Linear Gradient Fill */
590     case 0x12:			/* Radial Gradient Fill */
591       parseSWF_MATRIX (f, &fillstyle->GradientMatrix);
592       parseSWF_GRADIENT (f, &fillstyle->Gradient, level);
593       break;
594     case 0x13:
595       parseSWF_MATRIX (f, &fillstyle->GradientMatrix);
596       parseSWF_FOCALGRADIENT(f, &fillstyle->FocalGradient, level);
597       break;
598     case 0x40:			/* Repeating Bitmap Fill */
599     case 0x41:			/* Clipped Bitmap Fill */
600     case 0x42:			/* Non-smoothed Repeating Bitmap Fill */
601     case 0x43:			/* Non-smoothed Clipped Bitmap Fill */
602       fillstyle->BitmapId = readUInt16 (f);
603       parseSWF_MATRIX (f, &fillstyle->BitmapMatrix);
604       break;
605     }
606 }
607 
608 void
parseSWF_FILLSTYLEARRAY(FILE * f,SWF_FILLSTYLEARRAY * fillstyle,int level)609 parseSWF_FILLSTYLEARRAY (FILE * f, SWF_FILLSTYLEARRAY * fillstyle, int level)
610 {
611   int count, i;
612   fillstyle->FillStyleCount = readUInt8 (f);
613   count = fillstyle->FillStyleCount;
614   if (fillstyle->FillStyleCount == 0xff)
615     {
616       fillstyle->FillStyleCountExtended = readUInt16 (f);
617       count = fillstyle->FillStyleCountExtended;
618     }
619   fillstyle->FillStyles =
620     (SWF_FILLSTYLE *) calloc (count, sizeof (SWF_FILLSTYLE));
621   for (i = 0; i < count; i++)
622     {
623       parseSWF_FILLSTYLE (f, &(fillstyle->FillStyles[i]), level);
624     }
625 }
626 
627 void
parseSWF_LINESTYLE(FILE * f,SWF_LINESTYLE * linestyle,int level)628 parseSWF_LINESTYLE (FILE * f, SWF_LINESTYLE * linestyle, int level)
629 {
630   linestyle->Width = readUInt16 (f);
631   if (level < 3)
632     parseSWF_RGB (f, &linestyle->Color);
633   else
634     parseSWF_RGBA (f, &linestyle->Color);
635 }
636 
637 void
parseSWF_LINESTYLE2(FILE * f,SWF_LINESTYLE2 * linestyle2,int level)638 parseSWF_LINESTYLE2 (FILE *f, SWF_LINESTYLE2 *linestyle2, int level)
639 {
640   linestyle2->Width = readUInt16(f);
641   linestyle2->StartCapStyle = readBits(f, 2);
642   linestyle2->JoinStyle = readBits(f, 2);
643   linestyle2->HasFillFlag = readBits(f, 1);
644   linestyle2->NoHScaleFlag = readBits(f, 1);
645   linestyle2->NoVScaleFlag = readBits(f, 1);
646   linestyle2->PixelHintingFlag = readBits(f, 1);
647   linestyle2->Reserved = readBits(f, 5);
648   linestyle2->NoClose = readBits(f, 1);
649   linestyle2->EndCapStyle = readBits(f, 2);
650   if(linestyle2->JoinStyle == 2)
651 	linestyle2->MiterLimitFactor = readUInt16(f);
652   if(linestyle2->HasFillFlag == 0)
653 	parseSWF_RGBA (f, &linestyle2->Color);
654   else
655 	parseSWF_FILLSTYLE(f, &linestyle2->FillType, level);
656 }
657 
658 void
parseSWF_LINESTYLEARRAY(FILE * f,SWF_LINESTYLEARRAY * linestyle,int level)659 parseSWF_LINESTYLEARRAY (FILE * f, SWF_LINESTYLEARRAY * linestyle, int level)
660 {
661   int count, i;
662 
663   count = readUInt8 (f);
664   if (count == 0xff)
665     {
666       count = readUInt16(f);
667     }
668   if (count == EOF)
669   {
670     SWF_error("unexpected end of file");
671   }
672 
673   linestyle->LineStyleCount = count;
674 
675   if(level == 4)
676   {
677     linestyle->LineStyles = NULL;
678     linestyle->LineStyles2 =
679       (SWF_LINESTYLE2 *) malloc (count * sizeof (SWF_LINESTYLE2));
680   }
681   else
682   {
683     linestyle->LineStyles =
684       (SWF_LINESTYLE *) malloc (count * sizeof (SWF_LINESTYLE));
685     linestyle->LineStyles2 = NULL;
686   }
687 
688   for (i = 0; i < count; i++)
689   {
690     if(level == 4)
691       parseSWF_LINESTYLE2 (f, &(linestyle->LineStyles2[i]), level);
692     else
693       parseSWF_LINESTYLE (f, &(linestyle->LineStyles[i]), level);
694   }
695 }
696 
697 void
parseSWF_MORPHLINESTYLE(FILE * f,SWF_MORPHLINESTYLE * linestyle)698 parseSWF_MORPHLINESTYLE (FILE * f, SWF_MORPHLINESTYLE * linestyle)
699 {
700   linestyle->StartWidth = readUInt16 (f);
701   linestyle->EndWidth = readUInt16 (f);
702   parseSWF_RGBA (f, &linestyle->StartColor);
703   parseSWF_RGBA (f, &linestyle->EndColor);
704 }
705 
706 void
707 parseSWF_MORPHFILLSTYLE (FILE * f, SWF_MORPHFILLSTYLE * fillstyle );
708 void
parseSWF_MORPHLINESTYLE2(FILE * f,SWF_MORPHLINESTYLE2 * linestyle2)709 parseSWF_MORPHLINESTYLE2 (FILE * f, SWF_MORPHLINESTYLE2 * linestyle2)
710 {
711   linestyle2->StartWidth = readUInt16 (f);
712   linestyle2->EndWidth = readUInt16 (f);
713   linestyle2->StartCapStyle = readBits(f, 2);
714   linestyle2->JoinStyle = readBits(f, 2);
715   linestyle2->HasFillFlag = readBits(f, 1);
716   linestyle2->NoHScaleFlag = readBits(f, 1);
717   linestyle2->NoVScaleFlag = readBits(f, 1);
718   linestyle2->PixelHintingFlag = readBits(f, 1);
719   linestyle2->Reserved = readBits(f, 5);
720   linestyle2->NoClose = readBits(f, 1);
721   linestyle2->EndCapStyle = readBits(f, 2);
722   if(linestyle2->JoinStyle == 2)
723 	linestyle2->MiterLimitFactor = readUInt16(f);
724   if(linestyle2->HasFillFlag == 0) {
725   	parseSWF_RGBA (f, &linestyle2->StartColor);
726 	parseSWF_RGBA (f, &linestyle2->EndColor);
727   }
728   else
729 	parseSWF_MORPHFILLSTYLE(f, &linestyle2->FillType);
730 }
731 
732 
733 void
parseSWF_MORPHLINESTYLES(FILE * f,SWF_MORPHLINESTYLES * linestyle,int version)734 parseSWF_MORPHLINESTYLES (FILE * f, SWF_MORPHLINESTYLES * linestyle,
735                           int version)
736 {
737   int count, i;
738 
739   linestyle->LineStyleCount = readUInt8 (f);
740   count = linestyle->LineStyleCount;
741   if (linestyle->LineStyleCount == 0xff)
742     {
743       linestyle->LineStyleCountExtended = readUInt16 (f);
744       count = linestyle->LineStyleCountExtended;
745     }
746   if (count == EOF)
747   {
748     SWF_error("unexpected end of file");
749   }
750   if(version == 1)
751     linestyle->LineStyles =
752       (SWF_MORPHLINESTYLE *) malloc (count * sizeof (SWF_MORPHLINESTYLE));
753   else if(version == 2)
754     linestyle->LineStyles2 =
755       (SWF_MORPHLINESTYLE2 *) malloc (count * sizeof (SWF_MORPHLINESTYLE2));
756 
757   for (i = 0; i < count; i++)
758     {
759       if(version == 1)
760         parseSWF_MORPHLINESTYLE (f, &(linestyle->LineStyles[i]));
761       else if(version == 2)
762         parseSWF_MORPHLINESTYLE2 (f, &(linestyle->LineStyles2[i]));
763       else
764         SWF_error("parseSWF_MORPHLINESTYLES: unknow MORPH version\n");
765     }
766 }
767 
768 void
parseSWF_MORPHGRADIENTRECORD(FILE * f,struct SWF_MORPHGRADIENTRECORD * gradientrec)769 parseSWF_MORPHGRADIENTRECORD (FILE * f, struct SWF_MORPHGRADIENTRECORD *gradientrec)
770 {
771   gradientrec->StartRatio = readUInt8 (f);
772   parseSWF_RGBA (f, &gradientrec->StartColor);
773   gradientrec->EndRatio = readUInt8 (f);
774   parseSWF_RGBA (f, &gradientrec->EndColor);
775 }
776 
777 void
parseSWF_MORPHGRADIENT(FILE * f,struct SWF_MORPHGRADIENT * gradient)778 parseSWF_MORPHGRADIENT (FILE * f, struct SWF_MORPHGRADIENT *gradient)
779 {
780   int i;
781   gradient->NumGradients = readUInt8 (f);
782   if( gradient->NumGradients > 8 ) {
783 	  fprintf(stderr, "%d gradients in SWF_MORPHGRADiENT, expected a max of 8", gradient->NumGradients);
784 	  gradient->NumGradients = 8;
785   }
786   for (i = 0; i < gradient->NumGradients; i++)
787     parseSWF_MORPHGRADIENTRECORD (f, &(gradient->GradientRecords[i]));
788 }
789 void
parseSWF_MORPHFILLSTYLE(FILE * f,SWF_MORPHFILLSTYLE * fillstyle)790 parseSWF_MORPHFILLSTYLE (FILE * f, SWF_MORPHFILLSTYLE * fillstyle )
791 {
792   fillstyle->FillStyleType = readUInt8 (f);
793   switch (fillstyle->FillStyleType)
794     {
795     case 0x00:			/* Solid Fill */
796 	parseSWF_RGBA (f, &fillstyle->StartColor);
797 	parseSWF_RGBA (f, &fillstyle->EndColor);
798       break;
799     case 0x10:			/* Linear Gradient Fill */
800     case 0x12:			/* Radial Gradient Fill */
801       parseSWF_MATRIX (f, &fillstyle->StartGradientMatrix);
802       parseSWF_MATRIX (f, &fillstyle->EndGradientMatrix);
803       parseSWF_MORPHGRADIENT (f, &fillstyle->Gradient);
804       break;
805     case 0x40:			/* Repeating Bitmap Fill */
806     case 0x41:			/* Clipped Bitmap Fill */
807     case 0x42:			/* Non-smoothed Repeating Bitmap Fill */
808     case 0x43:			/* Non-smoothed Clipped Bitmap Fill */
809       fillstyle->BitmapId = readUInt16 (f);
810       parseSWF_MATRIX (f, &fillstyle->StartBitmapMatrix);
811       parseSWF_MATRIX (f, &fillstyle->EndBitmapMatrix);
812       break;
813     }
814 }
815 void
parseSWF_MORPHFILLSTYLES(FILE * f,SWF_MORPHFILLSTYLES * fillstyle)816 parseSWF_MORPHFILLSTYLES (FILE * f, SWF_MORPHFILLSTYLES * fillstyle )
817 {
818   int count, i;
819   fillstyle->FillStyleCount = readUInt8 (f);
820   count = fillstyle->FillStyleCount;
821   if (fillstyle->FillStyleCount == 0xff)
822     {
823       fillstyle->FillStyleCountExtended = readUInt16 (f);
824       count = fillstyle->FillStyleCountExtended;
825     }
826   fillstyle->FillStyles =
827     (SWF_MORPHFILLSTYLE *) calloc (count, sizeof (SWF_MORPHFILLSTYLE));
828   for (i = 0; i < count; i++)
829     {
830       parseSWF_MORPHFILLSTYLE (f, &(fillstyle->FillStyles[i]));
831     }
832 }
833 
834 void
parseSWF_SHAPE(FILE * f,SWF_SHAPE * shape,int level,int len)835 parseSWF_SHAPE (FILE * f, SWF_SHAPE * shape, int level, int len)
836 {
837   int fillBits, lineBits;
838   int end;
839   byteAlign ();
840 
841   end = fileOffset + len;
842   shape->NumFillBits = fillBits = readBits (f, 4);
843   shape->NumLineBits = lineBits = readBits (f, 4);
844   shape->ShapeRecords =
845     (SWF_SHAPERECORD *) calloc (1, sizeof (SWF_SHAPERECORD));
846   shape->NumShapeRecords = 0;
847   while (fileOffset < end)
848   {
849     size_t size;
850     SWF_SHAPERECORD *rec = &(shape->ShapeRecords[shape->NumShapeRecords]);
851     int ret = parseSWF_SHAPERECORD(f, rec, &fillBits, &lineBits, level);
852     if(!ret)
853 	return;
854 
855     shape->NumShapeRecords++;
856     size = (shape->NumShapeRecords + 1) * sizeof(SWF_SHAPERECORD);
857     shape->ShapeRecords = (SWF_SHAPERECORD *)realloc (shape->ShapeRecords, size);
858   }
859 }
860 
861 void
parseSWF_SHAPEWITHSTYLE(FILE * f,SWF_SHAPEWITHSTYLE * shape,int level)862 parseSWF_SHAPEWITHSTYLE (FILE * f, SWF_SHAPEWITHSTYLE * shape, int level)
863 {
864   int fillBits, lineBits;
865   memset (shape, 0, sizeof (SWF_SHAPEWITHSTYLE));
866 
867   parseSWF_FILLSTYLEARRAY (f, &shape->FillStyles, level);
868   parseSWF_LINESTYLEARRAY (f, &shape->LineStyles, level);
869 
870   byteAlign ();
871 
872   shape->NumFillBits = fillBits = readBits (f, 4);
873   shape->NumLineBits = lineBits = readBits (f, 4);
874 
875   shape->ShapeRecords =
876     (SWF_SHAPERECORD *) calloc (1, sizeof (SWF_SHAPERECORD));
877   shape->NumShapeRecords = 0;
878   while (parseSWF_SHAPERECORD
879 	 (f, &(shape->ShapeRecords[shape->NumShapeRecords++]), &fillBits,
880 	  &lineBits, level))
881     {
882       shape->ShapeRecords = (SWF_SHAPERECORD *) realloc (shape->ShapeRecords,
883 							 (shape->
884 							  NumShapeRecords +
885 							  1) *
886 							 sizeof
887 							 (SWF_SHAPERECORD));
888     }
889 }
890 
891 /* Parse Action types */
892 
893 #define ACT_BEGIN(acttype) \
894 	struct acttype *act;\
895 	act=(struct acttype *)action; \
896 	act->Length = readUInt16(f);
897 
898 #define ACT_BEGIN_NOLEN(acttype) \
899 	struct acttype *act;\
900 	act=(struct acttype *)action;
901 
902 int
parseSWF_ACTIONRECORD(FILE * f,int * thisactionp,SWF_ACTION * actions)903 parseSWF_ACTIONRECORD(FILE * f, int *thisactionp, SWF_ACTION *actions)
904 {
905 	int thisaction = *thisactionp;
906 	SWF_ACTION *action = &(actions[thisaction]);
907 
908 	//fprintf(stderr,"ACTION[%d] Offset %d\n", thisaction, fileOffset );
909 
910 	action->SWF_ACTIONRECORD.Offset = fileOffset; /* remember where it came from */
911 	if( (action->SWF_ACTIONRECORD.ActionCode = readUInt8(f)) == SWFACTION_END )
912 		return 0;
913 	/*
914 	 * Actions without the high bit set take no additional
915 	 * arguments, so we are done for these types.
916 	 */
917 	if( !(action->SWF_ACTIONRECORD.ActionCode&0x80) ) {
918 		action->SWF_ACTIONRECORD.Length = 1; /* Fill in the size for later use */
919 		return 1;
920 	}
921 
922 	action->SWF_ACTIONRECORD.Length = 0; /* make valgrind happy */
923 	/*
924 	 * Actions with the high bit set take additional
925 	 * arguments, so we have to parse each one uniquely.
926 	 */
927 	switch( action->SWF_ACTIONRECORD.ActionCode ) {
928 		/* v3 actions */
929 	case SWFACTION_GOTOFRAME:
930 		{
931 		ACT_BEGIN(SWF_ACTIONGOTOFRAME)
932 		act->Frame = readUInt16(f);
933 		break;
934 		}
935 	case SWFACTION_GETURL:
936 		{
937 		ACT_BEGIN(SWF_ACTIONGETURL)
938 		act->UrlString = readString(f);
939 		act->TargetString = readString(f);
940 		break;
941 		}
942 	case SWFACTION_WAITFORFRAME:
943 		{
944 		ACT_BEGIN(SWF_ACTIONWAITFORFRAME)
945 		act->Frame = readUInt16(f);
946 		act->SkipCount = readUInt8(f);
947 		break;
948 		}
949 	case SWFACTION_SETTARGET:
950 		{
951 		ACT_BEGIN(SWF_ACTIONSETTARGET)
952 		act->TargetName = readString(f);
953 		break;
954 		}
955 	case SWFACTION_GOTOLABEL:
956 		{
957 		ACT_BEGIN(SWF_ACTIONGOTOLABEL)
958 		act->FrameLabel = readString(f);
959 		break;
960 		}
961 
962 
963 		/* v4 actions */
964 	case SWFACTION_PUSH:
965 		{
966 		int end;
967 		struct SWF_ACTIONPUSHPARAM *param;
968 		ACT_BEGIN(SWF_ACTIONPUSH)
969 
970 		end = fileOffset + act->Length;
971   		act->Params = (struct SWF_ACTIONPUSHPARAM *) calloc (1, sizeof (struct SWF_ACTIONPUSHPARAM));
972   		act->NumParam = 0;
973   		while ( fileOffset < end ) {
974 			param = &(act->Params[act->NumParam++]);
975 			param->Type = readUInt8(f);
976 			switch( param->Type ) {
977 			case 0: /* STRING */
978 				param->p.String = readString(f);
979 				break;
980 			case 1: /* FLOAT */
981 				param->p.Float = readFloat(f);
982 				break;
983 			case 2: /* NULL */
984 			case 3: /* Undefined */
985 				break;
986 			case 4: /* Register */
987 				param->p.RegisterNumber = readUInt8(f);
988 				break;
989 			case 5: /* BOOLEAN */
990 				param->p.Boolean = readUInt8(f);
991 				break;
992 			case 6: /* DOUBLE */
993 				param->p.Double = readDouble(f);
994 				break;
995 			case 7: /* INTEGER */
996 				param->p.Integer = readSInt32(f);
997 				break;
998 			case 8: /* CONSTANT8 */
999 				param->p.Constant8 = readUInt8(f);
1000 				break;
1001 			case 9: /* CONSTANT16 */
1002 				param->p.Constant16 = readUInt16(f);
1003 				break;
1004 			default:
1005 				printf("Unknown data type to push %x\n", param->Type );
1006 				exit(1);
1007 			}
1008       			act->Params = (struct SWF_ACTIONPUSHPARAM *) realloc (act->Params,
1009 							 (act->NumParam + 1) *
1010 							 sizeof (struct SWF_ACTIONPUSHPARAM));
1011     		}
1012 		break;
1013 		}
1014 	case SWFACTION_LOGICALNOT:
1015 		{
1016 		ACT_BEGIN_NOLEN(SWF_ACTIONNOT)
1017 		act->Boolean = readUInt32(f);
1018 		fprintf(stderr,"NOT param: %d\n", act->Boolean );
1019 		break;
1020 		}
1021 	case SWFACTION_CALLFRAME:
1022 		{
1023 		ACT_BEGIN(SWF_ACTIONCALL)
1024 		// readUInt16(f);		/* seems to be an exception: NO reading here */
1025 		break;
1026 		}
1027 	case SWFACTION_JUMP:
1028 		{
1029 		ACT_BEGIN(SWF_ACTIONJUMP)
1030 		act->BranchOffset = readUInt16(f);
1031 		break;
1032 		}
1033 	case SWFACTION_IF:
1034 		{
1035 		int i,j,k, curroffset;
1036 		ACT_BEGIN(SWF_ACTIONIF)
1037 
1038 		act->BranchOffset = readUInt16(f);
1039 		/*
1040 		 * Set curroffset to point to the next action so that an
1041 		 * offset of zero matches it.
1042 		 */
1043 		curroffset=(action->SWF_ACTIONRECORD.Offset-actions[0].SWF_ACTIONRECORD.Offset)+
1044 			    action->SWF_ACTIONRECORD.Length+3; /* Action + Length bytes not included in the length */
1045 		if( act->BranchOffset < 0 ) {
1046 			/*
1047 			 * We are branching to records that we already have in the array. Just
1048 			 * allocate new space for the if clause, and copy the records there, and then
1049 			 * fix the count of records in actions[], and put this record at the new
1050 			 * end of actions[].
1051 			 */
1052 		    for(i=0;i<=thisaction;i++) {
1053 			if( (actions[i].SWF_ACTIONRECORD.Offset-actions[0].SWF_ACTIONRECORD.Offset) == curroffset+act->BranchOffset ) break;
1054 		    }
1055 		    if( i>=thisaction ) {
1056                             SWF_warn("Failed to find branch target!!!\n");
1057                             SWF_warn("Looking for: %d\n\n", curroffset + act->BranchOffset);
1058                             act->BranchOffset=0;	/* despite the problem ..*/
1059                             i=thisaction;		/* ..continue with empty block */
1060 		    }
1061 		    act->numActions = thisaction-i;
1062 		    act->Actions = (union SWF_ACTION *) calloc (act->numActions, sizeof (SWF_ACTION));
1063 		    for(j=i,k=0;j<thisaction;j++,k++)
1064 			    act->Actions[k] = actions[j];
1065 		    actions[i]=*((SWF_ACTION *)act);	/* added by ak,2006 */
1066 		    *thisactionp = i;
1067 		} else {
1068 			/*
1069 			 * We are branching to records not yet parsed. Just handle this in the
1070 			 * same manner used for with, try, etc.
1071 			 */
1072 		    act->Actions = (union SWF_ACTION *) calloc (1, sizeof (SWF_ACTION));
1073 		    act->numActions = 0;
1074 		    while ( (fileOffset-actions[0].SWF_ACTIONRECORD.Offset) < curroffset+act->BranchOffset ) {
1075 			parseSWF_ACTIONRECORD (f, &(act->numActions), (SWF_ACTION *)act->Actions);
1076 			act->Actions = (union SWF_ACTION *) realloc (act->Actions,
1077 							 (++act->numActions + 1) *
1078 							 sizeof (SWF_ACTION));
1079 		    }
1080 		}
1081 		break;
1082 		}
1083 	case SWFACTION_GETURL2:
1084 		{
1085 		ACT_BEGIN(SWF_ACTIONGETURL2)
1086 		// act->f.Flags = readUInt8(f);
1087 		act->f.FlagBits.LoadTargetFlag = readBits(f,1);
1088 		act->f.FlagBits.LoadVariableFlag = readBits(f,1);
1089 		act->f.FlagBits.Reserved = readBits(f,4);
1090 		act->f.FlagBits.SendVarsMethod = readBits(f,2);
1091 		break;
1092 		}
1093 	case SWFACTION_GOTOFRAME2:
1094 		{
1095 		ACT_BEGIN(SWF_ACTIONGOTOFRAME2)
1096 		act->f.FlagBits.Reserved = readBits(f,6);
1097 		act->f.FlagBits.SceneBiasFlag = readBits(f,1);
1098 		act->f.FlagBits.PlayFlag = readBits(f,1);
1099 		if( act->f.FlagBits.SceneBiasFlag ) {
1100 			act->SceneBias = readUInt16(f);
1101 		}
1102 		break;
1103 		}
1104 	case SWFACTION_WAITFORFRAME2:
1105 		{
1106 		ACT_BEGIN(SWF_ACTIONWAITFORFRAME2)
1107 		act->SkipCount = readUInt8(f);
1108 		break;
1109 		}
1110 
1111 
1112 		/* v5 actions */
1113 	case SWFACTION_CONSTANTPOOL:
1114 		{
1115 		int i, count;
1116 		ACT_BEGIN(SWF_ACTIONCONSTANTPOOL)
1117 
1118 		count = readUInt16(f);
1119 		if (count == EOF)
1120                 {
1121                   SWF_error("unexpected end of file");
1122                 }
1123 		act->Count = count;
1124 		act->ConstantPool = malloc(act->Count*sizeof(char *));
1125 		for(i=0;i<act->Count;i++) {
1126 			act->ConstantPool[i] = readString(f);
1127 		}
1128 		break;
1129 		}
1130 	case SWFACTION_DEFINEFUNCTION:
1131 		{
1132 		int i, end2, num_params;
1133 		ACT_BEGIN(SWF_ACTIONDEFINEFUNCTION)
1134 
1135 		act->FunctionName = readString(f);
1136                 num_params = readUInt16(f);
1137                 if (num_params == EOF) {
1138                   SWF_error("unexpected end of file");
1139                 }
1140 		act->NumParams = num_params;
1141 
1142 		act->Params = (STRING *)malloc(act->NumParams*sizeof(char *));
1143 		for(i=0;i<act->NumParams;i++) {
1144 			act->Params[i] = readString(f);
1145 			/* printf("Read %s\n", act->ConstantPool[i] ); */
1146 		}
1147 		act->CodeSize = readSInt16(f);
1148 		end2 = fileOffset + act->CodeSize;
1149 		act->Actions = (union SWF_ACTION *) calloc (1, sizeof (SWF_ACTION));
1150 		act->numActions = 0;
1151 		while ( fileOffset < end2 ) {
1152 			parseSWF_ACTIONRECORD (f, &(act->numActions), (SWF_ACTION *)act->Actions);
1153 			act->Actions = (union SWF_ACTION *) realloc (act->Actions,
1154 							 (++act->numActions + 1) *
1155 							 sizeof (SWF_ACTION));
1156 		    }
1157 		break;
1158 		}
1159 	case SWFACTION_WITH:
1160 		{
1161 		int end;
1162 		ACT_BEGIN(SWF_ACTIONWITH)
1163 
1164 		act->Size = readUInt16(f);
1165 		end = fileOffset + act->Size;
1166 		act->Actions = (union SWF_ACTION *) calloc (1, sizeof (SWF_ACTION));
1167 		act->numActions = 0;
1168 		while ( fileOffset < end ) {
1169 			parseSWF_ACTIONRECORD (f, &(act->numActions), (SWF_ACTION *)act->Actions);
1170 			act->Actions = (union SWF_ACTION *) realloc (act->Actions,
1171 							 (++act->numActions + 1) *
1172 							 sizeof (SWF_ACTION));
1173 		    }
1174 		break;
1175 		}
1176 	case SWFACTION_STOREREGISTER:
1177 		{
1178 		ACT_BEGIN(SWF_ACTIONSTOREREGISTER)
1179 
1180 		act->Register = readUInt8(f);
1181 		break;
1182 		}
1183 
1184 
1185 		/* v6 actions */
1186 
1187 		/* v7 actions */
1188 	case SWFACTION_DEFINEFUNCTION2:
1189 		{
1190 		int i, end2, num_params;
1191 		ACT_BEGIN(SWF_ACTIONDEFINEFUNCTION2)
1192 
1193 		act->FunctionName = readString(f);
1194 		num_params = readUInt16(f);
1195 		if (num_params == EOF) {
1196 		  SWF_error("unexpected end of file");
1197 		}
1198 		act->NumParams = num_params;
1199 		act->RegisterCount = readSInt8(f);
1200 		act->PreloadParentFlag = readBits(f,1);
1201 		act->PreloadRootFlag = readBits(f,1);
1202 		act->SuppressSuperFlag = readBits(f,1);
1203 		act->PreloadSuperFlag = readBits(f,1);
1204 		act->SuppressArgumentsFlag = readBits(f,1);
1205 		act->PreloadArgumentsFlag = readBits(f,1);
1206 		act->SuppressThisFlag = readBits(f,1);
1207 		act->PreloadThisFlag = readBits(f,1);
1208 		act->Reserved = readBits(f,7);
1209 		act->PreloadGlobalFlag = readBits(f,1);
1210 		act->Params = (struct REGISTERPARAM *)malloc(act->NumParams*sizeof(struct REGISTERPARAM));
1211 		for(i=0;i<act->NumParams;i++) {
1212 			act->Params[i].Register = readUInt8(f);
1213 			act->Params[i].ParamName = readString(f);
1214 		}
1215 		act->CodeSize = readSInt16(f);
1216 		end2 = fileOffset + act->CodeSize;
1217 		act->Actions = (union SWF_ACTION *) calloc (1, sizeof (SWF_ACTION));
1218 		act->numActions = 0;
1219 		while ( fileOffset < end2 ) {
1220 			parseSWF_ACTIONRECORD (f, &(act->numActions), (SWF_ACTION *)act->Actions);
1221 			act->Actions = (union SWF_ACTION *) realloc (act->Actions,
1222 							 (++act->numActions + 1) *
1223 							 sizeof (SWF_ACTION));
1224 		    }
1225 		break;
1226 		}
1227 	case SWFACTION_TRY:
1228 		{
1229 		int end2;
1230 		ACT_BEGIN(SWF_ACTIONTRY)
1231 
1232 		act->Reserved = readBits(f,5);
1233 		act->CatchInRegisterFlag = readBits(f,1);
1234 		act->FinallyBlockFlag = readBits(f,1);
1235 		act->CatchBlockFlag = readBits(f,1);
1236 		act->TrySize = readSInt16(f);
1237 		act->CatchSize = readSInt16(f);
1238 		act->FinallySize = readSInt16(f);
1239 		if( act->CatchInRegisterFlag == 0 ) {
1240 			act->CatchName = readString(f);
1241 		} else {
1242 			act->CatchRegister = readUInt8(f);
1243 		}
1244 
1245 		/* Try Body */
1246 		end2 = fileOffset + act->TrySize;
1247 		act->TryActs = (union SWF_ACTION *) calloc (1, sizeof (SWF_ACTION));
1248 		act->numTryActs = 0;
1249 		while ( fileOffset < end2 ) {
1250 			parseSWF_ACTIONRECORD (f, &(act->numTryActs), (SWF_ACTION *)act->TryActs);
1251 			act->TryActs = (union SWF_ACTION *) realloc (act->TryActs,
1252 							 (++act->numTryActs + 1) *
1253 							 sizeof (SWF_ACTION));
1254 		    }
1255 
1256 		/* Catch Body */
1257 		end2 = fileOffset + act->CatchSize;
1258 		act->CatchActs = (union SWF_ACTION *) calloc (1, sizeof (SWF_ACTION));
1259 		act->numCatchActs = 0;
1260 		while ( fileOffset < end2 ) {
1261 			parseSWF_ACTIONRECORD (f, &(act->numCatchActs), (SWF_ACTION *)act->CatchActs);
1262 			act->CatchActs = (union SWF_ACTION *) realloc (act->CatchActs,
1263 							 (++act->numCatchActs + 1) *
1264 							 sizeof (SWF_ACTION));
1265 		    }
1266 
1267 		/* Finally Body */
1268 		end2 = fileOffset + act->FinallySize;
1269 		act->FinallyActs = (union SWF_ACTION *) calloc (1, sizeof (SWF_ACTION));
1270 		act->numFinallyActs = 0;
1271 		while ( fileOffset < end2 ) {
1272 			parseSWF_ACTIONRECORD (f, &(act->numFinallyActs), (SWF_ACTION *)act->FinallyActs);
1273 			act->FinallyActs = (union SWF_ACTION *) realloc (act->FinallyActs,
1274 							 (++act->numFinallyActs + 1) *
1275 							 sizeof (SWF_ACTION));
1276 		    }
1277 		break;
1278 		}
1279 	default:
1280 		printf("Not parsing action %x length %x\n", action->SWF_ACTIONRECORD.ActionCode, action->SWF_ACTIONRECORD.Length );
1281 		peekBytes(f,100);
1282 		exit(1);
1283 	}
1284 	return 1;
1285 }
1286 
1287 void
parseSWF_DROPSHADOWFILTER(FILE * f,SWF_DROPSHADOWFILTER * filter)1288 parseSWF_DROPSHADOWFILTER(FILE *f, SWF_DROPSHADOWFILTER *filter)
1289 {
1290 	parseSWF_RGBA(f, &filter->DropShadowColor);
1291 	filter->BlurX = readUInt32(f);
1292 	filter->BlurY = readUInt32(f);
1293 	filter->Angle = readUInt32(f);
1294 	filter->Distance = readUInt32(f);
1295 	filter->Strength = readUInt16(f);
1296 	filter->InnerShadow = readBits(f, 1);
1297 	filter->Kockout = readBits(f, 1);
1298 	filter->CompositeSource = readBits(f, 1);
1299 	filter->Passes = readBits(f, 5);
1300 }
1301 
1302 void
parseSWF_BLURFILTER(FILE * f,SWF_BLURFILTER * filter)1303 parseSWF_BLURFILTER(FILE *f, SWF_BLURFILTER *filter)
1304 {
1305 	filter->BlurX = readUInt32(f);
1306 	filter->BlurY = readUInt32(f);
1307 	filter->Passes = readBits(f, 5);
1308 	filter->Reserved = readBits(f, 3);
1309 }
1310 
1311 void
parseSWF_GLOWFILTER(FILE * f,SWF_GLOWFILTER * filter)1312 parseSWF_GLOWFILTER(FILE *f, SWF_GLOWFILTER *filter)
1313 {
1314 	parseSWF_RGBA(f, &filter->GlowColor);
1315 	filter->BlurX = readUInt32(f);
1316 	filter->BlurY = readUInt32(f);
1317 	filter->Strength = readUInt16(f);
1318 	filter->InnerGlow = readBits(f, 1);
1319 	filter->Kockout = readBits(f, 1);
1320 	filter->CompositeSource = readBits(f, 1);
1321 	filter->Passes = readBits(f, 5);
1322 }
1323 
1324 void
parseSWF_BEVELFILTER(FILE * f,SWF_BEVELFILTER * filter)1325 parseSWF_BEVELFILTER(FILE *f, SWF_BEVELFILTER *filter)
1326 {
1327 	parseSWF_RGBA(f, &filter->ShadowColor);
1328 	parseSWF_RGBA(f, &filter->HighlightColor);
1329 	filter->BlurX = readUInt32(f);
1330 	filter->BlurY = readUInt32(f);
1331 	filter->Angle = readUInt32(f);
1332 	filter->Distance = readUInt32(f);
1333 	filter->Strength = readUInt16(f);
1334 	filter->InnerShadow = readBits(f, 1);
1335 	filter->Kockout = readBits(f, 1);
1336 	filter->CompositeSource = readBits(f, 1);
1337 	filter->OnTop = readBits(f, 1);
1338 	filter->Passes = readBits(f, 4);
1339 }
1340 
1341 void
parseSWF_GRADIENTFILTER(FILE * f,SWF_GRADIENTFILTER * filter)1342 parseSWF_GRADIENTFILTER(FILE *f, SWF_GRADIENTFILTER *filter)
1343 {
1344 	int i, size, num_colors;
1345 
1346 	num_colors = readUInt8(f);
1347         if (num_colors == EOF) {
1348           SWF_error("unexpected end of file");
1349         }
1350 	filter->NumColors = num_colors;
1351 	size = filter->NumColors * sizeof(SWF_RGBA);
1352 	filter->GradientColors = (SWF_RGBA *)malloc(size);
1353 	for(i = 0; i < filter->NumColors; i++)
1354 		parseSWF_RGBA(f, filter->GradientColors + i);
1355 
1356 	size = filter->NumColors * sizeof(UI8);
1357 	filter->GradientRatio = (UI8 *)malloc(size);
1358 	for(i = 0; i < filter->NumColors; i++)
1359 		filter->GradientRatio[i] = readUInt8(f);
1360 
1361 	filter->BlurX = readUInt32(f);
1362 	filter->BlurY = readUInt32(f);
1363 	filter->Angle = readUInt32(f);
1364 	filter->Distance = readUInt32(f);
1365 	filter->Strength = readUInt16(f);
1366 	filter->InnerShadow = readBits(f, 1);
1367 	filter->Kockout = readBits(f, 1);
1368 	filter->CompositeSource = readBits(f, 1);
1369 	filter->OnTop = readBits(f, 1);
1370 	filter->Passes = readBits(f, 4);
1371 }
1372 
1373 void
parseSWF_CONVOLUTIONFILTER(FILE * f,SWF_CONVOLUTIONFILTER * filter)1374 parseSWF_CONVOLUTIONFILTER(FILE *f, SWF_CONVOLUTIONFILTER *filter)
1375 {
1376 	int size, i, x, y;
1377 
1378 	x = readUInt8(f);
1379 	y = readUInt8(f);
1380         if (x == EOF || y == EOF) {
1381           SWF_error("unexpected end of file");
1382         }
1383 	filter->MatrixX = x;
1384 	filter->MatrixY = y;
1385 	filter->Divisor = readUInt32(f);
1386 	filter->Bias = readUInt32(f);
1387 
1388 	size = filter->MatrixX * filter->MatrixY * sizeof(UI32);
1389 	filter->Matrix = (FLOAT *)malloc(size);
1390 	for(i = 0; i < filter->MatrixX * filter->MatrixY; i++)
1391 		filter->Matrix[i] = readUInt32(f);
1392 
1393 	parseSWF_RGBA(f, &filter->DefaultColor);
1394 	filter->Reserved = readBits(f, 6);
1395 	filter->Clamp = readBits(f, 1);
1396 	filter->PreserveAlpha = readBits(f, 1);
1397 }
1398 
1399 void
parseSWF_COLORMATRIXFILTER(FILE * f,SWF_COLORMATRIXFILTER * filter)1400 parseSWF_COLORMATRIXFILTER(FILE *f, SWF_COLORMATRIXFILTER *filter)
1401 {
1402 	int i;
1403 
1404 	for(i = 0; i < 20; i++)
1405 		filter->Matrix[i] = readFloat(f);
1406 }
1407 
1408 void
parseSWF_FILTER(FILE * f,SWF_FILTER * filter)1409 parseSWF_FILTER(FILE *f, SWF_FILTER *filter)
1410 {
1411 	filter->FilterId = readUInt8(f);
1412 
1413 	switch(filter->FilterId)
1414 	{
1415 		case FILTER_DROPSHADOW:
1416 			parseSWF_DROPSHADOWFILTER(f, &filter->filter.dropShadow);
1417 			break;
1418 		case FILTER_BLUR:
1419 			parseSWF_BLURFILTER(f, &filter->filter.blur);
1420 			break;
1421 		case FILTER_GLOW:
1422 			parseSWF_GLOWFILTER(f, &filter->filter.glow);
1423 			break;
1424 		case FILTER_BEVEL:
1425 			parseSWF_BEVELFILTER(f, &filter->filter.bevel);
1426 			break;
1427 		case FILTER_CONVOLUTION:
1428 			parseSWF_CONVOLUTIONFILTER(f, &filter->filter.convolution);
1429 			break;
1430 		case FILTER_COLORMATRIX:
1431 			parseSWF_COLORMATRIXFILTER(f, &filter->filter.colorMatrix);
1432 			break;
1433 		case FILTER_GRADIENTGLOW:
1434 			parseSWF_GRADIENTFILTER(f, &filter->filter.gradientGlow);
1435 			break;
1436 		case FILTER_GRADIENTBEVEL:
1437 			parseSWF_GRADIENTFILTER(f, &filter->filter.gradientBevel);
1438 			break;
1439 		default:
1440 			printf("unknown filter %i\n", filter->FilterId);
1441 	}
1442 }
1443 
1444 void
parseSWF_FILTERLIST(FILE * f,SWF_FILTERLIST * list)1445 parseSWF_FILTERLIST(FILE *f, SWF_FILTERLIST *list)
1446 {
1447 	int i, size, number_of_filters;
1448 	number_of_filters = readUInt8(f);
1449         if (number_of_filters == EOF) {
1450           list->NumberOfFilters = 0;
1451           SWF_error("unexpected end of file");
1452           return;
1453         }
1454 	list->NumberOfFilters = number_of_filters;
1455 	size = list->NumberOfFilters * sizeof(SWF_FILTER);
1456 	list->Filter = (SWF_FILTER *)malloc(size);
1457 
1458 	for(i = 0; i < list->NumberOfFilters; i++)
1459 		parseSWF_FILTER(f, list->Filter + i);
1460 }
1461 
1462 /* Parse Block types */
1463 
1464 SWF_Parserstruct *
parseSWF_CHARACTERSET(FILE * f,int length)1465 parseSWF_CHARACTERSET (FILE * f, int length)
1466 {
1467   PAR_BEGIN (SWF_CHARACTERSET);
1468   SKIP;
1469   PAR_END;
1470 }
1471 
1472 SWF_Parserstruct *
parseSWF_DEFINEBITS(FILE * f,int length)1473 parseSWF_DEFINEBITS (FILE * f, int length)
1474 {
1475   int end = fileOffset + length;
1476   PAR_BEGIN (SWF_DEFINEBITS);
1477 
1478   parserrec->CharacterID = readUInt16 (f);
1479   parserrec->JPEGDataSize = end-fileOffset;
1480   parserrec->JPEGData = (UI8 *)readBytes(f,end-fileOffset);
1481 
1482   PAR_END;
1483 }
1484 
1485 SWF_Parserstruct *
parseSWF_DEFINEBITSJPEG2(FILE * f,int length)1486 parseSWF_DEFINEBITSJPEG2 (FILE * f, int length)
1487 {
1488   int end = fileOffset + length;
1489   PAR_BEGIN (SWF_DEFINEBITSJPEG2);
1490 
1491   parserrec->CharacterID = readUInt16 (f);
1492   parserrec->JPEGDataSize = end-fileOffset;
1493   parserrec->JPEGData = (UI8 *)readBytes(f,end-fileOffset);
1494 
1495   PAR_END;
1496 }
1497 
1498 SWF_Parserstruct *
parseSWF_DEFINEBITSJPEG3(FILE * f,int length)1499 parseSWF_DEFINEBITSJPEG3 (FILE * f, int length)
1500 {
1501   int end = fileOffset + length;
1502   PAR_BEGIN (SWF_DEFINEBITSJPEG3);
1503 
1504   parserrec->CharacterID = readUInt16 (f);
1505   parserrec->AlphaDataOffset = readUInt32 (f);
1506   parserrec->JPEGData = (UI8 *)readBytes(f,parserrec->AlphaDataOffset);
1507   parserrec->AlphaDataSize = end-fileOffset;
1508   parserrec->BitmapAlphaData = (UI8 *)readBytes(f,end-fileOffset);
1509 
1510 
1511   PAR_END;
1512 }
1513 
1514 SWF_Parserstruct *
parseSWF_DEFINEBITSPTR(FILE * f,int length)1515 parseSWF_DEFINEBITSPTR (FILE * f, int length)
1516 {
1517   PAR_BEGIN (SWF_DEFINEBITSPTR);
1518   SKIP;
1519   PAR_END;
1520 }
1521 
1522 SWF_Parserstruct *
parseSWF_DEFINEBUTTON(FILE * f,int length)1523 parseSWF_DEFINEBUTTON (FILE * f, int length)
1524 {
1525   PAR_BEGIN (SWF_DEFINEBUTTON);
1526   parserrec->ButtonId = readUInt16 (f);
1527   parserrec->numCharacters = 0;
1528   parserrec->Characters = (SWF_BUTTONRECORD *)calloc(1, sizeof (SWF_BUTTONRECORD));
1529   while (parseSWF_BUTTONRECORD (f, &(parserrec->Characters[parserrec->numCharacters++]), 1 ))
1530   {
1531     int size = (parserrec->numCharacters + 1) * sizeof(SWF_BUTTONRECORD);
1532     parserrec->Characters = (SWF_BUTTONRECORD *) realloc (parserrec->Characters, size);
1533   }
1534   parserrec->CharacterEndFlag = 0; // handled by parseSWF_BUTTONRECORD
1535 
1536   parserrec->Actions = (SWF_ACTION *) calloc (1, sizeof (SWF_ACTION));
1537   parserrec->numActions = 0;
1538   while (parseSWF_ACTIONRECORD (f, &(parserrec->numActions), parserrec->Actions))
1539   {
1540     int size = (++parserrec->numActions + 1) * sizeof(SWF_ACTION);
1541     parserrec->Actions = (SWF_ACTION *) realloc (parserrec->Actions, size);
1542   }
1543   parserrec->ActionEndFlag = 0;
1544   PAR_END;
1545 }
1546 
1547 SWF_Parserstruct *
parseSWF_DEFINEBUTTON2(FILE * f,int length)1548 parseSWF_DEFINEBUTTON2 (FILE * f, int length)
1549 {
1550   int stop;
1551   int end = fileOffset + length;
1552   PAR_BEGIN (SWF_DEFINEBUTTON2);
1553 
1554   byteAlign();
1555 
1556   parserrec->Buttonid = readUInt16 (f);
1557   parserrec->ReservedFlags = readBits (f, 7);
1558   parserrec->TrackAsMenu = readBits (f, 1);
1559   stop = fileOffset;
1560   parserrec->ActionOffset = readUInt16 (f);
1561   if( parserrec->ActionOffset )
1562     stop += parserrec->ActionOffset;
1563   else
1564     stop = end;
1565   parserrec->numCharacters = 0;
1566   parserrec->Characters =
1567     (SWF_BUTTONRECORD *) calloc (1, sizeof (SWF_BUTTONRECORD));
1568 
1569   while ( fileOffset < stop-1 ) {
1570     parseSWF_BUTTONRECORD (f, &(parserrec->Characters[parserrec->numCharacters++]), 2 );
1571     parserrec->Characters = (SWF_BUTTONRECORD *) realloc (parserrec->Characters,
1572 							 (parserrec->numCharacters + 1) *
1573 							 sizeof
1574 							 (SWF_BUTTONRECORD));
1575     }
1576 
1577   parserrec->CharacterEndFlag = readUInt8 (f);
1578   if ( parserrec->CharacterEndFlag != 0 )
1579   {
1580     SWF_warn(" CharacterEndFlag in DefineButton2 != 0");
1581   }
1582 
1583   parserrec->numActions = 0;
1584   parserrec->Actions =
1585     (SWF_BUTTONCONDACTION *) calloc (1, sizeof (SWF_BUTTONCONDACTION));
1586   while( fileOffset < end &&
1587        parseSWF_BUTTONCONDACTION (f, &(parserrec->Actions[parserrec->numActions++]), end))
1588   {
1589     parserrec->Actions = (SWF_BUTTONCONDACTION *) realloc (parserrec->Actions,
1590 							 (parserrec->numActions + 1) *
1591 							 sizeof
1592 							 (SWF_BUTTONCONDACTION));
1593   }
1594 
1595   PAR_END;
1596 }
1597 
1598 SWF_Parserstruct *
parseSWF_DEFINEBUTTONCXFORM(FILE * f,int length)1599 parseSWF_DEFINEBUTTONCXFORM (FILE * f, int length)
1600 {
1601   PAR_BEGIN (SWF_DEFINEBUTTONCXFORM);
1602   parserrec->ButtonId = readUInt16(f);
1603   parseSWF_CXFORM(f, &parserrec->ButtonColorTransform);
1604   PAR_END;
1605 }
1606 
1607 void parseSWF_SOUNDINFO(FILE *f, struct SWF_SOUNDINFO *si);
1608 
1609 SWF_Parserstruct *
parseSWF_DEFINEBUTTONSOUND(FILE * f,int length)1610 parseSWF_DEFINEBUTTONSOUND (FILE * f, int length)
1611 {
1612   PAR_BEGIN (SWF_DEFINEBUTTONSOUND);
1613   parserrec->CharacterID = readUInt16 (f);
1614   parserrec->ButtonSoundChar0 = readUInt16 (f);
1615   if (parserrec->ButtonSoundChar0)
1616     parseSWF_SOUNDINFO(f, &parserrec->ButtonSoundInfo0);
1617 
1618   parserrec->ButtonSoundChar1 = readUInt16 (f);
1619   if (parserrec->ButtonSoundChar1)
1620     parseSWF_SOUNDINFO(f, &parserrec->ButtonSoundInfo1);
1621 
1622   parserrec->ButtonSoundChar2 = readUInt16 (f);
1623   if (parserrec->ButtonSoundChar2)
1624     parseSWF_SOUNDINFO(f, &parserrec->ButtonSoundInfo2);
1625 
1626   parserrec->ButtonSoundChar3 = readUInt16 (f);
1627   if (parserrec->ButtonSoundChar3)
1628     parseSWF_SOUNDINFO(f, &parserrec->ButtonSoundInfo3);
1629 
1630   PAR_END;
1631 }
1632 
1633 SWF_Parserstruct *
parseSWF_DEFINECOMMANDOBJ(FILE * f,int length)1634 parseSWF_DEFINECOMMANDOBJ (FILE * f, int length)
1635 {
1636   PAR_BEGIN (SWF_DEFINECOMMANDOBJ);
1637   SKIP;
1638   PAR_END;
1639 }
1640 
1641 SWF_Parserstruct *
parseSWF_DEFINEEDITTEXT(FILE * f,int length)1642 parseSWF_DEFINEEDITTEXT (FILE * f, int length)
1643 {
1644   PAR_BEGIN (SWF_DEFINEEDITTEXT);
1645 
1646   parserrec->CharacterID = readUInt16 (f);
1647   parseSWF_RECT (f, &(parserrec->Bounds));
1648   byteAlign ();
1649   parserrec->HasText = readBits (f, 1);
1650   parserrec->WordWrap = readBits (f, 1);
1651   parserrec->Multiline = readBits (f, 1);
1652   parserrec->Password = readBits (f, 1);
1653   parserrec->ReadOnly = readBits (f, 1);
1654   parserrec->HasTextColor = readBits (f, 1);
1655   parserrec->HasMaxLength = readBits (f, 1);
1656   parserrec->HasFont = readBits (f, 1);
1657   parserrec->HasFontClass = readBits (f, 1);
1658   parserrec->AutoSize = readBits (f, 1);
1659   parserrec->HasLayout = readBits (f, 1);
1660   parserrec->NoSelect = readBits (f, 1);
1661   parserrec->Border = readBits (f, 1);
1662   parserrec->WasStatic = readBits (f, 1);
1663   parserrec->HTML = readBits (f, 1);
1664   parserrec->UseOutlines = readBits (f, 1);
1665   if (parserrec->HasFont)
1666     parserrec->FontID = readUInt16 (f);
1667 
1668   if (parserrec->HasFontClass)
1669     parserrec->FontClass = readString(f);
1670 
1671   if (parserrec->HasFont)
1672     parserrec->FontHeight = readUInt16 (f);
1673 
1674   if (parserrec->HasTextColor)
1675     {
1676       parseSWF_RGBA (f, &parserrec->TextColor);
1677     }
1678   if (parserrec->HasMaxLength)
1679     {
1680       parserrec->MaxLength = readUInt16 (f);
1681     }
1682   if (parserrec->HasLayout)
1683     {
1684       parserrec->Align = readUInt8 (f);
1685       parserrec->LeftMargin = readUInt16 (f);
1686       parserrec->RightMargin = readUInt16 (f);
1687       parserrec->Indent = readUInt16 (f);
1688       parserrec->Leading = readUInt16 (f);
1689     }
1690   parserrec->VariableName = readString (f);
1691   if (parserrec->HasText)
1692     {
1693       parserrec->InitialText = readString (f);
1694     }
1695 
1696   PAR_END;
1697 }
1698 
1699 SWF_Parserstruct *
parseSWF_DEFINEFONT(FILE * f,int length)1700 parseSWF_DEFINEFONT (FILE * f, int length)
1701 {
1702   int i;
1703   int  firstOffset;
1704   PAR_BEGIN (SWF_DEFINEFONT);
1705 
1706   parserrec->FontID = readUInt16 (f);
1707   firstOffset = readUInt16 (f);
1708   if (firstOffset == EOF) {
1709     SWF_error("unexpected end of file");
1710   }
1711 
1712   parserrec->NumGlyphs = (firstOffset/2);
1713   Movie_addFontInfo(&m, parserrec->FontID, parserrec->NumGlyphs);
1714   // store at least a 0 in the first offset table element if there are no glyphs
1715   parserrec->OffsetTable = (UI16 *)malloc(MAX(1, (firstOffset/2)) * sizeof( UI16 ) );
1716   parserrec->OffsetTable[0] = firstOffset;
1717   for(i=1;i<firstOffset/2;i++) {
1718   	parserrec->OffsetTable[i] = readUInt16 (f);
1719   }
1720   parserrec->GlyphShapeTable = (SWF_SHAPE *)malloc(firstOffset/2 * sizeof( SWF_SHAPE ) );
1721   for(i=0;i<firstOffset/2;i++) {
1722     int len;
1723     if(i < firstOffset/2 - 1)
1724       len = parserrec->OffsetTable[i + 1] - parserrec->OffsetTable[i];
1725     else
1726       len = length -  parserrec->OffsetTable[i];
1727     parseSWF_SHAPE(f, &(parserrec->GlyphShapeTable[i]), 1, len);
1728   }
1729   PAR_END;
1730 }
1731 
1732 SWF_Parserstruct *
parseSWF_DEFINEFONT2(FILE * f,int length)1733 parseSWF_DEFINEFONT2 (FILE * f, int length)
1734 {
1735   int i, num_glyphs;
1736   PAR_BEGIN (SWF_DEFINEFONT2);
1737 
1738   byteAlign ();
1739 
1740   parserrec->FontID = readUInt16 (f);
1741   parserrec->FontFlagsHasLayout = readBits (f, 1);
1742   parserrec->FontFlagsShiftJis = readBits (f, 1);
1743   parserrec->FontFlagsSmallText = readBits (f, 1);
1744   parserrec->FontFlagsFlagANSI = readBits (f, 1);
1745   parserrec->FontFlagsWideOffsets = readBits (f, 1);
1746   parserrec->FontFlagsWideCodes = readBits (f, 1);
1747   parserrec->FontFlagsFlagsItalics = readBits (f, 1);
1748   parserrec->FontFlagsFlagsBold = readBits (f, 1);
1749   parserrec->LanguageCode = readUInt8 (f);
1750   parserrec->FontNameLen = readUInt8 (f);
1751   parserrec->FontName = readSizedString (f, parserrec->FontNameLen);
1752   num_glyphs = readUInt16 (f);
1753   if (num_glyphs == EOF) {
1754     SWF_error("unexpected end of file");
1755   }
1756   parserrec->NumGlyphs = num_glyphs;
1757   Movie_addFontInfo(&m, parserrec->FontID, parserrec->NumGlyphs);
1758   if (parserrec->FontFlagsWideOffsets)
1759     {
1760       parserrec->OffsetTable.UI32 =
1761 	(UI32 *) malloc (parserrec->NumGlyphs * sizeof (UI32));
1762       for (i = 0; i < parserrec->NumGlyphs; i++)
1763 	{
1764 	  parserrec->OffsetTable.UI32[i] = readUInt32 (f);
1765 	}
1766     }
1767   else
1768     {
1769       parserrec->OffsetTable.UI16 =
1770 	(UI16 *) malloc (parserrec->NumGlyphs * sizeof (UI16));
1771       for (i = 0; i < parserrec->NumGlyphs; i++)
1772 	{
1773 	  parserrec->OffsetTable.UI16[i] = readUInt16 (f);
1774 	}
1775     }
1776 
1777   if (parserrec->FontFlagsWideOffsets)
1778     {
1779 	parserrec->CodeTableOffset.UI32 = readUInt32 (f);
1780     }
1781   else
1782     {
1783 	parserrec->CodeTableOffset.UI16 = readUInt16 (f);
1784     }
1785 
1786   parserrec->GlyphShapeTable = (SWF_SHAPE *)
1787     malloc (parserrec->NumGlyphs * sizeof (SWF_SHAPE));
1788   for (i = 0; i < parserrec->NumGlyphs; i++)
1789     {
1790       int len;
1791       if(parserrec->FontFlagsWideOffsets)
1792       {
1793         if(i < parserrec->NumGlyphs - 1)
1794           len = parserrec->OffsetTable.UI32[i + 1] - parserrec->OffsetTable.UI32[i];
1795         else
1796           len = parserrec->CodeTableOffset.UI32 - parserrec->OffsetTable.UI32[i];
1797       }
1798       else
1799       {
1800          if(i < parserrec->NumGlyphs - 1)
1801            len = parserrec->OffsetTable.UI16[i + 1] - parserrec->OffsetTable.UI16[i];
1802          else
1803            len = parserrec->CodeTableOffset.UI16 - parserrec->OffsetTable.UI16[i];
1804       }
1805 	parseSWF_SHAPE (f, parserrec->GlyphShapeTable + i, 3, len);
1806     }
1807 
1808   parserrec->CodeTable =
1809 	(int *) malloc (parserrec->NumGlyphs * sizeof (int));
1810   if (parserrec->FontFlagsWideCodes)
1811     {
1812       for (i = 0; i < parserrec->NumGlyphs; i++)
1813 	{
1814 	  parserrec->CodeTable[i] = readUInt16 (f);
1815 	}
1816     }
1817   else
1818     {
1819       for (i = 0; i < parserrec->NumGlyphs; i++)
1820 	{
1821 	  parserrec->CodeTable[i] = readUInt8 (f);
1822 	}
1823     }
1824 
1825   if( parserrec->FontFlagsHasLayout ) {
1826 	  int kerning_count;
1827 	  parserrec->FontAscent = readSInt16(f);
1828 	  parserrec->FontDecent = readSInt16(f);
1829 	  parserrec->FontLeading = readSInt16(f);
1830 	  /* FontAdvanceTable */
1831 	  parserrec->FontAdvanceTable =
1832 	     (SI16 *) malloc (parserrec->NumGlyphs * sizeof (SI16));
1833 	  for (i = 0; i < parserrec->NumGlyphs; i++)
1834 	  {
1835 	    parserrec->FontAdvanceTable[i] = readSInt16 (f);
1836 	  }
1837 	  /* FontBoundsTable */
1838 	  parserrec->FontBoundsTable =
1839 	     (SWF_RECT *) malloc (parserrec->NumGlyphs * sizeof (SWF_RECT));
1840 	  for (i = 0; i < parserrec->NumGlyphs; i++)
1841 	  {
1842 	    parseSWF_RECT (f, &(parserrec->FontBoundsTable[i]));
1843 	  }
1844 	  kerning_count = readUInt16(f);
1845           if (kerning_count == EOF) {
1846             SWF_error("unexpected end of file");
1847           }
1848 	  parserrec->KerningCount = kerning_count;
1849 	  /* FontKerningTable */
1850 	  parserrec->FontKerningTable =
1851 	     (struct SWF_KERNINGRECORD *) malloc (parserrec->KerningCount * sizeof (struct SWF_KERNINGRECORD));
1852 	  for (i = 0; i < parserrec->KerningCount; i++)
1853 	  {
1854 	    if( parserrec->FontFlagsWideCodes ) {
1855 		parserrec->FontKerningTable[i].FontKerningCode1 = readUInt16 (f);
1856 		parserrec->FontKerningTable[i].FontKerningCode2 = readUInt16 (f);
1857 	    } else {
1858 		parserrec->FontKerningTable[i].FontKerningCode1 = readUInt8 (f);
1859 		parserrec->FontKerningTable[i].FontKerningCode2 = readUInt8 (f);
1860 	    }
1861 	    parserrec->FontKerningTable[i].FontKerningAdjustment = readSInt16 (f);
1862 	  }
1863   }
1864 
1865   PAR_END;
1866 }
1867 
1868 SWF_Parserstruct *
parseSWF_DEFINEFONT3(FILE * f,int length)1869 parseSWF_DEFINEFONT3 (FILE * f, int length)
1870 {
1871   int i, num_glyphs;
1872   PAR_BEGIN (SWF_DEFINEFONT3);
1873 
1874   byteAlign ();
1875 
1876   parserrec->FontID = readUInt16 (f);
1877   parserrec->FontFlagsHasLayout = readBits (f, 1);
1878   parserrec->FontFlagsShiftJis = readBits (f, 1);
1879   parserrec->FontFlagsSmallText = readBits (f, 1);
1880   parserrec->FontFlagsFlagANSI = readBits (f, 1);
1881   parserrec->FontFlagsWideOffsets = readBits (f, 1);
1882   parserrec->FontFlagsWideCodes = readBits (f, 1);
1883   parserrec->FontFlagsFlagsItalics = readBits (f, 1);
1884   parserrec->FontFlagsFlagsBold = readBits (f, 1);
1885   parserrec->LanguageCode = readUInt8 (f);
1886   parserrec->FontNameLen = readUInt8 (f);
1887   parserrec->FontName = readSizedString (f, parserrec->FontNameLen);
1888   num_glyphs = readUInt16 (f);
1889   if (num_glyphs == EOF) {
1890     SWF_error("unexpected end of file");
1891   }
1892   parserrec->NumGlyphs = num_glyphs;
1893   Movie_addFontInfo(&m, parserrec->FontID, parserrec->NumGlyphs);
1894   if (parserrec->FontFlagsWideOffsets)
1895     {
1896       parserrec->OffsetTable.UI32 =
1897 	(UI32 *) malloc (parserrec->NumGlyphs * sizeof (UI32));
1898       for (i = 0; i < parserrec->NumGlyphs; i++)
1899 	{
1900 	  parserrec->OffsetTable.UI32[i] = readUInt32 (f);
1901 	}
1902     }
1903   else
1904     {
1905       parserrec->OffsetTable.UI16 =
1906 	(UI16 *) malloc (parserrec->NumGlyphs * sizeof (UI16));
1907       for (i = 0; i < parserrec->NumGlyphs; i++)
1908 	{
1909 	  parserrec->OffsetTable.UI16[i] = readUInt16 (f);
1910 	}
1911     }
1912 
1913   if (parserrec->FontFlagsWideOffsets)
1914     {
1915 	parserrec->CodeTableOffset.UI32 = readUInt32 (f);
1916     }
1917   else
1918     {
1919 	parserrec->CodeTableOffset.UI16 = readUInt16 (f);
1920     }
1921 
1922   parserrec->GlyphShapeTable = (SWF_SHAPE *)
1923     malloc (parserrec->NumGlyphs * sizeof (SWF_SHAPE));
1924   for (i = 0; i < parserrec->NumGlyphs; i++)
1925     {
1926       int len;
1927       if(parserrec->FontFlagsWideOffsets)
1928       {
1929         if(i < parserrec->NumGlyphs - 1)
1930           len = parserrec->OffsetTable.UI32[i + 1] - parserrec->OffsetTable.UI32[i];
1931         else
1932           len = parserrec->CodeTableOffset.UI32 - parserrec->OffsetTable.UI32[i];
1933       }
1934       else
1935       {
1936          if(i < parserrec->NumGlyphs - 1)
1937            len = parserrec->OffsetTable.UI16[i + 1] - parserrec->OffsetTable.UI16[i];
1938          else
1939            len = parserrec->CodeTableOffset.UI16 - parserrec->OffsetTable.UI16[i];
1940       }
1941       parseSWF_SHAPE (f, &parserrec->GlyphShapeTable[i], 3, len);
1942     }
1943 
1944   parserrec->CodeTable =
1945 	(UI16 *) malloc (parserrec->NumGlyphs * sizeof (UI16));
1946   if (parserrec->FontFlagsWideCodes)
1947     {
1948       for (i = 0; i < parserrec->NumGlyphs; i++)
1949 	{
1950 	  parserrec->CodeTable[i] = readUInt16 (f);
1951 	}
1952     }
1953   else
1954     {
1955       for (i = 0; i < parserrec->NumGlyphs; i++)
1956 	{
1957 	  parserrec->CodeTable[i] = readUInt8 (f);
1958 	}
1959     }
1960 
1961   if( parserrec->FontFlagsHasLayout ) {
1962 	  int kerning_count;
1963 	  parserrec->FontAscent = readSInt16(f);
1964 	  parserrec->FontDecent = readSInt16(f);
1965 	  parserrec->FontLeading = readSInt16(f);
1966 	  /* FontAdvanceTable */
1967 	  parserrec->FontAdvanceTable =
1968 	     (SI16 *) malloc (parserrec->NumGlyphs * sizeof (SI16));
1969 	  for (i = 0; i < parserrec->NumGlyphs; i++)
1970 	  {
1971 	    parserrec->FontAdvanceTable[i] = readSInt16 (f);
1972 	  }
1973 	  /* FontBoundsTable */
1974 	  parserrec->FontBoundsTable =
1975 	     (SWF_RECT *) malloc (parserrec->NumGlyphs * sizeof (SWF_RECT));
1976 	  for (i = 0; i < parserrec->NumGlyphs; i++)
1977 	  {
1978 	    parseSWF_RECT (f, &(parserrec->FontBoundsTable[i]));
1979 	  }
1980 	  kerning_count = readUInt16(f);
1981           if (kerning_count == EOF) {
1982             SWF_error("unexpected end of file");
1983           }
1984 	  parserrec->KerningCount = kerning_count;
1985 	  /* FontKerningTable */
1986 	  parserrec->FontKerningTable =
1987 	     (struct SWF_KERNINGRECORD *) malloc (parserrec->KerningCount * sizeof (struct SWF_KERNINGRECORD));
1988 	  for (i = 0; i < parserrec->KerningCount; i++)
1989 	  {
1990 	    if( parserrec->FontFlagsWideCodes ) {
1991 		parserrec->FontKerningTable[i].FontKerningCode1 = readUInt16 (f);
1992 		parserrec->FontKerningTable[i].FontKerningCode2 = readUInt16 (f);
1993 	    } else {
1994 		parserrec->FontKerningTable[i].FontKerningCode1 = readUInt8 (f);
1995 		parserrec->FontKerningTable[i].FontKerningCode2 = readUInt8 (f);
1996 	    }
1997 	    parserrec->FontKerningTable[i].FontKerningAdjustment = readSInt16 (f);
1998 	  }
1999   }
2000 
2001   PAR_END;
2002 }
2003 
2004 SWF_Parserstruct *
parseSWF_DEFINEFONTINFO(FILE * f,int length)2005 parseSWF_DEFINEFONTINFO (FILE * f, int length)
2006 {
2007   int i, end = fileOffset + length;
2008   PAR_BEGIN (SWF_DEFINEFONTINFO);
2009 
2010   parserrec->FontID = readUInt16 (f);
2011   parserrec->FontNameLen = readUInt8 (f);
2012   parserrec->FontName = readSizedString (f, parserrec->FontNameLen);
2013   byteAlign ();
2014   parserrec->FontFlagsReserved = readBits (f, 2);
2015   parserrec->FontFlagsSmallText = readBits (f, 1);
2016   parserrec->FontFlagsShiftJIS = readBits (f, 1);
2017   parserrec->FontFlagsANSI = readBits (f, 1);
2018   parserrec->FontFlagsItalic = readBits (f, 1);
2019   parserrec->FontFlagsBold = readBits (f, 1);
2020   parserrec->FontFlagsWideCodes = readBits (f, 1);
2021   if( parserrec->FontFlagsWideCodes )
2022 	  parserrec->nGlyph = (end-fileOffset)/2;
2023   else
2024 	  parserrec->nGlyph = end-fileOffset;
2025 
2026   if (parserrec->nGlyph < 0 || parserrec->nGlyph > (INT_MAX / sizeof(UI16))) {
2027     SWF_error("invalid Glyph count");
2028   }
2029   parserrec->CodeTable = (UI16 *)malloc(parserrec->nGlyph*sizeof(UI16));
2030   for(i=0;i<parserrec->nGlyph;i++)
2031   if( parserrec->FontFlagsWideCodes )
2032 	  parserrec->CodeTable[i] = readUInt16(f);
2033   else
2034 	  parserrec->CodeTable[i] = readUInt8(f);
2035 
2036   PAR_END;
2037 }
2038 
2039 SWF_Parserstruct *
parseSWF_DEFINEFONTINFO2(FILE * f,int length)2040 parseSWF_DEFINEFONTINFO2 (FILE * f, int length)
2041 {
2042   int i, end = fileOffset + length;
2043   PAR_BEGIN (SWF_DEFINEFONTINFO2);
2044 
2045   parserrec->FontID = readUInt16 (f);
2046   parserrec->FontNameLen = readUInt8 (f);
2047   parserrec->FontName = readSizedString (f, parserrec->FontNameLen);
2048   byteAlign ();
2049   parserrec->FontFlagsReserved = readBits (f, 2);
2050   parserrec->FontFlagsSmallText = readBits (f, 1);
2051   parserrec->FontFlagsShiftJIS = readBits (f, 1);
2052   parserrec->FontFlagsANSI = readBits (f, 1);
2053   parserrec->FontFlagsItalic = readBits (f, 1);
2054   parserrec->FontFlagsBold = readBits (f, 1);
2055   parserrec->FontFlagsWideCodes = readBits (f, 1);
2056   parserrec->LanguageCode = readUInt8(f);
2057   parserrec->nGlyph = (end-fileOffset)/2;
2058   if (parserrec->nGlyph < 0 || parserrec->nGlyph > (INT_MAX / sizeof(UI16))) {
2059     SWF_error("invalid Glyph count");
2060   }
2061 
2062   parserrec->CodeTable = (UI16 *)malloc(parserrec->nGlyph*sizeof(UI16));
2063   for(i=0;i<parserrec->nGlyph;i++)
2064 	  parserrec->CodeTable[i] = readUInt16(f);
2065 
2066   PAR_END;
2067 }
2068 
2069 SWF_Parserstruct *
parseSWF_CSMTEXTSETTINGS(FILE * f,int length)2070 parseSWF_CSMTEXTSETTINGS (FILE * f, int length)
2071 {
2072   PAR_BEGIN (SWF_CSMTEXTSETTINGS);
2073   parserrec->TextID = readUInt16(f);
2074   parserrec->UseFlashType = readBits(f, 2);
2075   parserrec->GridFit = readBits(f, 3);
2076   parserrec->Reserved = readBits(f, 3);
2077   parserrec->Thickness = readUInt32(f);
2078   parserrec->Sharpness = readUInt32(f);
2079   parserrec->Reserved = readUInt8(f);
2080   PAR_END;
2081 }
2082 
2083 void
parseSWF_ZONEDATA(FILE * f,struct SWF_ZONEDATA * data)2084 parseSWF_ZONEDATA(FILE *f, struct SWF_ZONEDATA *data)
2085 {
2086   data->AlignmentCoordinate = readUInt16(f); // FLOAT16
2087   data->Range = readUInt16(f); // FLOAT16
2088 }
2089 
2090 void
parseSWF_ZONERECORD(FILE * f,struct SWF_ZONERECORD * table)2091 parseSWF_ZONERECORD(FILE *f, struct SWF_ZONERECORD *table)
2092 {
2093   int i, num_zone_data;
2094   num_zone_data = readUInt8(f);
2095   if (num_zone_data == EOF) {
2096     SWF_error("unexpeced end of file");
2097   }
2098   table->NumZoneData = num_zone_data;
2099   table->ZoneData = (struct SWF_ZONEDATA *)
2100     malloc(table->NumZoneData * sizeof(struct SWF_ZONEDATA));
2101   for(i = 0; i < table->NumZoneData; i++)
2102   	parseSWF_ZONEDATA(f, table->ZoneData + i);
2103 
2104   table->ZoneMaskX = readBits(f, 1);
2105   table->ZoneMaskY = readBits(f, 1);
2106   table->Reserved  = readBits(f, 6);
2107 }
2108 
2109 SWF_Parserstruct *
parseSWF_DEFINEFONTALIGNZONES(FILE * f,int length)2110 parseSWF_DEFINEFONTALIGNZONES(FILE *f, int length)
2111 {
2112   int i;
2113   PAR_BEGIN (SWF_DEFINEFONTALIGNZONES);
2114   parserrec->FontID = readUInt16(f);
2115   parserrec->CSMTableHint = readBits(f, 2);
2116   parserrec->Reserved = readBits(f, 6);
2117   parserrec->GlyphCount = Movie_getFontGlyphCount(&m, parserrec->FontID);
2118   if(parserrec->GlyphCount < 0)
2119 	SWF_error("SWF_DEFINEFONTALIGNZONES: FontID %i not present\n", parserrec->FontID);
2120   parserrec->ZoneTable = malloc(sizeof(struct SWF_ZONERECORD) * parserrec->GlyphCount);
2121 
2122   for(i = 0; i < parserrec->GlyphCount; i++)
2123   	parseSWF_ZONERECORD(f, parserrec->ZoneTable + i);
2124   PAR_END;
2125 }
2126 
2127 SWF_Parserstruct *
parseSWF_DEFINEFONTNAME(FILE * f,int length)2128 parseSWF_DEFINEFONTNAME(FILE * f, int length)
2129 {
2130   PAR_BEGIN(SWF_DEFINEFONTNAME);
2131   parserrec->FontId = readUInt16(f);
2132   parserrec->FontName = readString(f);
2133   parserrec->FontCopyright = readString(f);
2134   PAR_END;
2135 }
2136 
2137 SWF_Parserstruct *
parseSWF_DEFINELOSSLESS(FILE * f,int length)2138 parseSWF_DEFINELOSSLESS (FILE * f, int length)
2139 {
2140   int end = fileOffset + length;
2141   PAR_BEGIN (SWF_DEFINELOSSLESS);
2142 
2143   parserrec->CharacterID = readUInt16 (f);
2144   parserrec->BitmapFormat = readUInt8 (f);
2145   parserrec->BitmapWidth = readUInt16 (f);
2146   parserrec->BitmapHeight = readUInt16 (f);
2147   if( parserrec->BitmapFormat == 3 /* 8-bit */ ) {
2148       parserrec->BitmapColorTableSize = readUInt8 (f);
2149   }
2150   parserrec->ZlibBitmapData = (UI8 *)readBytes (f,end-fileOffset);
2151 
2152   PAR_END;
2153 }
2154 
2155 SWF_Parserstruct *
parseSWF_DEFINELOSSLESS2(FILE * f,int length)2156 parseSWF_DEFINELOSSLESS2 (FILE * f, int length)
2157 {
2158   int end = fileOffset + length;
2159   PAR_BEGIN (SWF_DEFINELOSSLESS2);
2160 
2161   parserrec->CharacterID = readUInt16 (f);
2162   parserrec->BitmapFormat = readUInt8 (f);
2163   parserrec->BitmapWidth = readUInt16 (f);
2164   parserrec->BitmapHeight = readUInt16 (f);
2165   if( parserrec->BitmapFormat == 3 /* 8-bit */ ) {
2166       parserrec->BitmapColorTableSize = readUInt8 (f);
2167   }
2168   parserrec->ZlibBitmapData = (UI8 *)readBytes (f,end-fileOffset);
2169 
2170   PAR_END;
2171 }
2172 
2173 SWF_Parserstruct *
parseSWF_DEFINEMORPHSHAPE(FILE * f,int length)2174 parseSWF_DEFINEMORPHSHAPE (FILE * f, int length)
2175 {
2176   int end, endEdges;
2177   PAR_BEGIN (SWF_DEFINEMORPHSHAPE);
2178   end = fileOffset + length;
2179   parserrec->CharacterID = readUInt16 (f);
2180   parseSWF_RECT (f, &(parserrec->StartBounds));
2181   parseSWF_RECT (f, &(parserrec->EndBounds));
2182 
2183   parserrec->Offset = readUInt32 (f);
2184   endEdges = fileOffset + parserrec->Offset;
2185 
2186   parseSWF_MORPHFILLSTYLES (f, &(parserrec->MorphFillStyles));
2187   parseSWF_MORPHLINESTYLES (f, &(parserrec->MorphLineStyles), 1);
2188 
2189   if(parserrec->Offset == 0)
2190     SWF_error("parseSWF_DEFINEMORPHSHAPE: offset == 0!\n");
2191 
2192   parseSWF_SHAPE (f, &(parserrec->StartEdges), 0, endEdges - fileOffset);
2193   parseSWF_SHAPE (f, &(parserrec->EndEdges), 0, end - fileOffset);
2194 
2195   PAR_END;
2196 }
2197 
2198 SWF_Parserstruct *
parseSWF_DEFINEMORPHSHAPE2(FILE * f,int length)2199 parseSWF_DEFINEMORPHSHAPE2 (FILE * f, int length)
2200 {
2201   int end, endEdges;
2202   PAR_BEGIN (SWF_DEFINEMORPHSHAPE2);
2203   end = fileOffset + length;
2204 
2205   parserrec->CharacterID = readUInt16 (f);
2206   parseSWF_RECT (f, &(parserrec->StartBounds));
2207   parseSWF_RECT (f, &(parserrec->EndBounds));
2208   parseSWF_RECT (f, &(parserrec->StartEdgeBounds));
2209   parseSWF_RECT (f, &(parserrec->EndEdgeBounds));
2210   parserrec->Reserved = readBits(f, 6);
2211   parserrec->UsesNonScalingStrokes = readBits(f, 1);
2212   parserrec->UsesScalingStrokes = readBits(f, 1);
2213 
2214   parserrec->Offset = readUInt32 (f);
2215   endEdges = fileOffset + parserrec->Offset + 4;
2216   parseSWF_MORPHFILLSTYLES (f, &(parserrec->MorphFillStyles));
2217   parseSWF_MORPHLINESTYLES (f, &(parserrec->MorphLineStyles), 2);
2218 
2219   if(parserrec->Offset == 0)
2220     SWF_error("parseSWF_DEFINEMORPHSHAPE2: offset == 0!\n");
2221 
2222   parseSWF_SHAPE (f, &(parserrec->StartEdges), 0, endEdges - fileOffset);
2223   parseSWF_SHAPE (f, &(parserrec->EndEdges), 0, end - fileOffset);
2224 
2225   PAR_END;
2226 }
2227 
2228 SWF_Parserstruct *
parseSWF_DEFINESHAPE(FILE * f,int length)2229 parseSWF_DEFINESHAPE (FILE * f, int length)
2230 {
2231   PAR_BEGIN (SWF_DEFINESHAPE);
2232 
2233   parserrec->ShapeID = readUInt16 (f);
2234   parseSWF_RECT (f, &(parserrec->ShapeBounds));
2235   parseSWF_SHAPEWITHSTYLE (f, &(parserrec->Shapes), 1);
2236 
2237   PAR_END;
2238 }
2239 
2240 SWF_Parserstruct *
parseSWF_DEFINESHAPE2(FILE * f,int length)2241 parseSWF_DEFINESHAPE2 (FILE * f, int length)
2242 {
2243   PAR_BEGIN (SWF_DEFINESHAPE2);
2244 
2245   parserrec->ShapeID = readUInt16 (f);
2246   parseSWF_RECT (f, &(parserrec->ShapeBounds));
2247   parseSWF_SHAPEWITHSTYLE (f, &(parserrec->Shapes), 2);
2248 
2249   PAR_END;
2250 }
2251 
2252 SWF_Parserstruct *
parseSWF_DEFINESHAPE3(FILE * f,int length)2253 parseSWF_DEFINESHAPE3 (FILE * f, int length)
2254 {
2255   PAR_BEGIN (SWF_DEFINESHAPE3);
2256 
2257   parserrec->ShapeID = readUInt16 (f);
2258   parseSWF_RECT (f, &(parserrec->ShapeBounds));
2259   parseSWF_SHAPEWITHSTYLE (f, &(parserrec->Shapes), 3);
2260 
2261   PAR_END;
2262 }
2263 
2264 SWF_Parserstruct *
parseSWF_DEFINESHAPE4(FILE * f,int length)2265 parseSWF_DEFINESHAPE4 (FILE * f, int length)
2266 {
2267   PAR_BEGIN (SWF_DEFINESHAPE4);
2268 
2269   parserrec->ShapeID = readUInt16 (f);
2270   parseSWF_RECT (f, &(parserrec->ShapeBounds));
2271   parseSWF_RECT (f, &(parserrec->EdgeBounds));
2272   parserrec->Reserved = readBits(f, 6);
2273   parserrec->UsesNonScalingStrokes = readBits(f, 1);
2274   parserrec->UsesScalingStrokes = readBits(f, 1);
2275   parseSWF_SHAPEWITHSTYLE (f, &(parserrec->Shapes), 4);
2276 
2277   PAR_END;
2278 }
2279 
2280 
2281 SWF_Parserstruct *
parseSWF_DEFINESPRITE(FILE * f,int length)2282 parseSWF_DEFINESPRITE (FILE * f, int length)
2283 {
2284   int block, type, splength, blockstart, nextFrame;
2285   int numblocks, start;
2286   PAR_BEGIN (SWF_DEFINESPRITE);
2287 
2288   numblocks=0;
2289   start = fileOffset;
2290   parserrec->SpriteId = readUInt16 (f);
2291   parserrec->FrameCount = readUInt16 (f);
2292   parserrec->tagTypes = NULL;
2293   parserrec->Tags = NULL;
2294   while( fileOffset < start+length ) {
2295 	  /*
2296 	  printf ("Block offset: %d\n", fileOffset);
2297 	  */
2298 	  block = readUInt16 (f);
2299 	  type = block >> 6;
2300 	  splength = block & ((1 << 6) - 1);
2301 	  if (splength == 63)         /* it's a long block. */
2302 		    splength = readUInt32 (f);
2303 	  blockstart = fileOffset;
2304 	  nextFrame = fileOffset+splength;
2305           /*
2306 	  printf ("Found Block: %s, %i bytes @%i\n",
2307 			  blockName (type), splength, blockstart );
2308           */
2309 	  parserrec->tagTypes = (UI16 *)
2310 	  	realloc(parserrec->tagTypes, ((numblocks+1)*sizeof(UI16)));
2311 	  parserrec->Tags = (SWF_Parserstruct **)
2312 	  	realloc(parserrec->Tags,
2313 				((numblocks+1)*sizeof(SWF_Parserstruct *)));
2314 
2315 	  parserrec->tagTypes[numblocks] = type;
2316 	  parserrec->Tags[numblocks++]=blockParse(f,splength,type);
2317 	  if( ftell(f) != nextFrame ) {
2318 	    SWF_warn(" Sprite Stream out of sync...\n");
2319 	    SWF_warn(" %ld but expecting %d\n", ftell(f),nextFrame);
2320 	    fseek(f,blockstart,SEEK_SET);
2321 	    silentSkipBytes (f, (nextFrame-ftell(f)));
2322 	    fileOffset=ftell(f);
2323 	  }
2324 	  if(type == 0)
2325 		break;
2326   }
2327   if(fileOffset < start + length)
2328   {
2329     SWF_warn("PARSER: parseSWF_DEFINESPRITE (ID %i): skiping excessive bytes after SWF_END.\n",
2330 	parserrec->SpriteId);
2331     readBytes(f, start + length - fileOffset);
2332   }
2333   parserrec->BlockCount = numblocks;
2334 
2335   PAR_END;
2336 }
2337 
2338 SWF_Parserstruct *
parseSWF_DEFINETEXT(FILE * f,int length)2339 parseSWF_DEFINETEXT (FILE * f, int length)
2340 {
2341   PAR_BEGIN (SWF_DEFINETEXT);
2342 
2343   parserrec->CharacterID = readUInt16 (f);
2344   parseSWF_RECT (f, &(parserrec->TextBounds));
2345   parseSWF_MATRIX (f, &(parserrec->TextMatrix));
2346   parserrec->GlyphBits = readUInt8 (f);
2347   parserrec->AdvanceBits = readUInt8 (f);
2348 
2349   parserrec->TextRecords =
2350     (SWF_TEXTRECORD *) calloc (1, sizeof (SWF_TEXTRECORD));
2351   parserrec->numTextRecords = 0;
2352   while ( parseSWF_TEXTRECORD (f, &(parserrec->TextRecords[parserrec->numTextRecords++]), parserrec->GlyphBits, parserrec->AdvanceBits, 1 ) ) {
2353       parserrec->TextRecords = (SWF_TEXTRECORD *) realloc (parserrec->TextRecords,
2354 							 (parserrec->
2355 							  numTextRecords +
2356 							  1) *
2357 							 sizeof
2358 							 (SWF_TEXTRECORD));
2359     }
2360 
2361   PAR_END;
2362 }
2363 
2364 SWF_Parserstruct *
parseSWF_DEFINETEXT2(FILE * f,int length)2365 parseSWF_DEFINETEXT2 (FILE * f, int length)
2366 {
2367   PAR_BEGIN (SWF_DEFINETEXT2);
2368 
2369   parserrec->CharacterID = readUInt16 (f);
2370   parseSWF_RECT (f, &(parserrec->TextBounds));
2371   parseSWF_MATRIX (f, &(parserrec->TextMatrix));
2372   parserrec->GlyphBits = readUInt8 (f);
2373   parserrec->AdvanceBits = readUInt8 (f);
2374 
2375   parserrec->TextRecords =
2376     (SWF_TEXTRECORD *) calloc (1, sizeof (SWF_TEXTRECORD));
2377   parserrec->numTextRecords = 0;
2378   while ( parseSWF_TEXTRECORD (f, &(parserrec->TextRecords[parserrec->numTextRecords++]), parserrec->GlyphBits, parserrec->AdvanceBits, 2 ) ) {
2379       parserrec->TextRecords = (SWF_TEXTRECORD *) realloc (parserrec->TextRecords,
2380 							 (parserrec->
2381 							  numTextRecords +
2382 							  1) *
2383 							 sizeof
2384 							 (SWF_TEXTRECORD));
2385     }
2386 
2387   PAR_END;
2388 }
2389 
2390 SWF_Parserstruct *
parseSWF_DEFINETEXTFORMAT(FILE * f,int length)2391 parseSWF_DEFINETEXTFORMAT (FILE * f, int length)
2392 {
2393   PAR_BEGIN (SWF_DEFINETEXTFORMAT);
2394   SKIP;
2395   PAR_END;
2396 }
2397 
2398 SWF_Parserstruct *
parseSWF_DEFINEVIDEO(FILE * f,int length)2399 parseSWF_DEFINEVIDEO (FILE * f, int length)
2400 {
2401   PAR_BEGIN (SWF_DEFINEVIDEO);
2402   SKIP;
2403   PAR_END;
2404 }
2405 
2406 SWF_Parserstruct *
parseSWF_DEFINEVIDEOSTREAM(FILE * f,int length)2407 parseSWF_DEFINEVIDEOSTREAM (FILE * f, int length)
2408 {
2409   PAR_BEGIN (SWF_DEFINEVIDEOSTREAM);
2410 
2411   parserrec->CharacterID = readUInt16 (f);
2412   parserrec->NumFrames = readUInt16(f);
2413   parserrec->Width = readUInt16(f);
2414   parserrec->Height = readUInt16(f);
2415   byteAlign ();
2416   parserrec->Reserved = readBits (f, 5);
2417   parserrec->VideoFlagsDeblocking = readBits (f, 2);
2418   parserrec->VideoFlagsSmoothing = readBits(f, 1);
2419   parserrec->CodecID = readUInt8(f);
2420 
2421   PAR_END;
2422 }
2423 
2424 SWF_Parserstruct *
parseSWF_DOACTION(FILE * f,int length)2425 parseSWF_DOACTION (FILE * f, int length)
2426 {
2427   int end = fileOffset + length;
2428   PAR_BEGIN (SWF_DOACTION);
2429 
2430   parserrec->Actions =
2431     (SWF_ACTION *) calloc (1, sizeof (SWF_ACTION));
2432   parserrec->numActions = 0;
2433   while ( fileOffset < end ) {
2434       parseSWF_ACTIONRECORD (f, &(parserrec->numActions), parserrec->Actions );
2435       parserrec->Actions = (SWF_ACTION *) realloc (parserrec->Actions,
2436 							 (++parserrec->
2437 							  numActions +
2438 							  1) *
2439 							 sizeof
2440 							 (SWF_ACTION));
2441     }
2442 
2443   /* parserrec->AScript = decompile5Action (f, length, 1); */
2444 
2445   PAR_END;
2446 }
2447 
2448 SWF_Parserstruct *
parseSWF_ENABLEDEBUGGER(FILE * f,int length)2449 parseSWF_ENABLEDEBUGGER (FILE * f, int length)
2450 {
2451   PAR_BEGIN (SWF_ENABLEDEBUGGER);
2452   parserrec->Password = readString(f);
2453   PAR_END;
2454 }
2455 
2456 SWF_Parserstruct *
parseSWF_ENABLEDEBUGGER2(FILE * f,int length)2457 parseSWF_ENABLEDEBUGGER2 (FILE * f, int length)
2458 {
2459   PAR_BEGIN (SWF_ENABLEDEBUGGER2);
2460   parserrec->Reserved = readUInt16(f);
2461   parserrec->Password = readString(f);
2462   PAR_END;
2463 }
2464 
2465 
2466 SWF_Parserstruct *
parseSWF_END(FILE * f,int length)2467 parseSWF_END (FILE * f, int length)
2468 {
2469   PAR_BEGIN (SWF_END);
2470 
2471   PAR_END;
2472 }
2473 
2474 SWF_Parserstruct *
parseSWF_EXPORTASSETS(FILE * f,int length)2475 parseSWF_EXPORTASSETS (FILE * f, int length)
2476 {
2477   int i;
2478   PAR_BEGIN (SWF_EXPORTASSETS);
2479 
2480   parserrec->Count = readUInt16 (f);
2481   parserrec->Tags = (UI16 *)malloc(parserrec->Count*sizeof(UI16));
2482   parserrec->Names = (STRING *)malloc(parserrec->Count*sizeof(char *));
2483   for(i=0;i<parserrec->Count;i++) {
2484 	parserrec->Tags[i] = readUInt16(f);
2485 	parserrec->Names[i] = readString(f);
2486   }
2487 
2488   PAR_END;
2489 }
2490 
2491 SWF_Parserstruct *
parseSWF_FONTREF(FILE * f,int length)2492 parseSWF_FONTREF (FILE * f, int length)
2493 {
2494   PAR_BEGIN (SWF_FONTREF);
2495   SKIP;
2496   PAR_END;
2497 }
2498 
2499 SWF_Parserstruct *
parseSWF_FRAMELABEL(FILE * f,int length)2500 parseSWF_FRAMELABEL (FILE * f, int length)
2501 {
2502   PAR_BEGIN (SWF_FRAMELABEL);
2503 
2504   parserrec->Name = readString (f);
2505 
2506   // SWF6 named anchor
2507   if ( strlen(parserrec->Name)+1 == length-1 )
2508   {
2509     parserrec->IsAnchor = readUInt8(f);
2510   }
2511 
2512   PAR_END;
2513 }
2514 
2515 SWF_Parserstruct *
parseSWF_FRAMETAG(FILE * f,int length)2516 parseSWF_FRAMETAG (FILE * f, int length)
2517 {
2518   PAR_BEGIN (SWF_FRAMETAG);
2519   SKIP;
2520   PAR_END;
2521 }
2522 
2523 SWF_Parserstruct *
parseSWF_FREEALL(FILE * f,int length)2524 parseSWF_FREEALL (FILE * f, int length)
2525 {
2526   PAR_BEGIN (SWF_FREEALL);
2527   SKIP;
2528   PAR_END;
2529 }
2530 
2531 SWF_Parserstruct *
parseSWF_FREECHARACTER(FILE * f,int length)2532 parseSWF_FREECHARACTER (FILE * f, int length)
2533 {
2534   PAR_BEGIN (SWF_FREECHARACTER);
2535   SKIP;
2536   PAR_END;
2537 }
2538 
2539 SWF_Parserstruct *
parseSWF_GENCOMMAND(FILE * f,int length)2540 parseSWF_GENCOMMAND (FILE * f, int length)
2541 {
2542   PAR_BEGIN (SWF_GENCOMMAND);
2543   SKIP;
2544   PAR_END;
2545 }
2546 
2547 SWF_Parserstruct *
parseSWF_IMPORTASSETS(FILE * f,int length)2548 parseSWF_IMPORTASSETS (FILE * f, int length)
2549 {
2550   int i;
2551   PAR_BEGIN (SWF_IMPORTASSETS);
2552 
2553   parserrec->URL = readString (f);
2554   parserrec->Count = readUInt16 (f);
2555   parserrec->Tags = (UI16 *)malloc(parserrec->Count*sizeof(UI16));
2556   parserrec->Names = (STRING *)malloc(parserrec->Count*sizeof(char *));
2557   for(i=0;i<parserrec->Count;i++) {
2558 	parserrec->Tags[i] = readUInt16(f);
2559 	parserrec->Names[i] = readString(f);
2560   }
2561 
2562   PAR_END;
2563 }
2564 
2565 SWF_Parserstruct *
parseSWF_IMPORTASSETS2(FILE * f,int length)2566 parseSWF_IMPORTASSETS2 (FILE * f, int length)
2567 {
2568   int i;
2569   PAR_BEGIN (SWF_IMPORTASSETS2);
2570 
2571   parserrec->URL = readString (f);
2572   parserrec->Reserved = readUInt8(f);
2573   parserrec->Reserved2 = readUInt8(f);
2574   parserrec->Count = readUInt16 (f);
2575   parserrec->Tags = (UI16 *)malloc(parserrec->Count*sizeof(UI16));
2576   parserrec->Names = (STRING *)malloc(parserrec->Count*sizeof(char *));
2577   for(i=0;i<parserrec->Count;i++) {
2578 	parserrec->Tags[i] = readUInt16(f);
2579 	parserrec->Names[i] = readString(f);
2580   }
2581 
2582   PAR_END;
2583 }
2584 
2585 SWF_Parserstruct *
parseSWF_JPEGTABLES(FILE * f,int length)2586 parseSWF_JPEGTABLES (FILE * f, int length)
2587 {
2588   int end = fileOffset + length;
2589   PAR_BEGIN (SWF_JPEGTABLES);
2590 
2591   parserrec->JPEGDataSize = end-fileOffset;
2592   parserrec->JPEGData = (UI8 *)readBytes(f,end-fileOffset);
2593 
2594   PAR_END;
2595 }
2596 
2597 SWF_Parserstruct *
parseSWF_NAMECHARACTER(FILE * f,int length)2598 parseSWF_NAMECHARACTER (FILE * f, int length)
2599 {
2600   PAR_BEGIN (SWF_NAMECHARACTER);
2601   parserrec->Id = readUInt16(f);
2602   parserrec->Name = readString(f);
2603   PAR_END;
2604 }
2605 
2606 SWF_Parserstruct *
parseSWF_PATHSAREPOSTSCRIPT(FILE * f,int length)2607 parseSWF_PATHSAREPOSTSCRIPT (FILE * f, int length)
2608 {
2609   PAR_BEGIN (SWF_PATHSAREPOSTSCRIPT);
2610   SKIP;
2611   PAR_END;
2612 }
2613 
2614 SWF_Parserstruct *
parseSWF_PLACEOBJECT(FILE * f,int length)2615 parseSWF_PLACEOBJECT (FILE * f, int length)
2616 {
2617   int end = fileOffset + length;
2618   PAR_BEGIN (SWF_PLACEOBJECT);
2619 
2620   parserrec->CharacterId = readUInt16 (f);
2621   parserrec->Depth = readUInt16 (f);
2622   parseSWF_MATRIX( f, &(parserrec->Matrix) );
2623 
2624   if(end > fileOffset)
2625     parseSWF_CXFORMWITHALPHA( f, &(parserrec->ColorTransform) );
2626 
2627   PAR_END;
2628 }
2629 
2630 SWF_Parserstruct *
parseSWF_PLACEOBJECT2(FILE * f,int length)2631 parseSWF_PLACEOBJECT2 (FILE * f, int length)
2632 {
2633   PAR_BEGIN (SWF_PLACEOBJECT2);
2634 
2635   byteAlign();
2636   int end = fileOffset + length;
2637   parserrec->PlaceFlagHasClipActions = readBits (f, 1);
2638   parserrec->PlaceFlagHasClipDepth   = readBits (f, 1);
2639   parserrec->PlaceFlagHasName        = readBits (f, 1);
2640   parserrec->PlaceFlagHasRatio       = readBits (f, 1);
2641   parserrec->PlaceFlagHasColorTransform = readBits (f, 1);
2642   parserrec->PlaceFlagHasMatrix      = readBits (f, 1);
2643   parserrec->PlaceFlagHasCharacter   = readBits (f, 1);
2644   parserrec->PlaceFlagMove           = readBits (f, 1);
2645   parserrec->Depth = readUInt16 (f);
2646   if( parserrec->PlaceFlagHasCharacter ) {
2647     parserrec->CharacterId = readUInt16 (f);
2648   }
2649   if( parserrec->PlaceFlagHasMatrix ) {
2650     parseSWF_MATRIX( f, &(parserrec->Matrix) );
2651   }
2652   if( parserrec->PlaceFlagHasColorTransform ) {
2653     parseSWF_CXFORMWITHALPHA( f, &(parserrec->ColorTransform) );
2654   }
2655   if( parserrec->PlaceFlagHasRatio ) {
2656     parserrec->Ratio = readUInt16 (f);
2657   }
2658   if( parserrec->PlaceFlagHasName ) {
2659     parserrec->Name = readString (f);
2660   }
2661   if( parserrec->PlaceFlagHasClipDepth ) {
2662     parserrec->ClipDepth = readUInt16 (f);
2663   }
2664   if( parserrec->PlaceFlagHasClipActions ) {
2665     parseSWF_CLIPACTIONS( f, &(parserrec->ClipActions), end);
2666   }
2667 
2668   PAR_END;
2669 }
2670 
2671 SWF_Parserstruct *
parseSWF_PLACEOBJECT3(FILE * f,int length)2672 parseSWF_PLACEOBJECT3 (FILE * f, int length)
2673 {
2674   PAR_BEGIN (SWF_PLACEOBJECT3);
2675 
2676   byteAlign();
2677   int end = fileOffset + length;
2678   parserrec->PlaceFlagHasClipActions = readBits (f, 1);
2679   parserrec->PlaceFlagHasClipDepth   = readBits (f, 1);
2680   parserrec->PlaceFlagHasName        = readBits (f, 1);
2681   parserrec->PlaceFlagHasRatio       = readBits (f, 1);
2682   parserrec->PlaceFlagHasColorTransform = readBits (f, 1);
2683   parserrec->PlaceFlagHasMatrix      = readBits (f, 1);
2684   parserrec->PlaceFlagHasCharacter   = readBits (f, 1);
2685   parserrec->PlaceFlagMove           = readBits (f, 1);
2686 
2687   byteAlign();
2688   parserrec->Reserved                = readBits (f, 3);
2689   parserrec->PlaceFlagHasImage       = readBits (f, 1);
2690   parserrec->PlaceFlagHasClassName   = readBits (f, 1);
2691   parserrec->PlaceFlagHasCacheAsBitmap = readBits (f, 1);
2692   parserrec->PlaceFlagHasBlendMode   = readBits(f, 1);
2693   parserrec->PlaceFlagHasFilterList  = readBits(f, 1);
2694 
2695   parserrec->Depth = readUInt16 (f);
2696   if( parserrec->PlaceFlagHasCharacter ) {
2697     parserrec->CharacterId = readUInt16 (f);
2698   }
2699 
2700   if(parserrec->PlaceFlagHasClassName ||
2701       (parserrec->PlaceFlagHasImage && parserrec->PlaceFlagHasCharacter))
2702   {
2703     parserrec->ClassName = readString(f);
2704   }
2705 
2706   if( parserrec->PlaceFlagHasMatrix ) {
2707     parseSWF_MATRIX( f, &(parserrec->Matrix) );
2708   }
2709   if( parserrec->PlaceFlagHasColorTransform ) {
2710     parseSWF_CXFORMWITHALPHA( f, &(parserrec->ColorTransform) );
2711   }
2712   if( parserrec->PlaceFlagHasRatio ) {
2713     parserrec->Ratio = readUInt16 (f);
2714   }
2715   if( parserrec->PlaceFlagHasName ) {
2716     parserrec->Name = readString (f);
2717   }
2718   if( parserrec->PlaceFlagHasClipDepth ) {
2719     parserrec->ClipDepth = readUInt16 (f);
2720   }
2721   if( parserrec->PlaceFlagHasFilterList ) {
2722     parseSWF_FILTERLIST( f, &parserrec->SurfaceFilterList);
2723   }
2724   if( parserrec->PlaceFlagHasBlendMode ) {
2725     parserrec->BlendMode = readUInt8 (f);
2726   }
2727   if( parserrec->PlaceFlagHasClipActions ) {
2728     parseSWF_CLIPACTIONS( f, &(parserrec->ClipActions), end);
2729   }
2730 
2731   PAR_END;
2732 }
2733 
2734 SWF_Parserstruct *
parseSWF_PREBUILT(FILE * f,int length)2735 parseSWF_PREBUILT (FILE * f, int length)
2736 {
2737   PAR_BEGIN (SWF_PREBUILT);
2738   SKIP;
2739   PAR_END;
2740 }
2741 
2742 SWF_Parserstruct *
parseSWF_PREBUILTCLIP(FILE * f,int length)2743 parseSWF_PREBUILTCLIP (FILE * f, int length)
2744 {
2745   PAR_BEGIN (SWF_PREBUILTCLIP);
2746   SKIP;
2747   PAR_END;
2748 }
2749 
2750 SWF_Parserstruct *
parseSWF_PROTECT(FILE * f,int length)2751 parseSWF_PROTECT (FILE * f, int length)
2752 {
2753   PAR_BEGIN (SWF_PROTECT);
2754 
2755   if( length != 0 ) {
2756   	parserrec->Password = readString (f);
2757   } else {
2758   	parserrec->Password = NULL;
2759   }
2760 
2761   PAR_END;
2762 }
2763 
2764 SWF_Parserstruct *
parseSWF_REMOVEOBJECT(FILE * f,int length)2765 parseSWF_REMOVEOBJECT (FILE * f, int length)
2766 {
2767   PAR_BEGIN (SWF_REMOVEOBJECT);
2768 
2769   parserrec->CharacterId = readUInt16 (f);
2770   parserrec->Depth = readUInt16 (f);
2771 
2772   PAR_END;
2773 }
2774 
2775 SWF_Parserstruct *
parseSWF_REMOVEOBJECT2(FILE * f,int length)2776 parseSWF_REMOVEOBJECT2 (FILE * f, int length)
2777 {
2778   PAR_BEGIN (SWF_REMOVEOBJECT2);
2779 
2780   parserrec->Depth = readUInt16 (f);
2781 
2782   PAR_END;
2783 }
2784 
2785 SWF_Parserstruct *
parseSWF_SERIALNUMBER(FILE * f,int length)2786 parseSWF_SERIALNUMBER (FILE * f, int length)
2787 {
2788   PAR_BEGIN (SWF_SERIALNUMBER);
2789   parserrec->Id = readUInt32(f);
2790   parserrec->Edition = readUInt32(f);
2791   parserrec->Major = readUInt8(f);
2792   parserrec->Minor = readUInt8(f);
2793   parserrec->BuildL = readUInt32(f);
2794   parserrec->BuildH = readUInt32(f);
2795   parserrec->TimestampL = readUInt32(f);
2796   parserrec->TimestampH = readUInt32(f);
2797   PAR_END;
2798 }
2799 
2800 SWF_Parserstruct *
parseSWF_SETBACKGROUNDCOLOR(FILE * f,int length)2801 parseSWF_SETBACKGROUNDCOLOR (FILE * f, int length)
2802 {
2803   PAR_BEGIN (SWF_SETBACKGROUNDCOLOR);
2804 
2805   parseSWF_RGB (f, &parserrec->rgb);
2806 
2807   PAR_END;
2808 }
2809 
2810 SWF_Parserstruct *
parseSWF_SHOWFRAME(FILE * f,int length)2811 parseSWF_SHOWFRAME (FILE * f, int length)
2812 {
2813   PAR_BEGIN (SWF_SHOWFRAME);
2814 
2815   PAR_END;
2816 }
2817 
2818 static inline void
parseMp3Stream(FILE * f,struct MP3STREAMSOUNDDATA * data,int blockEnd)2819 parseMp3Stream(FILE *f, struct MP3STREAMSOUNDDATA *data, int blockEnd)
2820 {
2821   data->SampleCount = readUInt16(f);
2822   data->SeekSamples = readSInt16(f);
2823   data->frames = (UI8 *)readBytes(f, blockEnd - fileOffset);
2824 }
2825 
2826 SWF_Parserstruct *
parseSWF_SOUNDSTREAMBLOCK(FILE * f,int length)2827 parseSWF_SOUNDSTREAMBLOCK (FILE * f, int length)
2828 {
2829   int end = fileOffset + length;
2830   PAR_BEGIN (SWF_SOUNDSTREAMBLOCK);
2831   switch(m.soundStreamFmt)
2832   {
2833     case 2:
2834       parseMp3Stream(f, &parserrec->StreamData.mp3, end);
2835       break;
2836     default:
2837       parserrec->StreamData.data = (UI8 *)readBytes(f, end - fileOffset);
2838   }
2839   PAR_END;
2840 }
2841 
2842 SWF_Parserstruct *
parseSWF_SOUNDSTREAMHEAD(FILE * f,int length)2843 parseSWF_SOUNDSTREAMHEAD (FILE * f, int length)
2844 {
2845   PAR_BEGIN (SWF_SOUNDSTREAMHEAD);
2846 
2847   byteAlign ();
2848   parserrec->Reserved = readBits (f, 4);
2849   parserrec->PlaybackSoundRate = readBits (f, 2);
2850   parserrec->PlaybackSoundSize = readBits (f, 1);
2851   parserrec->PlaybackSoundType = readBits (f, 1);
2852   parserrec->StreamSoundCompression = readBits (f, 4);
2853   parserrec->StreamSoundRate = readBits (f, 2);
2854   parserrec->StreamSoundSize = readBits (f, 1);
2855   parserrec->StreamSoundType = readBits (f, 1);
2856   parserrec->StreamSoundSampleCount = readUInt16 (f);
2857   if( parserrec->StreamSoundCompression == 2 /* MP3 */ )
2858     parserrec->LatencySeek = readUInt16 (f);
2859   m.soundStreamFmt = parserrec->StreamSoundCompression;
2860   PAR_END;
2861 }
2862 
2863 SWF_Parserstruct *
parseSWF_SOUNDSTREAMHEAD2(FILE * f,int length)2864 parseSWF_SOUNDSTREAMHEAD2 (FILE * f, int length)
2865 {
2866   PAR_BEGIN (SWF_SOUNDSTREAMHEAD2);
2867 
2868   byteAlign ();
2869   parserrec->Reserved = readBits (f, 4);
2870   parserrec->PlaybackSoundRate = readBits (f, 2);
2871   parserrec->PlaybackSoundSize = readBits (f, 1);
2872   parserrec->PlaybackSoundType = readBits (f, 1);
2873   parserrec->StreamSoundCompression = readBits (f, 4);
2874   parserrec->StreamSoundRate = readBits (f, 2);
2875   parserrec->StreamSoundSize = readBits (f, 1);
2876   parserrec->StreamSoundType = readBits (f, 1);
2877   parserrec->StreamSoundSampleCount = readUInt16 (f);
2878   if( parserrec->StreamSoundCompression == 2 /* MP3 */ )
2879     parserrec->LatencySeek = readUInt16 (f);
2880   m.soundStreamFmt = parserrec->StreamSoundCompression;
2881   PAR_END;
2882 }
2883 
2884 SWF_Parserstruct *
parseSWF_DEFINESOUND(FILE * f,int length)2885 parseSWF_DEFINESOUND (FILE * f, int length)
2886 {
2887   int end = fileOffset + length;
2888   PAR_BEGIN (SWF_DEFINESOUND);
2889 
2890   parserrec->SoundId = readUInt16 (f);
2891   parserrec->SoundFormat = readBits (f, 4);
2892   parserrec->SoundRate = readBits (f, 2);
2893   parserrec->SoundSize = readBits (f, 1);
2894   parserrec->SoundType = readBits (f, 1);
2895   byteAlign ();
2896   parserrec->SoundSampleCount = readUInt32 (f);
2897 
2898   switch(parserrec->SoundFormat)
2899   {
2900     case 2:
2901       parserrec->SoundData.mp3.SeekSamples = readSInt16(f);
2902       parserrec->SoundData.mp3.frames = (UI8 *)readBytes(f, end - fileOffset);
2903       break;
2904     default:
2905       parserrec->SoundData.data = (UI8 *)readBytes(f, end - fileOffset);
2906   }
2907   PAR_END;
2908 }
2909 
parseSWF_SOUNDINFO(FILE * f,struct SWF_SOUNDINFO * si)2910 void parseSWF_SOUNDINFO(FILE *f, struct SWF_SOUNDINFO *si)
2911 {
2912   int i;
2913 
2914   si->Reserved = readBits (f, 2);
2915   si->SyncStop = readBits (f, 1);
2916   si->SyncNoMultiple = readBits (f, 1);
2917   si->HasEnvelope = readBits (f, 1);
2918   si->HasLoops = readBits (f, 1);
2919   si->HasOutPoint = readBits (f, 1);
2920   si->HasInPoint = readBits (f, 1);
2921   if( si->HasInPoint )
2922     si->InPoint = readUInt32 (f);
2923   if( si->HasOutPoint )
2924     si->OutPoint = readUInt32 (f);
2925   if( si->HasLoops )
2926     si->LoopCount = readUInt16 (f);
2927   if( si->HasEnvelope ) {
2928     si->EnvPoints = readUInt8 (f);
2929     si->EnvelopeRecords =
2930     (SWF_SOUNDENVELOPE *) calloc (si->EnvPoints, sizeof (SWF_SOUNDENVELOPE));
2931     for(i=0;i<si->EnvPoints;i++) {
2932     	si->EnvelopeRecords[i].Pos44 = readUInt32 (f);
2933     	si->EnvelopeRecords[i].LeftLevel = readUInt16 (f);
2934     	si->EnvelopeRecords[i].RightLevel = readUInt16 (f);
2935     	}
2936     }
2937 }
2938 
2939 SWF_Parserstruct *
parseSWF_STARTSOUND(FILE * f,int length)2940 parseSWF_STARTSOUND (FILE * f, int length)
2941 {
2942   PAR_BEGIN (SWF_STARTSOUND);
2943 
2944   parserrec->SoundId = readUInt16 (f);
2945   parseSWF_SOUNDINFO(f, &parserrec->SoundInfo);
2946 
2947   PAR_END;
2948 }
2949 
2950 SWF_Parserstruct *
parseSWF_STARTSOUND2(FILE * f,int length)2951 parseSWF_STARTSOUND2 (FILE * f, int length)
2952 {
2953   PAR_BEGIN (SWF_STARTSOUND2);
2954 
2955   parserrec->SoundClassName = readString (f);
2956   parseSWF_SOUNDINFO(f, &parserrec->SoundInfo);
2957 
2958   PAR_END;
2959 }
2960 
2961 SWF_Parserstruct *
parseSWF_SYNCFRAME(FILE * f,int length)2962 parseSWF_SYNCFRAME (FILE * f, int length)
2963 {
2964   PAR_BEGIN (SWF_SYNCFRAME);
2965   SKIP;
2966   PAR_END;
2967 }
2968 
2969 SWF_Parserstruct *
parseSWF_INITACTION(FILE * f,int length)2970 parseSWF_INITACTION (FILE * f, int length)
2971 {
2972   int end = fileOffset + length;
2973   PAR_BEGIN (SWF_INITACTION);
2974 
2975   parserrec->SpriteId = readUInt16 (f);
2976   parserrec->Actions =
2977     (SWF_ACTION *) calloc (1, sizeof (SWF_ACTION));
2978   parserrec->numActions = 0;
2979   while ( fileOffset < end ) {
2980       parseSWF_ACTIONRECORD (f, &(parserrec->numActions), parserrec->Actions);
2981       parserrec->Actions = (SWF_ACTION *) realloc (parserrec->Actions,
2982 							 (++parserrec->
2983 							  numActions +
2984 							  1) *
2985 							 sizeof
2986 							 (SWF_ACTION));
2987     }
2988 
2989   /* parserrec->AScript = decompile5Action (f, length, 1); */
2990 
2991   PAR_END;
2992 }
2993 
2994 SWF_Parserstruct *
parseSWF_VIDEOFRAME(FILE * f,int length)2995 parseSWF_VIDEOFRAME (FILE * f, int length)
2996 {
2997   int end = fileOffset + length;
2998   PAR_BEGIN (SWF_VIDEOFRAME);
2999   parserrec->StreamID = readUInt16 (f);
3000   parserrec->FrameNum = readUInt16 (f);
3001   parserrec->VideoData = (UI8 *)readBytes(f, end - fileOffset);
3002   PAR_END;
3003 }
3004 
3005 SWF_Parserstruct *
parseSWF_REFLEX(FILE * f,int length)3006 parseSWF_REFLEX (FILE * f, int length)
3007 {
3008   PAR_BEGIN (SWF_REFLEX);
3009   parserrec->rfx[0] = readUInt8 (f);
3010   parserrec->rfx[1] = readUInt8 (f);
3011   parserrec->rfx[2] = readUInt8 (f);
3012   PAR_END;
3013 }
3014 
3015 SWF_Parserstruct *
parseSWF_FILEATTRIBUTES(FILE * f,int length)3016 parseSWF_FILEATTRIBUTES (FILE * f, int length)
3017 {
3018   PAR_BEGIN (SWF_FILEATTRIBUTES);
3019   byteAlign();
3020   parserrec->Reserved = readBits(f, 3);
3021   parserrec->HasMetadata = readBits(f, 1);
3022   parserrec->ActionScript3 = readBits(f, 1);
3023   parserrec->Reserved2 = readBits(f, 2);
3024   parserrec->UseNetwork = readBits(f, 1);
3025   parserrec->Reserved3 = readUInt16(f);
3026   parserrec->Reserved4 = readUInt8(f);
3027   PAR_END;
3028 }
3029 
3030 SWF_Parserstruct *
parseSWF_METADATA(FILE * f,int length)3031 parseSWF_METADATA (FILE * f, int length)
3032 {
3033   PAR_BEGIN(SWF_METADATA);
3034   parserrec->Metadata = readString(f);
3035   PAR_END;
3036 }
3037 
3038 SWF_Parserstruct *
parseSWF_SCRIPTLIMITS(FILE * f,int length)3039 parseSWF_SCRIPTLIMITS (FILE * f, int length)
3040 {
3041   PAR_BEGIN(SWF_SCRIPTLIMITS);
3042   parserrec->MaxRecursionDepth = readUInt16(f);
3043   parserrec->ScriptTimeoutSeconds = readUInt16(f);
3044   PAR_END;
3045 }
3046 
3047 SWF_Parserstruct *
parseSWF_DEFINESCALINGGRID(FILE * f,int length)3048 parseSWF_DEFINESCALINGGRID (FILE * f, int length)
3049 {
3050   PAR_BEGIN(SWF_DEFINESCALINGGRID);
3051   parserrec->CharacterId = readUInt16(f);
3052   parseSWF_RECT(f, &parserrec->Splitter);
3053   PAR_END;
3054 }
3055 
3056 SWF_Parserstruct *
parseSWF_SETTABINDEX(FILE * f,int length)3057 parseSWF_SETTABINDEX (FILE * f, int length)
3058 {
3059   PAR_BEGIN(SWF_SETTABINDEX);
3060   parserrec->Depth = readUInt16(f);
3061   parserrec->TabIndex = readUInt16(f);
3062   PAR_END;
3063 }
3064 
parseABC_STRING_INFO(struct ABC_STRING_INFO * sinfo,FILE * f)3065 void parseABC_STRING_INFO(struct ABC_STRING_INFO *sinfo, FILE *f)
3066 {
3067   sinfo->Size = readEncUInt30(f);
3068   sinfo->UTF8String = (UI8 *)readBytes(f, sinfo->Size);
3069 }
3070 
parseABC_NS_INFO(struct ABC_NS_INFO * nsinfo,FILE * f)3071 void parseABC_NS_INFO(struct ABC_NS_INFO *nsinfo, FILE *f)
3072 {
3073   nsinfo->Kind = readUInt8(f);
3074   nsinfo->Name = readEncUInt30(f);
3075 }
3076 
parseABC_NS_SET_INFO(struct ABC_NS_SET_INFO * nsset,FILE * f)3077 void parseABC_NS_SET_INFO(struct ABC_NS_SET_INFO *nsset, FILE *f)
3078 {
3079   int i;
3080   nsset->Count = readEncUInt30(f);
3081   nsset->NS = malloc(sizeof(U30) * nsset->Count);
3082   for(i = 0; i < nsset->Count; i++)
3083     nsset->NS[i] = readEncUInt30(f);
3084 }
3085 
parseABC_QNAME(struct ABC_QNAME * qname,FILE * f)3086 void parseABC_QNAME(struct ABC_QNAME *qname, FILE *f)
3087 {
3088   qname->NS = readEncUInt30(f);
3089   qname->Name = readEncUInt30(f);
3090 }
3091 
parseABC_RTQNAME(struct ABC_RTQNAME * rtq,FILE * f)3092 void parseABC_RTQNAME(struct ABC_RTQNAME *rtq, FILE *f)
3093 {
3094   rtq->Name = readEncUInt30(f);
3095 }
3096 
parseABC_RTQNAME_L(struct ABC_RTQNAME_L * rtql,FILE * f)3097 void parseABC_RTQNAME_L(struct ABC_RTQNAME_L *rtql, FILE *f)
3098 {
3099 
3100 }
3101 
parseABC_MULTINAME(struct ABC_MULTINAME * mn,FILE * f)3102 void parseABC_MULTINAME(struct ABC_MULTINAME *mn, FILE *f)
3103 {
3104   mn->Name = readEncUInt30(f);
3105   mn->NSSet = readEncUInt30(f);
3106 }
3107 
parseABC_MULTINAME_L(struct ABC_MULTINAME_L * mnl,FILE * f)3108 void parseABC_MULTINAME_L(struct ABC_MULTINAME_L *mnl, FILE *f)
3109 {
3110   mnl->NSSet = readEncUInt30(f);
3111 }
3112 
parseABC_MULTINAME_INFO(struct ABC_MULTINAME_INFO * minfo,FILE * f)3113 void parseABC_MULTINAME_INFO(struct ABC_MULTINAME_INFO *minfo, FILE *f)
3114 {
3115   minfo->Kind = readUInt8(f);
3116   switch(minfo->Kind)
3117   {
3118     case ABC_CONST_QNAME:
3119     case ABC_CONST_QNAME_A:
3120       parseABC_QNAME(&minfo->Data.QName, f);
3121       break;
3122     case ABC_CONST_RTQNAME:
3123     case ABC_CONST_RTQNAME_A:
3124       parseABC_RTQNAME(&minfo->Data.RTQName, f);
3125       break;
3126     case ABC_CONST_RTQNAME_L:
3127     case ABC_CONST_RTQNAME_LA:
3128       parseABC_RTQNAME_L(&minfo->Data.RTQNameL, f);
3129       break;
3130     case ABC_CONST_MULTINAME:
3131     case ABC_CONST_MULTINAME_A:
3132       parseABC_MULTINAME(&minfo->Data.Multiname, f);
3133       break;
3134     case ABC_CONST_MULTINAME_L:
3135     case ABC_CONST_MULTINAME_LA:
3136       parseABC_MULTINAME_L(&minfo->Data.MultinameL, f);
3137       break;
3138     default:
3139       SWF_error("Unknow multiname kind %x\n", minfo->Kind);
3140   }
3141 }
3142 
parseABC_CONSTANT_POOL(struct ABC_CONSTANT_POOL * cpool,FILE * f)3143 void parseABC_CONSTANT_POOL(struct ABC_CONSTANT_POOL *cpool, FILE *f)
3144 {
3145   int i;
3146   size_t s;
3147 
3148   cpool->IntCount = readEncUInt30(f);
3149   if (cpool->IntCount > INT_MAX / sizeof(S32))
3150     SWF_error("value is too big");
3151   cpool->Integers = malloc(cpool->IntCount * sizeof(S32));
3152   for(i = 1; i < cpool->IntCount; i++)
3153       cpool->Integers[i] = readEncSInt32(f);
3154 
3155   cpool->UIntCount = readEncUInt30(f);
3156   if (cpool->UIntCount > INT_MAX / sizeof(U32))
3157     SWF_error("value is too big");
3158   cpool->UIntegers = malloc(cpool->UIntCount * sizeof(U32));
3159   for(i = 1; i < cpool->UIntCount; i++)
3160     cpool->UIntegers[i] = readEncUInt32(f);
3161 
3162   cpool->DoubleCount = readEncUInt30(f);
3163   if (cpool->DoubleCount > INT_MAX / sizeof(DOUBLE))
3164     SWF_error("value is too big");
3165   cpool->Doubles = malloc(cpool->DoubleCount * sizeof(DOUBLE));
3166   for(i = 1; i < cpool->DoubleCount; i++)
3167     cpool->Doubles[i] = readDouble(f);
3168 
3169   cpool->StringCount = readEncUInt30(f);
3170   if (cpool->StringCount > INT_MAX / sizeof(struct ABC_STRING_INFO))
3171     SWF_error("value is too big");
3172   s = cpool->StringCount * sizeof(struct ABC_STRING_INFO);
3173   cpool->Strings = malloc(s);
3174   for(i = 1; i < cpool->StringCount; i++)
3175     parseABC_STRING_INFO(cpool->Strings + i, f);
3176 
3177   cpool->NamespaceCount = readEncUInt30(f);
3178   if (cpool->NamespaceCount > INT_MAX / sizeof(struct ABC_NS_INFO))
3179     SWF_error("value is too big");
3180   s = cpool->NamespaceCount * sizeof(struct ABC_NS_INFO);
3181   cpool->Namespaces = malloc(s);
3182   for(i = 1; i < cpool->NamespaceCount; i++)
3183     parseABC_NS_INFO(cpool->Namespaces + i, f);
3184 
3185   cpool->NamespaceSetCount = readEncUInt30(f);
3186   if (cpool->NamespaceSetCount > INT_MAX / sizeof(struct ABC_NS_SET_INFO))
3187     SWF_error("value is too big");
3188   s = cpool->NamespaceSetCount * sizeof(struct ABC_NS_SET_INFO);
3189   cpool->NsSets = malloc(s);
3190   for(i = 1; i < cpool->NamespaceSetCount; i++)
3191     parseABC_NS_SET_INFO(cpool->NsSets + i, f);
3192 
3193   cpool->MultinameCount = readEncUInt30(f);
3194   if (cpool->MultinameCount > INT_MAX / sizeof(struct ABC_MULTINAME_INFO))
3195     SWF_error("value is too big");
3196   s = cpool->MultinameCount * sizeof(struct ABC_MULTINAME_INFO);
3197   cpool->Multinames = malloc(s);
3198   for(i = 1; i < cpool->MultinameCount; i++)
3199     parseABC_MULTINAME_INFO(cpool->Multinames + i, f);
3200 }
3201 
parseABC_OPTION_INFO(struct ABC_OPTION_INFO * oinfo,FILE * f)3202 void parseABC_OPTION_INFO(struct ABC_OPTION_INFO *oinfo, FILE *f)
3203 {
3204   int i;
3205   oinfo->OptionCount = readEncUInt30(f);
3206   if (oinfo->OptionCount > INT_MAX / sizeof(struct ABC_OPTION_INFO))
3207     SWF_error("%s: line %d: OptionCount is too big", __FUNCTION__, __LINE__);
3208   oinfo->Option = malloc(sizeof(struct ABC_OPTION_INFO) * oinfo->OptionCount);
3209   for(i = 0; i < oinfo->OptionCount; i++)
3210   {
3211     oinfo->Option[i].Val = readEncUInt30(f);
3212     oinfo->Option[i].Kind = readUInt8(f);
3213   }
3214 }
3215 
parseABC_PARAM_INFO(struct ABC_PARAM_INFO * pinfo,U30 count,FILE * f)3216 void parseABC_PARAM_INFO(struct ABC_PARAM_INFO *pinfo, U30 count, FILE *f)
3217 {
3218   int i;
3219   pinfo->ParamNames = malloc(count * sizeof(U30));
3220   for(i = 0; i < count; i++)
3221     pinfo->ParamNames[i] = readEncUInt30(f);
3222 }
3223 
parseABC_METHOD_INFO(struct ABC_METHOD_INFO * method,FILE * f)3224 void parseABC_METHOD_INFO(struct ABC_METHOD_INFO *method, FILE *f)
3225 {
3226   int i;
3227 
3228   method->ParamCount = readEncUInt30(f);
3229   method->ReturnType = readEncUInt30(f);
3230   if (method->ParamCount > INT_MAX / sizeof(U30))
3231     SWF_error("parseABC_METHOD_INFO: ParamCount is too big");
3232   method->ParamType = malloc(sizeof(U30) * method->ParamCount);
3233   for(i = 0; i < method->ParamCount; i++)
3234     method->ParamType[i] = readEncUInt30(f);
3235   method->Name = readEncUInt30(f);
3236   method->Flags = readUInt8(f);
3237   if(method->Flags & ABC_METHOD_HAS_OPTIONAL)
3238     parseABC_OPTION_INFO(&method->Options, f);
3239   if(method->Flags & ABC_METHOD_HAS_PARAM_NAMES)
3240     parseABC_PARAM_INFO(&method->ParamNames, method->ParamCount, f);
3241 }
3242 
parseABC_METADATA_INFO(struct ABC_METADATA_INFO * meta,FILE * f)3243 void parseABC_METADATA_INFO(struct ABC_METADATA_INFO *meta, FILE *f)
3244 {
3245   int i;
3246 
3247   meta->Name = readEncUInt30(f);
3248   meta->ItemCount = readEncUInt30(f);
3249   if (meta->ItemCount > INT_MAX / sizeof(struct ABC_ITEM_INFO))
3250     SWF_error("parseABC_METADATA_INFO: ItemCount is too big");
3251   meta->Items = malloc(sizeof(struct ABC_ITEM_INFO) * meta->ItemCount);
3252   for(i = 0; i < meta->ItemCount; i++)
3253   {
3254     meta->Items[i].Key = readEncUInt30(f);
3255     meta->Items[i].Value = readEncUInt30(f);
3256   }
3257 }
3258 
parseABC_TRAIT_SLOT(struct ABC_TRAIT_SLOT * slot,FILE * f)3259 void parseABC_TRAIT_SLOT(struct ABC_TRAIT_SLOT *slot, FILE *f)
3260 {
3261   slot->SlotId = readEncUInt30(f);
3262   slot->TypeName = readEncUInt30(f);
3263   slot->VIndex = readEncUInt30(f);
3264   if(slot->VIndex)
3265     slot->VKind = readUInt8(f);
3266 }
3267 
parseABC_TRAIT_CLASS(struct ABC_TRAIT_CLASS * class,FILE * f)3268 void parseABC_TRAIT_CLASS(struct ABC_TRAIT_CLASS *class, FILE *f)
3269 {
3270   class->SlotId = readEncUInt30(f);
3271   class->ClassIndex = readEncUInt30(f);
3272 }
3273 
parseABC_TRAIT_FUNCTION(struct ABC_TRAIT_FUNCTION * func,FILE * f)3274 void parseABC_TRAIT_FUNCTION(struct ABC_TRAIT_FUNCTION *func, FILE *f)
3275 {
3276   func->SlotId = readEncUInt30(f);
3277   func->Function = readEncUInt30(f);
3278 }
3279 
parseABC_TRAIT_METHOD(struct ABC_TRAIT_METHOD * m,FILE * f)3280 void parseABC_TRAIT_METHOD(struct ABC_TRAIT_METHOD *m, FILE *f)
3281 {
3282   m->DispId = readEncUInt30(f);
3283   m->Method = readEncUInt30(f);
3284 }
3285 
parseABC_TRAITS_INFO(struct ABC_TRAITS_INFO * trait,FILE * f)3286 void parseABC_TRAITS_INFO(struct ABC_TRAITS_INFO *trait, FILE *f)
3287 {
3288   int i;
3289 
3290   trait->Name = readEncUInt30(f);
3291   trait->Kind = readUInt8(f);
3292   trait->Attr = (trait->Kind & 0xf0) >> 4;
3293   switch(trait->Kind & 0x0f) // lower 4-bits for type
3294   {
3295     case ABC_CONST_TRAIT_SLOT:
3296     case ABC_CONST_TRAIT_CONST:
3297       parseABC_TRAIT_SLOT(&trait->Data.Slot, f);
3298       break;
3299     case ABC_CONST_TRAIT_CLASS:
3300       parseABC_TRAIT_CLASS(&trait->Data.Class, f);
3301       break;
3302     case ABC_CONST_TRAIT_FUNCTION:
3303       parseABC_TRAIT_FUNCTION(&trait->Data.Function, f);
3304       break;
3305     case ABC_CONST_TRAIT_METHOD:
3306     case ABC_CONST_TRAIT_GETTER:
3307     case ABC_CONST_TRAIT_SETTER:
3308       parseABC_TRAIT_METHOD(&trait->Data.Method, f);
3309       break;
3310     default:
3311       SWF_error("Unknow trait %x\n", trait->Kind);
3312   }
3313 
3314   if(trait->Attr & ABC_TRAIT_ATTR_METADATA)
3315   {
3316     trait->MetadataCount = readEncUInt30(f);
3317     if (trait->MetadataCount > INT_MAX / sizeof(U30)) {
3318       SWF_error("parseABC_TRAITS_INFO: MetadataCount is too big");
3319       return;
3320     }
3321     trait->Metadata = malloc(trait->MetadataCount * sizeof(U30));
3322     for(i = 0; i < trait->MetadataCount; i++)
3323       trait->Metadata[i] = readEncUInt30(f);
3324   }
3325 }
3326 
parseABC_CLASS_INFO(struct ABC_CLASS_INFO * cinfo,FILE * f)3327 void parseABC_CLASS_INFO(struct ABC_CLASS_INFO *cinfo, FILE *f)
3328 {
3329   int i;
3330 
3331   cinfo->CInit = readEncUInt30(f);
3332   cinfo->TraitCount = readEncUInt30(f);
3333   if (cinfo->TraitCount > INT_MAX / sizeof(struct ABC_TRAITS_INFO))
3334     SWF_error("%s: value is too big, ", __FUNCTION__);
3335   cinfo->Traits = malloc(sizeof(struct ABC_TRAITS_INFO) * cinfo->TraitCount);
3336   for(i = 0; i < cinfo->TraitCount; i++)
3337     parseABC_TRAITS_INFO(cinfo->Traits + i, f);
3338 }
3339 
parseABC_SCRIPT_INFO(struct ABC_SCRIPT_INFO * sinfo,FILE * f)3340 void parseABC_SCRIPT_INFO(struct ABC_SCRIPT_INFO *sinfo, FILE *f)
3341 {
3342   int i;
3343 
3344   sinfo->Init = readEncUInt30(f);
3345   sinfo->TraitCount = readEncUInt30(f);
3346   if (sinfo->TraitCount > INT_MAX / sizeof(struct ABC_TRAITS_INFO))
3347     SWF_error("%s: value is too big, ", __FUNCTION__);
3348   sinfo->Traits = malloc(sizeof(struct ABC_TRAITS_INFO) * sinfo->TraitCount);
3349   for(i = 0; i < sinfo->TraitCount; i++)
3350     parseABC_TRAITS_INFO(sinfo->Traits + i, f);
3351 }
3352 
3353 
parseABC_INSTANCE_INFO(struct ABC_INSTANCE_INFO * inst,FILE * f)3354 void parseABC_INSTANCE_INFO(struct ABC_INSTANCE_INFO *inst, FILE *f)
3355 {
3356   int i;
3357 
3358   inst->Name = readEncUInt30(f);
3359   inst->SuperName = readEncUInt30(f);
3360   inst->Flags = readUInt8(f);
3361 
3362   if(inst->Flags & ABC_CLASS_PROTECTED_NS)
3363     inst->ProtectedNs = readEncUInt30(f);
3364 
3365   inst->InterfaceCount = readEncUInt30(f);
3366   if (inst->InterfaceCount > INT_MAX / sizeof(U30))
3367     SWF_error("%s: value is too big, ", __FUNCTION__);
3368   inst->Interfaces = malloc(inst->InterfaceCount * sizeof(U30));
3369   for(i = 0; i < inst->InterfaceCount; i++)
3370     inst->Interfaces[i] = readEncUInt30(f);
3371 
3372   inst->IInit = readEncUInt30(f);
3373 
3374   inst->TraitCount = readEncUInt30(f);
3375   if (inst->TraitCount > INT_MAX / sizeof(struct ABC_TRAITS_INFO))
3376     SWF_error("%s: value is too big, ", __FUNCTION__);
3377   inst->Traits = malloc(inst->TraitCount * sizeof(struct ABC_TRAITS_INFO));
3378   for(i = 0; i < inst->TraitCount; i++)
3379     parseABC_TRAITS_INFO(inst->Traits + i, f);
3380 }
3381 
parseABC_EXCEPTION_INFO(struct ABC_EXCEPTION_INFO * ex,FILE * f)3382 void parseABC_EXCEPTION_INFO(struct ABC_EXCEPTION_INFO *ex, FILE *f)
3383 {
3384   ex->From = readEncUInt30(f);
3385   ex->To = readEncUInt30(f);
3386   ex->Target = readEncUInt30(f);
3387   ex->ExcType = readEncUInt30(f);
3388   ex->VarName = readEncUInt30(f);
3389 }
3390 
parseABC_METHOD_BODY_INFO(struct ABC_METHOD_BODY_INFO * minfo,FILE * f)3391 void parseABC_METHOD_BODY_INFO(struct ABC_METHOD_BODY_INFO *minfo, FILE *f)
3392 {
3393   int i;
3394 
3395   minfo->Method = readEncUInt30(f);
3396   minfo->MaxStack = readEncUInt30(f);
3397   minfo->LocalCount = readEncUInt30(f);
3398   minfo->InitScopeDepth = readEncUInt30(f);
3399   minfo->MaxScopeDepth = readEncUInt30(f);
3400   minfo->CodeLength = readEncUInt30(f);
3401   minfo->Code = (UI8 *)readBytes(f, minfo->CodeLength);
3402 
3403   minfo->ExceptionCount = readEncUInt30(f);
3404   if (minfo->ExceptionCount > INT_MAX / sizeof(struct ABC_EXCEPTION_INFO))
3405     SWF_error("%s: value is too big, ", __FUNCTION__);
3406   minfo->Exceptions = malloc(minfo->ExceptionCount * sizeof(struct ABC_EXCEPTION_INFO));
3407   for(i = 0; i < minfo->ExceptionCount; i++)
3408     parseABC_EXCEPTION_INFO(minfo->Exceptions + i, f);
3409 
3410   minfo->TraitCount = readEncUInt30(f);
3411   if (minfo->TraitCount > INT_MAX / sizeof(struct ABC_TRAITS_INFO))
3412     SWF_error("%s: value is too big, ", __FUNCTION__);
3413   minfo->Traits = malloc(sizeof(struct ABC_TRAITS_INFO) * minfo->TraitCount);
3414   for(i = 0; i < minfo->TraitCount; i++)
3415     parseABC_TRAITS_INFO(minfo->Traits + i, f);
3416 }
3417 
parseABC_FILE(struct ABC_FILE * abcFile,FILE * f)3418 void parseABC_FILE(struct ABC_FILE *abcFile, FILE *f)
3419 {
3420   int i;
3421   size_t size;
3422 
3423   abcFile->Minor = readUInt16(f);
3424   abcFile->Major = readUInt16(f);
3425 
3426   parseABC_CONSTANT_POOL(&abcFile->ConstantPool, f);
3427 
3428   abcFile->MethodCount = readEncUInt30(f);
3429   if (abcFile->MethodCount > INT_MAX / sizeof(struct ABC_METHOD_INFO))
3430     SWF_error("%s: value is too big, ", __FUNCTION__);
3431   size = abcFile->MethodCount * sizeof(struct ABC_METHOD_INFO);
3432   abcFile->Methods = malloc(size);
3433   for(i = 0; i < abcFile->MethodCount; i++)
3434     parseABC_METHOD_INFO(abcFile->Methods + i, f);
3435 
3436   abcFile->MetadataCount = readEncUInt30(f);
3437   if (abcFile->MetadataCount > INT_MAX / sizeof(struct ABC_METADATA_INFO))
3438     SWF_error("%s: value is too big, ", __FUNCTION__);
3439   size = abcFile->MetadataCount * sizeof(struct ABC_METADATA_INFO);
3440   abcFile->Metadata = malloc(size);
3441   for(i = 0; i < abcFile->MetadataCount; i++)
3442     parseABC_METADATA_INFO(abcFile->Metadata + i, f);
3443 
3444   abcFile->ClassCount = readEncUInt30(f);
3445   if (abcFile->ClassCount > INT_MAX / sizeof(struct ABC_INSTANCE_INFO))
3446     SWF_error("%s: value is too big, ", __FUNCTION__);
3447   size = abcFile->ClassCount * sizeof(struct ABC_INSTANCE_INFO);
3448   abcFile->Instances = malloc(size);
3449   if (abcFile->ClassCount > INT_MAX / sizeof(struct ABC_CLASS_INFO))
3450     SWF_error("%s: value is too big, ", __FUNCTION__);
3451   size = abcFile->ClassCount * sizeof(struct ABC_CLASS_INFO);
3452   abcFile->Classes = malloc(size);
3453   for(i = 0; i < abcFile->ClassCount; i++)
3454     parseABC_INSTANCE_INFO(abcFile->Instances + i, f);
3455   for(i = 0; i < abcFile->ClassCount; i++)
3456     parseABC_CLASS_INFO(abcFile->Classes + i, f);
3457 
3458   abcFile->ScriptCount = readEncUInt30(f);
3459   if (abcFile->ScriptCount > INT_MAX / sizeof(struct ABC_SCRIPT_INFO))
3460     SWF_error("%s: value is too big, ", __FUNCTION__);
3461   size = abcFile->ScriptCount * sizeof(struct ABC_SCRIPT_INFO);
3462   abcFile->Scripts = malloc(size);
3463   for(i = 0; i < abcFile->ScriptCount; i++)
3464     parseABC_SCRIPT_INFO(abcFile->Scripts + i, f);
3465 
3466   abcFile->MethodBodyCount = readEncUInt30(f);
3467   if (abcFile->MethodBodyCount > INT_MAX / sizeof(struct ABC_METHOD_BODY_INFO))
3468     SWF_error("%s: value is too big, ", __FUNCTION__);
3469   size = abcFile->MethodBodyCount * sizeof(struct ABC_METHOD_BODY_INFO);
3470   abcFile->MethodBodies = malloc(size);
3471   for(i = 0; i < abcFile->MethodBodyCount; i++)
3472     parseABC_METHOD_BODY_INFO(abcFile->MethodBodies + i, f);
3473 }
3474 
3475 SWF_Parserstruct *
parseSWF_DOABC(FILE * f,int length)3476 parseSWF_DOABC (FILE *f, int length)
3477 {
3478   PAR_BEGIN(SWF_DOABC);
3479   parserrec->Flags = readUInt32(f);
3480   parserrec->Name = readString(f);
3481   parseABC_FILE(&parserrec->AbcFile, f);
3482   PAR_END;
3483 }
3484 
3485 SWF_Parserstruct *
parseSWF_SYMBOLCLASS(FILE * f,int length)3486 parseSWF_SYMBOLCLASS (FILE *f, int length)
3487 {
3488   int i, count;
3489   PAR_BEGIN(SWF_SYMBOLCLASS);
3490   count = readUInt16(f);
3491   parserrec->SymbolCount = count;
3492   if (parserrec->SymbolCount > INT_MAX / sizeof(struct SWF_SYMBOLCLASS))
3493     SWF_error("%s: value is too big, ", __FUNCTION__);
3494   parserrec->SymbolList = malloc(parserrec->SymbolCount * sizeof(struct SWF_SYMBOLCLASS));
3495   for(i = 0; i < count; i++)
3496   {
3497      parserrec->SymbolList[i].SymbolId = readUInt16(f);
3498      parserrec->SymbolList[i].SymbolName = readString(f);
3499   }
3500   PAR_END;
3501 }
3502 
3503 SWF_Parserstruct *
parseSWF_DEFINEBINARYDATA(FILE * f,int length)3504 parseSWF_DEFINEBINARYDATA(FILE *f, int length)
3505 {
3506   PAR_BEGIN(SWF_DEFINEBINARYDATA);
3507   parserrec->Reserved = readUInt32(f);
3508   parserrec->Data = (UI8 *)readBytes(f, length - 4);
3509   parserrec->DataLength = length - 4;
3510   PAR_END;
3511 }
3512 
3513 SWF_Parserstruct *
parseSWF_DEFINESCENEANDFRAMEDATA(FILE * f,int length)3514 parseSWF_DEFINESCENEANDFRAMEDATA(FILE *f, int length)
3515 {
3516   int i;
3517   PAR_BEGIN(SWF_DEFINESCENEANDFRAMEDATA);
3518   parserrec->SceneCount = readEncUInt32(f);
3519   if (parserrec->SceneCount > INT_MAX / sizeof(struct SCENE_DATA))
3520     SWF_error("%s: value is too big, ", __FUNCTION__);
3521   parserrec->Scenes = malloc(sizeof(struct SCENE_DATA) * parserrec->SceneCount);
3522   for(i = 0; i < parserrec->SceneCount; i++)
3523   {
3524     parserrec->Scenes[i].Offset = readEncUInt32(f);
3525     parserrec->Scenes[i].Name = readString(f);
3526   }
3527   parserrec->FrameLabelCount = readEncUInt32(f);
3528   if (parserrec->FrameLabelCount > INT_MAX / sizeof(struct FRAME_DATA))
3529     SWF_error("%s: value is too big, ", __FUNCTION__);
3530   parserrec->Frames = malloc(sizeof(struct FRAME_DATA) * parserrec->FrameLabelCount);
3531   for(i = 0; i < parserrec->FrameLabelCount; i++)
3532   {
3533     parserrec->Frames[i].FrameNum = readEncUInt32(f);
3534     parserrec->Frames[i].FrameLabel = readString(f);
3535   }
3536   PAR_END;
3537 }
3538 
3539 SWF_Parserstruct *
parseSWF_DEBUGID(FILE * f,int length)3540 parseSWF_DEBUGID(FILE *f, int length)
3541 {
3542   PAR_BEGIN(SWF_DEBUGID);
3543   parserrec->UUID = (UI8 *)readBytes(f, length);
3544   PAR_END;
3545 }
3546 
3547 SWF_Parserstruct *
parseSWF_UNKNOWNBLOCK(FILE * f,int length)3548 parseSWF_UNKNOWNBLOCK(FILE *f, int length)
3549 {
3550   PAR_BEGIN(SWF_UNKNOWNBLOCK);
3551   parserrec->Data = (UI8 *)readBytes(f, length);
3552   PAR_END;
3553 }
3554 
3555