1 /****************************************************************************
2  *
3  *  Copyright (C) 2011      Sandro Santilli <strk@keybit.net>
4  *  Copyright (C) 2005-2006 Stuart R. Anderson <anderson@netsweng.com>
5  *  Copyright (C) 2001      Raffaele Sena
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  ****************************************************************************/
22 
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <assert.h>
27 
28 #include "parser.h"
29 
30 int fileOffset = 0;
31 
32 int buffer;
33 int bufbits = 0; /* # of bits in buffer */
34 
byteAlign()35 void byteAlign()
36 {
37   if(bufbits > 0)
38   {
39     bufbits = 0;
40     buffer = 0;
41   }
42 }
43 
readBits(FILE * f,int number)44 int readBits(FILE *f, int number)
45 {
46   int ret = buffer;
47   int tmp_char;
48 
49   if(number == bufbits)
50   {
51     bufbits = 0;
52     buffer = 0;
53     return ret;
54   }
55 
56   if(number > bufbits)
57   {
58     number -= bufbits;
59 
60     while(number>8)
61     {
62       tmp_char = fgetc(f);
63       if (tmp_char == EOF)
64       {
65         // exit here instead of crashing elswhere
66         fprintf(stderr, "truncated file\n");
67         exit(-1);
68       }
69 
70       ret <<= 8;
71       ret += tmp_char;
72       ++fileOffset;
73       number -= 8;
74     }
75 
76     ++fileOffset;
77     tmp_char = fgetc(f);
78     if (tmp_char == EOF)
79     {
80       // exit here instead of crashing elswhere
81       fprintf(stderr, "truncated file\n");
82       exit(-1);
83     }
84 
85     buffer = tmp_char;
86 
87     if(number>0)
88     {
89       ret <<= number;
90       bufbits = 8-number;
91       ret += buffer >> (8-number);
92       buffer &= (1<<bufbits)-1;
93     }
94 
95     return ret;
96   }
97 
98   ret = buffer >> (bufbits-number);
99   bufbits -= number;
100   buffer &= (1<<bufbits)-1;
101 
102   return ret;
103 }
104 
readSBits(FILE * f,int number)105 int readSBits(FILE *f, int number)
106 {
107   int num = readBits(f, number);
108 
109   if(num & (1<<(number-1)))
110     return num - (1<<number);
111   else
112     return num;
113 }
114 
readRect(FILE * f,struct Rect * s)115 void readRect(FILE *f, struct Rect *s)
116 {
117   int nBits;
118   byteAlign();
119 
120   nBits = readBits(f, 5);
121   s->xMin = readSBits(f, nBits);
122   s->xMax = readSBits(f, nBits);
123   s->yMin = readSBits(f, nBits);
124   s->yMax = readSBits(f, nBits);
125 }
126 
readUInt8(FILE * f)127 int readUInt8(FILE *f)
128 {
129   int tmp_char = fgetc(f);
130   // the rest of the code does not handle errors and use EOF as a valid unsigned char value
131   if (tmp_char == EOF)
132   {
133     // exit here instead of crashing elswhere
134     fprintf(stderr, "truncated file\n");
135     exit(-1);
136   }
137 
138   bufbits = 0;
139   ++fileOffset;
140   return tmp_char;
141 }
142 
readSInt8(FILE * f)143 int readSInt8(FILE *f)
144 {
145   return (signed char)readUInt8(f);
146 }
147 
readSInt16(FILE * f)148 int readSInt16(FILE *f)
149 {
150   return readUInt8(f) + readSInt8(f)*256;
151 }
152 
readUInt16(FILE * f)153 int readUInt16(FILE *f)
154 {
155   return readUInt8(f) + (readUInt8(f)<<8);
156 }
157 
readSInt32(FILE * f)158 long readSInt32(FILE *f)
159 {
160   return (long)readUInt8(f) + (readUInt8(f)<<8) + (readUInt8(f)<<16) + (readUInt8(f)<<24);
161 }
162 
readUInt32(FILE * f)163 unsigned long readUInt32(FILE *f)
164 {
165   return (unsigned long)(readUInt8(f) + (readUInt8(f)<<8) + (readUInt8(f)<<16) + (readUInt8(f)<<24));
166 }
167 
readDouble(FILE * f)168 double readDouble(FILE *f)
169 {
170   union {
171     char c[8];
172     double d;
173   } data;
174 
175 #ifdef SWF_LITTLE_ENDIAN
176   data.c[4] = readUInt8(f);
177   data.c[5] = readUInt8(f);
178   data.c[6] = readUInt8(f);
179   data.c[7] = readUInt8(f);
180   data.c[0] = readUInt8(f);
181   data.c[1] = readUInt8(f);
182   data.c[2] = readUInt8(f);
183   data.c[3] = readUInt8(f);
184 #else
185   data.c[3] = readUInt8(f);
186   data.c[2] = readUInt8(f);
187   data.c[1] = readUInt8(f);
188   data.c[0] = readUInt8(f);
189   data.c[7] = readUInt8(f);
190   data.c[6] = readUInt8(f);
191   data.c[5] = readUInt8(f);
192   data.c[4] = readUInt8(f);
193 #endif
194 
195 
196   return data.d;
197 }
198 
readFloat(FILE * f)199 float readFloat(FILE *f)
200 {
201   union {
202     char c[4];
203     float f;
204   } data;
205 
206 #ifdef SWF_LITTLE_ENDIAN
207   data.c[0] = readUInt8(f);
208   data.c[1] = readUInt8(f);
209   data.c[2] = readUInt8(f);
210   data.c[3] = readUInt8(f);
211 #else
212   data.c[3] = readUInt8(f);
213   data.c[2] = readUInt8(f);
214   data.c[1] = readUInt8(f);
215   data.c[0] = readUInt8(f);
216 #endif
217 
218   return data.f;
219 }
220 
221 
readBytes(FILE * f,int size)222 char *readBytes(FILE *f,int size)
223 {
224   int i;
225   char *buf;
226 
227   buf = (char *)malloc(sizeof(char)*size);
228 
229   for(i=0;i<size;i++)
230   {
231     buf[i]=(char)readUInt8(f);
232   }
233 
234   return buf;
235 }
236 
readString(FILE * f)237 char *readString(FILE *f)
238 {
239   int len = 0, buflen = 256;
240   char c, *buf, *p;
241 
242   buf = (char *)malloc(sizeof(char)*256);
243   p = buf;
244 
245   while((c=(char)readUInt8(f)) != '\0')
246   {
247     if(len >= buflen-2)
248     {
249       buf = (char *)realloc(buf, sizeof(char)*(buflen+256));
250       buflen += 256;
251       p = buf+len;
252     }
253 
254     switch(c)
255     {
256       case '\n':
257 	*(p++) = '\\';	*(p++) = 'n';	++len;	break;
258       case '\t':
259 	*(p++) = '\\';	*(p++) = 't';	++len;	break;
260       case '\r':
261 	*(p++) = '\\';	*(p++) = 'r';	++len;	break;
262       default:
263 	*(p++) = c;
264     }
265 
266     ++len;
267   }
268 
269   *p = 0;
270 
271   return buf;
272 }
273 
274 #define ENC_BITSPERBYTE 	7
275 #define ENC_BYTEMASK 		0x7f
276 #define ENC_U30_VERIFY		0xfc
277 #define ENC_HIGHBIT		0x80
278 
hasNextByte(unsigned int b)279 static inline int hasNextByte(unsigned int b)
280 {
281 	if(!(b & ENC_HIGHBIT))
282 		return 0;
283 	return 1;
284 }
285 
readEncSInt32(FILE * f)286 signed long readEncSInt32(FILE *f)
287 {
288 	signed long result = 0, temp;
289 	int shift = 0;
290 	do
291 	{
292 		if(shift > 4 * ENC_BITSPERBYTE)
293 			break;
294 
295 		temp = readUInt8(f);
296 		result |= (ENC_BYTEMASK & temp) << shift;
297 		shift += ENC_BITSPERBYTE;
298 	} while (hasNextByte(temp));
299 	return result;
300 }
301 
readEncUInt30(FILE * f)302 unsigned long readEncUInt30(FILE *f)
303 {
304 	unsigned long result = 0, temp;
305 	int shift = 0;
306 	do
307 	{
308 		if(shift > 4 * ENC_BITSPERBYTE)
309 			break;
310 
311 		temp = readUInt8(f);
312 		result |= (ENC_BYTEMASK & temp) << shift;
313 		shift += ENC_BITSPERBYTE;
314 	} while (hasNextByte(temp));
315 
316 	//if((temp & ENC_U30_VERIFY) && shift > 4 * ENC_BITSPERBYTE)
317 	//	printf("readEncUInt30: verification error\n");
318 
319 	return result;
320 }
321 
readEncUInt32(FILE * f)322 unsigned long readEncUInt32(FILE *f)
323 {
324 	unsigned long result = 0, temp;
325 	int shift = 0;
326 	do
327 	{
328 		if(shift > 4 * ENC_BITSPERBYTE)
329 			break;
330 
331 		temp = readUInt8(f);
332 		result |= (ENC_BYTEMASK & temp) << shift;
333 		shift += ENC_BITSPERBYTE;
334 	} while (hasNextByte(temp));
335 
336 	return result;
337 }
338 
readSizedString(FILE * f,int size)339 char *readSizedString(FILE *f,int size)
340 {
341   int len = 0, buflen = 256, i;
342   char c, *buf, *p;
343 
344   buf = (char *)malloc(sizeof(char)*buflen);
345   p = buf;
346 
347   for(i=0;i<size;i++)
348   {
349     c=(char)readUInt8(f);
350     if(len >= buflen-2)
351     {
352       buf = (char *)realloc(buf, sizeof(char)*(buflen+256));
353       buflen += 256;
354       p = buf+len;
355     }
356 
357     switch(c)
358     {
359       case '\n':
360 	*(p++) = '\\';	*(p++) = 'n';	++len;	break;
361       case '\t':
362 	*(p++) = '\\';	*(p++) = 't';	++len;	break;
363       case '\r':
364 	*(p++) = '\\';	*(p++) = 'r';	++len;	break;
365       default:
366 	*(p++) = c;
367     }
368 
369     ++len;
370   }
371 
372   *p = 0;
373 
374   return buf;
375 }
376 
_dumpBytes(FILE * f,int length,int restore)377 void _dumpBytes(FILE *f, int length, int restore)
378 {
379   int j=0, i, k, l=0, offset=0;
380   unsigned char buf[16];
381 
382   if(length<=0)
383     return;
384 
385   if(restore)
386 	  offset = ftell(f);
387 
388   putchar('\n');
389 
390   for(;; ++l)
391   {
392     printf("%03x0: ", l);
393     for(i=0; i<16; ++i)
394     {
395       if(i==8) putchar(' ');
396 
397       printf("%02x ", buf[i] = readUInt8(f));
398       ++j;
399 
400       if(j==length)
401 		break;
402     }
403 
404     if(j==length)
405     {
406       for(k=i+1; k<16; ++k)
407 	printf("   ");
408 
409       if(k==8) putchar(' ');
410 
411       ++i;
412     }
413 
414     printf("   ");
415 
416     for(k=0; k<i; ++k)
417     {
418       if(k==8) putchar(' ');
419 
420       if((buf[k] > 31) && (buf[k] < 128))
421 	putchar(buf[k]);
422       else
423 	putchar('.');
424     }
425 
426     putchar('\n');
427 
428     if(j==length)
429       break;
430   }
431   putchar('\n');
432   putchar('\n');
433 
434   if(restore) {
435 	fseek(f,offset, SEEK_SET);
436   	fileOffset = offset;
437   }
438 }
439 
dumpBytes(FILE * f,int length)440 void dumpBytes(FILE *f, int length)
441 {
442 	_dumpBytes(f, length, 0 );
443 }
444 
peekBytes(FILE * f,int length)445 void peekBytes(FILE *f, int length)
446 {
447 	_dumpBytes(f, length, 1 );
448 }
449 
dumpBuffer(unsigned char * buf,int length)450 void dumpBuffer(unsigned char *buf, int length)
451 {
452   int j=0, i, k, l=0;
453 
454   if(length<=0)
455     return;
456 
457   putchar('\n');
458 
459   for(;; ++l)
460   {
461     printf("%03x0: ", l);
462 
463     for(i=0; i<16; ++i)
464     {
465       if(i==8) putchar(' ');
466 
467       printf("%02x ", buf[16*l+i]);
468       ++j;
469 
470       if(j==length)
471 		break;
472     }
473 
474     if(j==length)
475     {
476       for(k=i+1; k<16; ++k)
477 	printf("   ");
478 
479       if(k==8) putchar(' ');
480 
481       ++i;
482     }
483 
484     printf("   ");
485 
486     for(k=0; k<i; ++k)
487     {
488       if(k==8) putchar(' ');
489 
490       if((buf[16*l+k] > 31) && (buf[16*l+k] < 128))
491 	putchar(buf[16*l+k]);
492       else
493 	putchar('.');
494     }
495 
496     putchar('\n');
497 
498     if(j==length)
499       break;
500   }
501 
502   putchar('\n');
503   putchar('\n');
504 }
505 
silentSkipBytes(FILE * f,int length)506 void silentSkipBytes(FILE *f, int length)
507 {
508   for(; length>0; --length)
509     readUInt8(f);
510 }
511 
512 
513