1 /* OpenCP Module Player
2  * copyright (c) 2020 Stian Skjelstad <stian.skjelstad@gmail.com>
3  *
4  * Utility: Dumping the ID3 tags from MP3 files
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 
21 
22 #define _GNU_SOURCE
23 #include <fcntl.h>
24 #include <inttypes.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <zlib.h>
33 
34 /**** Most common file-layuts:
35  *
36  * [----------MPEG DATA-------------][ID3v1.0]          # 128 bytes at the end
37  *
38  * [----------MPEG DATA-------------][ID3v1.1]          # 128 bytes at the end
39  *
40  *
41  * [ID3v2.2][----------MPEG DATA-------------]          # ID3V2.2 at the start
42  * [ID3v2.3][----------MPEG DATA-------------]          # ID3V2.3 at the start
43  * [ID3v2.4][----------MPEG DATA-------------]          # ID3V2.4 at the start
44  *
45  * [ID3v2.2][------MPEG DATA--------][ID3v1.0]          # ID3V1.x tag at the end of legacy software, ID3v2.x at the start
46  *
47  * [----------MPEG DATA----------][ID3v2.4][F]          # ID3V2.4 with footer at the end
48  *
49  * [MPEG DATA][ID3v2.x][MPEG DATA][ID3v2.x]..           # Streaming service, music changes while playing
50  *
51  *
52  * This never got popular:
53  *
54  * [------MPEG DATA--------][ID3v1.2][ID3v1.1]          # 256 bytes at the end - The two tags combined gives longer strings
55  *
56  *
57  * "Broken" software generates these:
58  *
59  *[ID3v2.2][ID3v2.3][-------MPEG DATA--------]          # not common, but perfectly OK. Tag with unknown versions should be ignored, so old software reads v2.2, new read v2.3 and replaces the information
60  */
61 
62 static int indent = 0;
63 static int _newline = 1;
print(const char * format,...)64 static void print(const char *format, ...)
65 {
66 	va_list ap;
67 
68 	if (_newline)
69 	{
70 		int i;
71 		_newline = 0;
72 		for (i=0; i < indent; i++)
73 		{
74 			fputc(' ', stdout);
75 		}
76 	}
77 
78 	va_start(ap, format);
79 	vprintf(format, ap);
80 	va_end(ap);
81 }
82 enum stack_message_type
83 {
84 	STACK_INFO = 0,
85 	STACK_WARNING = 1,
86 	STACK_ERROR = 2
87 };
88 static int stacked_count;
89 static char *stacked_messages[1024];
90 static int stacked_indent[1024];
91 static enum stack_message_type stacked_smt[1024];
stack_message(enum stack_message_type smt,int extraindent,const char * format,...)92 static void stack_message(enum stack_message_type smt, int extraindent, const char *format, ...)
93 {
94 	va_list ap;
95 
96 	char *buffer;
97 	buffer = malloc(1024);
98 	va_start(ap, format);
99 	vsnprintf(buffer, 1024, format, ap);
100 	va_end(ap);
101 	stacked_indent[stacked_count] = extraindent + indent;
102 	stacked_messages[stacked_count] = buffer;
103 	stacked_smt[stacked_count++] = smt;
104 }
flush()105 static void flush()
106 {
107 	int i;
108 	int oldindent = indent;
109 	if (!_newline)
110 	{
111 		fputc('\n', stdout);
112 		_newline=1;
113 	}
114 	for (i=0; i < stacked_count; i++)
115 	{
116 		indent = stacked_indent[i];
117 		switch (stacked_smt[i])
118 		{
119 			case STACK_WARNING: print ("*-* WARNING: "); break;
120 			case STACK_ERROR: print ("*-* ERROR: "); break;
121 			case STACK_INFO: print ("*-* INFO: "); break;
122 		}
123 		print(stacked_messages[i]);
124 		free(stacked_messages[i]);
125 		switch (stacked_smt[i])
126 		{
127 			case STACK_WARNING:
128 			case STACK_ERROR:
129 			case STACK_INFO: print (" *-*"); break;
130 		}
131 		fputc('\n', stdout);
132 		_newline=1;
133 	}
134 	indent = oldindent;
135 	stacked_count = 0;
136 }
newline()137 static void newline()
138 {
139 	if (stacked_count)
140 	{
141 		flush();
142 	} else {
143 		fputc('\n', stdout);
144 		_newline=1;
145 	}
146 }
unsync(uint8_t * data,uint32_t * len)147 static void unsync(uint8_t *data, uint32_t *len)
148 {
149 	uint32_t i;
150 	/* Unescape all 0xff 0x00 combinations with 0xff */
151 	for (i = 0; (i+1) < (*len); i++)
152 	{
153 		if ((data[i]==0xff) && (data[i+1]==0x00))
154 		{
155 			memmove (data + i + 1, data + i + 2, (*len) - i - 1);
156 			(*len)--;
157 		}
158 	}
159 }
160 
decode_print_UTF8(uint8_t ** data,uint32_t * len,const int must_include_null_term)161 static int decode_print_UTF8(uint8_t **data, uint32_t *len, const int must_include_null_term)
162 {
163 	int ilen = 1;
164 #warning TODO, sanitize UTF-8
165 	print("\"");
166 	while (*len)
167 	{
168 		if ((*data)[0] == 0x00)
169 		{
170 			(*data)++;
171 			(*len)--;
172 			print("\"");
173 			return 0;
174 		} else if ((*data[0]) == 0x0a)
175 		{
176 			ilen += 6;
177 			print("\" NL \"");
178 		} else if ((*data)[0] == 0x0d)
179 		{
180 			ilen += 6;
181 			print("\" CR \""); /* not always present */
182 		} else {
183 			if ((*data)[0] & 0x80)
184 			{
185 				if (((*data)[0] & 0xC0) != 0x80)
186 				{
187 					ilen++;
188 				}
189 			} else {
190 				ilen++;
191 			}
192 			print("%c", (*data)[0]);
193 		}
194 		(*data)++;
195 		(*len)--;
196 	}
197 	print("\"");
198 	if (must_include_null_term)
199 	{
200 		stack_message(ilen, STACK_ERROR, "no NULL termination");
201 		return -1;
202 	}
203 	return 0;
204 }
205 
decode_print_iso8859_1(uint8_t ** data,uint32_t * len,const int must_include_null_term)206 static int decode_print_iso8859_1(uint8_t **data, uint32_t *len, const int must_include_null_term)
207 {
208 	int ilen = 1;
209 	int valid_utf8_chars = 0;
210 	int invalid_utf8_chars = 0;
211 	/* first we prescan to detect if UTF-8 has been dumped into latin1.. this happens often in ID3.
212 	 *(we only probe for (2 and 3 characters wide)
213 	 */
214 	{
215 		uint8_t *d2 = *data;
216 		uint32_t l2 = *len;
217 		while (l2)
218 		{
219 			if (!*d2)
220 			{
221 				break;
222 			}
223 			if (d2[0] & 0x80)
224 			{
225 				if ((l2 >= 2) && ((d2[0] & 0xe0) == 0xc0) && ((d2[1] & 0xc0) == 0x80))
226 				{
227 					valid_utf8_chars++;
228 					d2+=2;
229 					l2-=2;
230 				} else if ((l2 >= 3) && ((d2[0] & 0xf0) == 0xe0) && ((d2[1] & 0xc0) == 0x80) && ((d2[2] & 0xc0) == 0x80))
231 				{
232 					valid_utf8_chars++;
233 					d2+=3;
234 					l2-=3;
235 				} else {
236 					invalid_utf8_chars++;
237 					break;
238 				}
239 			} else {
240 				d2++;
241 				l2--;
242 			}
243 		}
244 	}
245 
246 	if ((!invalid_utf8_chars) && valid_utf8_chars)
247 	{
248 		print("=> UTF8_detected ");
249 		return decode_print_UTF8(data, len, must_include_null_term);
250 	}
251 	print("\"");
252 	while (*len)
253 	{
254 		if ((*data)[0] == 0x00)
255 		{
256 			(*data)++;
257 			(*len)--;
258 			print("\"");
259 			return 0;
260 		} else if ((*data)[0] == 0x0a)
261 		{
262 			ilen += 6;
263 			print("\" NL \"");
264 		} else if ((*data)[0] == 0x0d)
265 		{
266 			ilen += 6;
267 			print("\" CR \""); /* not always present */
268 		} else if (((*data)[0] <= 0x1f) || (((*data)[0] >= 0x8f) && ((*data)[0] <= 0x9f)))
269 		{
270 			stack_message(STACK_WARNING, ilen, "byte with invalid value: 0x%02"PRIx8, (*data)[0]);
271 		} else {
272 			ilen++;
273 			if ((*data)[0] < 0x80)
274 			{
275 				print("%c", (*data)[0]);
276 			} else {
277 				print("%c%c", ((*data)[0] >> 6) | 0xc0, ((*data)[0] & 0x3f) | 0x80);
278 			}
279 		}
280 		(*data)++;
281 		(*len)--;
282 	}
283 	print("\"");
284 	if (must_include_null_term)
285 	{
286 		stack_message(STACK_ERROR, ilen, "no NULL termination");
287 		return -1;
288 	}
289 	return 0;
290 }
291 
decode_print_UCS2(uint8_t ** data,uint32_t * len,const int must_include_null_term,int firststring)292 static int decode_print_UCS2(uint8_t **data, uint32_t *len, const int must_include_null_term, int firststring)
293 {
294 	int ilen = 1;
295 	static int be = 1;
296 
297 	if (*len < 2)
298 	{
299 		stack_message(STACK_WARNING, ilen, "BOM can not fit");
300 		return -1;
301 	}
302 	if (((*data)[0] == 0xfe) && ((*data)[1] == 0xff))
303 	{ // big endian
304 		be = 1;
305 		(*data)+=2;
306 		(*len)-=2;
307 	} else if (((*data)[0] == 0xff) && ((*data)[1] == 0xfe))
308 	{ // little endian
309 		be = 0;
310 		(*data)+=2;
311 		(*len)-=2;
312 	} else {
313 		if (firststring)
314 		{
315 			stack_message(STACK_WARNING, ilen, "Invalid BOM: 0x%02x 0x%02x", (*data)[0], (*data)[1]);
316 			return -1;
317 		}
318 	}
319 
320 	print("\"");
321 	while (*len)
322 	{
323 		uint16_t codepoint;
324 		if (*len == 1)
325 		{
326 			stack_message(STACK_WARNING, ilen, "len==1");
327 			print("\"");
328 			return -1;
329 		}
330 		if (be)
331 		{
332 			codepoint = ((*data)[0]<<8) | (*data)[1];
333 		} else {
334 			codepoint = ((*data)[1]<<8) | (*data)[0];
335 		}
336 		(*data)+=2;
337 		(*len)-=2;
338 
339 		if (codepoint == 0x0000)
340 		{
341 			(*data)+=2;
342 			(*len)-=2;
343 			print("\"");
344 			return 0;
345 		} else if (codepoint == 0x000a)
346 		{
347 			ilen += 6;
348 			print("\" NL \"");
349 		} else if (codepoint == 0x000d)
350 		{
351 			ilen += 6;
352 			print("\" CR \""); /* not always present */
353 		} else if (codepoint < 127)
354 		{
355 			ilen++;
356 			print("%c", codepoint);
357 		} else if (codepoint < 0x800)
358 		{
359 			ilen++;
360 			print("%c%c", (codepoint >> 6) | 0xc0, (codepoint & 0x3f) | 0x80);
361 		} else {
362 			ilen++;
363 			print("%c%c%c", (codepoint >> 12) | 0xe0, ((codepoint >> 6) & 0x3f) | 0x80, (codepoint & 0x3f) | 0x80);
364 		}
365 	}
366 	print("\"");
367 	if (must_include_null_term)
368 	{
369 		stack_message(STACK_ERROR, ilen, "no NULL termination");
370 		return -1;
371 	}
372 	return 0;
373 }
374 
decode_print_UTF16(uint8_t ** data,uint32_t * len,const int must_include_null_term)375 static int decode_print_UTF16(uint8_t **data, uint32_t *len, const int must_include_null_term)
376 {
377 	int ilen = 1;
378 	int be = 1;
379 
380 	print("\"");
381 	while (*len)
382 	{
383 		uint32_t codepoint;
384 		if ((*len) == 1)
385 		{
386 			if (must_include_null_term)
387 			{
388 				(*data)+=2;
389 				(*len)-=2;
390 			}
391 			stack_message(STACK_ERROR, ilen, "len==1");
392 			return -1;
393 		}
394 		if (be)
395 		{
396 			codepoint = ((*data)[0]<<8) | (*data)[1];
397 		} else {
398 			codepoint = ((*data)[1]<<8) | (*data)[0];
399 		}
400 
401 		(*data)+=2;
402 		(*len)-=2;
403 
404 		if ((codepoint >= 0xd800) && (codepoint <= 0xdbff))
405 		{
406 			uint16_t second;
407 			if ((*len) < 2)
408 			{
409 				stack_message(STACK_ERROR, ilen, "Second surrogate does not fit");
410 				print("\"");
411 				return 1;
412 			}
413 			if (be)
414 			{
415 				second = ((*data)[0]<<8) | (*data)[1];
416 			} else {
417 				second = ((*data)[1]<<8) | (*data)[0];
418 			}
419 			(*data)+=2;
420 			(*len)-=2;
421 
422 			if ((second < 0xdc00) || (second > 0xdfff))
423 			{
424 				stack_message(STACK_ERROR, ilen, "Second surrogate out og range");
425 				print("\"");
426 				return -1;
427 			}
428 
429 			codepoint = ((codepoint & 0x03ff) << 10) | (second & 0x03ff);
430 			codepoint += 0x10000;
431 
432 		} else if ((codepoint >= 0xdc00) && (codepoint <= 0xdfff))
433 		{
434 			stack_message(STACK_ERROR, ilen, "Surrogates in the wrong order");
435 			print("\"");
436 			return -1;
437 		}
438 		if (codepoint == 0xfeff)
439 		{
440 			/* NO-OP */
441 		} if (codepoint == 0xfffe)
442 		{
443 			be = !be;
444 		} else if (codepoint == 0x0000)
445 		{
446 			(*data)+=2;
447 			(*len)-=2;
448 			print("\"");
449 			return 0;
450 		} else if (codepoint == 0x000a)
451 		{
452 			ilen += 6;
453 			print("\" NL \"");
454 		} else if (codepoint == 0x000d)
455 		{
456 			ilen += 6;
457 			print("\" CR \""); /* not always present */
458 		} else if (codepoint < 127)
459 		{
460 			ilen++;
461 			print("%c", codepoint);
462 		} else if (codepoint < 0x800)
463 		{
464 			ilen++;
465 			print("%c%c", (codepoint >> 6) | 0xc0, (codepoint & 0x3f) | 0x80);
466 		} else if (codepoint < 0x10000)
467 		{
468 			ilen++;
469 			print("%c%c%c", (codepoint >> 12) | 0xe0, ((codepoint >> 6) & 0x3f) | 0x80, (codepoint & 0x3f) | 0x80);
470 		} else {
471 			ilen++;
472 			print("%c%c%c%c", (codepoint >> 18) | 0xf0, ((codepoint >> 12) & 0x3f) | 0x80, ((codepoint >> 6) & 0x3f) | 0x80, (codepoint & 0x3f) | 0x80);
473 		}
474 	}
475 	print("\"");
476 	if (must_include_null_term)
477 	{
478 		stack_message(STACK_ERROR, ilen, "no NULL termination");
479 		return -1;
480 	}
481 	return 0;
482 }
483 
decode_UFID(uint8_t * data,uint32_t len)484 static void decode_UFID(uint8_t *data, uint32_t len)
485 { /* ID3v220 used UFI only */
486 	uint8_t *nameeof = memchr (data, len, 0x00);
487 
488 	print("Unique file identifier");
489 
490 	if (!nameeof)
491 	{
492 		stack_message(STACK_WARNING, 0, "no DB");
493 	} else {
494 		print(" \"%s\"", (char *)data);
495 		len -= nameeof-data;
496 		data=nameeof;
497 
498 		len--;
499 		data++;
500 	}
501 
502 	if (len > 64)
503 	{
504 		stack_message(STACK_WARNING, 0, "More than 64 bytes in ID");
505 	}
506 
507 	print(" ID=0x");
508 	while (len)
509 	{
510 		print("%02" PRIx8, *data);
511 		data++;
512 		len--;
513 	}
514 	newline();
515 }
516 
decode_MCDI(uint8_t * data,uint32_t len)517 static void decode_MCDI(uint8_t *data, uint32_t len)
518 { /* ID3v220 used MCI only */
519 	print("Music CD identifier");
520 
521 	if (len > 804)
522 	{
523 		stack_message(STACK_WARNING, 0, "More than 804 bytes in ID");
524 	}
525 
526 	print(" - CD-TOC=0x");
527 	while (len)
528 	{
529 		print("%02" PRIx8, *data);
530 		data++;
531 		len--;
532 	}
533 	newline();
534 }
535 
decode_ETCO(uint8_t * data,uint32_t len,uint8_t version)536 static void decode_ETCO(uint8_t *data, uint32_t len, uint8_t version)
537 { /* ID3v220 used ETC only */
538 	uint8_t format;
539 
540 	print("Event timing codes");
541 
542 	if (len < 1)
543 	{
544 		stack_message(STACK_WARNING, 0, "Frame contains no format");
545 		newline();
546 		return;
547 	}
548 	format = *data;
549 	data++;
550 	len--;
551 
552 	if ((format == 0) || (format > 2))
553 	{
554 		stack_message(STACK_WARNING, 0, "Invalid format");
555 		newline();
556 		return;
557 	}
558 
559 	newline();
560 	while (len >= 5)
561 	{
562 		if (data[0] != 0xff)
563 		{
564 			uint32_t timecode;
565 			timecode = (data[1]<<24)|(data[2]<<16)|(data[3]<<8)|data[4];
566 
567 			if (timecode == 0)
568 			{
569 				print("            %s", (format==1)?"  ":"           ");
570 			} else {
571 				print("%10" PRId32 " %s ", timecode, (format==1)?"ms":"mpeg-frames");
572 			}
573 
574 			     if (data[0] == 0x00) print("padding (has no meaning)");
575 			else if (data[0] == 0x01) print("end of initial silence");
576 			else if (data[0] == 0x02) print("intro start");
577 			else if (data[0] == 0x03) print("main part start");
578 			else if (data[0] == 0x04) print("outro start");
579 			else if (data[0] == 0x05) print("outro end");
580 			else if (data[0] == 0x06) print("verse start");
581 			else if (data[0] == 0x07) print("refrain start");
582 			else if (data[0] == 0x08) print("interlude start");
583 			else if (data[0] == 0x09) print("theme start");
584 			else if (data[0] == 0x0a) print("variation start");
585 			else if (data[0] == 0x0b) print("key change");
586 			else if (data[0] == 0x0c) print("time change");
587 			else if (data[0] == 0x0d) print("momentary unwanted noise (Snap, Crackle & Pop)");
588 			else if ((data[0] == 0x0e) && (version >= 3)) print("sustained noise");     /* new in ID3v230 */
589 			else if ((data[0] == 0x0f) && (version >= 3)) print("sustained noise end"); /* new in ID3v230 */
590 			else if ((data[0] == 0x10) && (version >= 3)) print("intro end");           /* new in ID3v230 */
591 			else if ((data[0] == 0x11) && (version >= 3)) print("main part end");       /* new in ID3v230 */
592 			else if ((data[0] == 0x12) && (version >= 3)) print("verse end");           /* new in ID3v230 */
593 			else if ((data[0] == 0x13) && (version >= 3)) print("refrain end");         /* new in ID3v230 */
594 			else if ((data[0] == 0x14) && (version >= 3)) print("theme end");           /* new in ID3v230 */
595 			else if ((data[0] == 0x15) && (version >= 4)) print("profanity");           /* new in ID3v240 */
596 			else if ((data[0] == 0x16) && (version >= 4)) print("profanity end");       /* new in ID3v240 */
597 			else if (data[0] == 0xfd) print("audio end (start of silence)");
598 			else if (data[0] == 0xfe) print("audio file ends");
599 			else if ((data[0] & 0xf0) == 0xe0) print("not predefined sync: %c", "0123456789ABCDEF"[data[0]&0x0f]);
600 			else print("(%02x) - reserved for future use", data[0]);
601 
602 			newline();
603 
604 			data+=5;
605 			len-=5;
606 		} else {
607 			int i, j;
608 			uint32_t timecode;
609 
610 			for (i=0; data[i]==0xff; i++)
611 			{
612 				if (len < (i*2+4))
613 				{
614 					stack_message(STACK_ERROR, 0, "Ran out of data while reading ETCO user event");
615 					return;
616 				}
617 			}
618 
619 			timecode = (data[i*2+0]<<24)|(data[i*2+1]<<16)|(data[i*2+2]<<8)|data[i*2+3];
620 			indent += 2;
621 			for (j=0; j < i; j++)
622 			{
623 				if ((timecode == 0) || j)
624 				{
625 					print("            %s", (format==1)?"  ":"           ");
626 				} else {
627 					print("%10" PRId32 " %s ", timecode, (format==1)?"ms":"mpeg-frames");
628 				}
629 				print ("User event %d", data[i+j]);
630 				newline();
631 			}
632 			indent -= 2;
633 
634 			data += i*2+4;
635 			len -= i*2+4;
636 		}
637 	}
638 
639 	if (len)
640 	{
641 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
642 	}
643 }
644 
decode_POSS(uint8_t * data,uint32_t len)645 static void decode_POSS(uint8_t *data, uint32_t len)
646 {
647 	uint32_t timecode = 0;
648 	uint8_t format;
649 
650 	print("Position synchronisation frame");
651 
652 	if (len < 1)
653 	{
654 		stack_message(STACK_ERROR, 0, "Frame contains no format");
655 		newline();
656 		return;
657 	}
658 	format = *data;
659 	data++;
660 	len--;
661 
662 	if ((format == 0) || (format > 2))
663 	{
664 		stack_message(STACK_ERROR, 0, "Invalid format");
665 		newline();
666 		return;
667 	}
668 
669 	while (len)
670 	{
671 		timecode <<= 8;
672 		timecode |= data[0];
673 	}
674 	print(" - Position: %" PRId32 " %s", timecode, (format==1)?"ms":"mpeg-frames");
675 	newline();
676 }
677 
decode_GEOB(uint8_t * data,uint32_t len,int version)678 static void decode_GEOB(uint8_t *data, uint32_t len, int version)
679 { /* ID3v220 used GEO only */
680 	uint8_t text_encoding;
681 	int error;
682 
683 	print("General encapsulated object");
684 
685 	if (len < 1)
686 	{
687 		stack_message(STACK_ERROR, 0, "No space for text_encoding");
688 		newline();
689 		return;
690 	}
691 	text_encoding = *data;
692 	data++;
693 	len--;
694 
695 	if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
696 	{
697 		stack_message(STACK_ERROR, 0, "Text_encoding out of range");
698 		newline();
699 		return;
700 	}
701 
702 	if (!len)
703 	{
704 		stack_message(STACK_ERROR, 0, "No space for MIME-Type");
705 		newline();
706 		return;
707 	}
708 	newline();
709 	print("MIME-Type: ");
710 	error=decode_print_iso8859_1(&data, &len, 1);
711 	newline();
712 
713 	if (error)
714 	{
715 		return;
716 	}
717 
718 	if (!len)
719 	{
720 		stack_message(STACK_ERROR, 0, "No space for Filename");
721 		return;
722 	}
723 
724 	print("Filename: ");
725 	switch (text_encoding)
726 	{
727 		case 0x00:
728 			print("LATIN1 ");
729 			error = decode_print_iso8859_1(&data, &len, 1);
730 			break;
731 		case 0x01:
732 			print("UCS-2 ");
733 			error = decode_print_UCS2(&data, &len, 1, 1);
734 			break;
735 		case 0x02:
736 			print("UTF-16 ");
737 			error = decode_print_UTF16(&data, &len, 1);
738 			break;
739 		case 0x03:
740 			print("UTF-8 ");
741 			error = decode_print_UTF8(&data, &len, 1);
742 			break;
743 	}
744 	newline();
745 	if (error)
746 	{
747 		return;
748 	}
749 
750 	if (!len)
751 	{
752 		stack_message(STACK_ERROR, 0, "Ran out of data");
753 		return;
754 	}
755 
756 	print("Content description: ");
757 	switch (text_encoding)
758 	{
759 		case 0x00:
760 			print("LATIN1 ");
761 			error = decode_print_iso8859_1(&data, &len, 1);
762 			break;
763 		case 0x01:
764 			print("UCS-2 ");
765 			error = decode_print_UCS2(&data, &len, 1, 0);
766 			break;
767 		case 0x02:
768 			print("UTF-16 ");
769 			error = decode_print_UTF16(&data, &len, 1);
770 			break;
771 		case 0x03:
772 			print("UTF-8 ");
773 			error = decode_print_UTF8(&data, &len, 1);
774 			break;
775 	}
776 	newline();
777 	if (error)
778 	{
779 		return;
780 	}
781 
782 	print("Encapsulated object: 0x");
783 	while (len)
784 	{
785 		print("%02" PRIx8, *data);
786 		data++;
787 		len--;
788 	}
789 	newline();
790 }
791 
decode_EQUA(uint8_t * data,uint32_t len)792 static void decode_EQUA(uint8_t *data, uint32_t len)
793 {
794 	uint8_t bits;
795 	print("Equalisation"); newline();
796 
797 	if (len < 1)
798 	{
799 		stack_message(STACK_ERROR, 0, "No space for Adjustment bits");
800 		return;
801 	}
802 	bits = data[0];
803 	if (bits==0||bits>16)
804 	{
805 		stack_message(STACK_ERROR, 0, "Adjustment bits out of range");
806 		return;
807 	}
808 	data++;
809 	len--;
810 
811 	while (len > 3)
812 	{
813 		uint16_t frequency  = (data[0]<<8) | data[1];
814 		uint16_t adjustment = (data[2]);
815 
816 		data+=3;
817 		len-=3;
818 		if (bits>8)
819 		{
820 			if (!len)
821 			{
822 				stack_message(STACK_ERROR, 0, "Ran out of data");
823 				return;
824 			}
825 			adjustment<<=8;
826 			adjustment|=data[0];
827 			data++;
828 			len--;
829 		}
830 
831 		print("Frequency: %"PRId16" Hz, Volume adjustment: %c%"PRId16, frequency & 0x7fff, (frequency & 0x8000)?'+':'-', adjustment); newline();
832 	}
833 	if (len)
834 	{
835 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
836 	}
837 }
838 
decode_EQU2(uint8_t * data,uint32_t len)839 static void decode_EQU2(uint8_t *data, uint32_t len)
840 {
841 	int error;
842 	print("Equalisation (2)"); newline();
843 
844 	if (len < 1)
845 	{
846 		stack_message(STACK_ERROR, 0, "No space for Interpolation method");
847 		return;
848 	}
849 	switch (data[0])
850 	{
851 		case 0x00: print("Interpolation method: Band"); newline(); break;
852 		case 0x01: print("Interpolation method: Linear"); newline(); break;
853 		default: stack_message(STACK_ERROR, 0, "Unknown interpolation method"); return;
854 	}
855 	data++;
856 	len--;
857 
858 	print("Identification: ");
859 	error = decode_print_iso8859_1(&data, &len, 1);
860 	newline();
861 	if (error)
862 	{
863 		return;
864 	}
865 
866 	while (len > 4)
867 	{
868 		uint16_t frequency  = (data[0]<<8) | data[1];
869 		uint16_t adjustment = (data[2]<<8) | data[3];
870 
871 		print("Frequency: %"PRId16" Hz, Volume adjustment: %"PRId16, frequency, adjustment); newline();
872 		data+=4;
873 		len-=4;
874 	}
875 	if (len)
876 	{
877 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
878 	}
879 }
880 
decode_RBUF(uint8_t * data,uint32_t len)881 static void decode_RBUF(uint8_t *data, uint32_t len)
882 { /* ID3v220 used BUF*/
883 	uint32_t buffersize;
884 	print("Recommended buffer size"); newline();
885 
886 	if (len < 4)
887 	{
888 		stack_message(STACK_ERROR, 0, "Frame too small");
889 		return;
890 	}
891 	buffersize = (data[0]<<16) | (data[1]<<8) | data[2];
892 	data+=3;
893 	len-=3;
894 
895 	print("Buffer size: %" PRId32, buffersize); newline();
896 	if (data[0] & 0x01)
897 	{
898 		print("ID3 tag larger than Recommended buffer size can appear!"); newline();
899 	} else {
900 		print("Oversized ID3 tag shall not appear!"); newline();
901 	}
902 	data++;
903 	len--;
904 
905 	if (len < 4)
906 	{
907 		print("(Offset to next tag omitted)"); newline();
908 	} else {
909 		buffersize = (data[0] << 24) | (data[1]<<16) | (data[2]<<8) | data[3];
910 		print("Offset to next tag: %" PRId32, buffersize); newline();
911 		data+=4;
912 		len-=4;
913 	}
914 
915 	if (len)
916 	{
917 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
918 	}
919 }
920 
decode_MLLT(uint8_t * data,uint32_t len)921 static void decode_MLLT(uint8_t *data, uint32_t len)
922 { /* ID3v220 used MLL */
923 	print("MPEG location lookup table"); newline();
924 
925 	if (len < 10)
926 	{
927 		stack_message(STACK_ERROR, 0, "Frame too small");
928 		return;
929 	}
930 
931 	print("MPEG frames between reference:   %d",                 (data[0]<<8) | data[1]); newline();
932 	print("Bytes between reference:         %d", (data[2]<<24) | (data[3]<<8) | data[4]); newline();
933 	print("Milliseconds between reference:  %d", (data[5]<<24) | (data[6]<<8) | data[7]); newline();
934 	print("Bits for bytes deviation:        %d",                                data[8]); newline();
935 	print("Bits for milliseconds deviation: %d",                                data[9]); newline();
936 	data+=10;
937 	len-=10;
938 	print("DATA: 0x");
939 #warning TODO, decode this raw data...
940 	while (len)
941 	{
942 		print("%02x", *data);
943 		data++;
944 		len--;
945 	}
946 	newline();
947 }
948 
decode_SEEK(uint8_t * data,uint32_t len)949 static void decode_SEEK(uint8_t *data, uint32_t len)
950 {
951 	uint32_t min;
952 	print("Seek"); newline();
953 
954 	if (len < 4)
955 	{
956 		stack_message(STACK_ERROR, 0, "Frame too small");
957 		return;
958 	}
959 	min = (data[0]<<24)|(data[1]<<16)|(data[2]<<8)|data[3];
960 	print("Minimum offset to next tag: %" PRId32, min); newline();
961 	data+=4;
962 	len-=4;
963 
964 	if (len)
965 	{
966 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
967 	}
968 }
969 
decode_ASPI(uint8_t * data,uint32_t len)970 static void decode_ASPI(uint8_t *data, uint32_t len)
971 {
972 	uint32_t S, L;
973 	uint16_t N;
974 	uint8_t  b;
975 	print("Audio seek point index"); newline();
976 
977 	if (len < 11)
978 	{
979 		stack_message(STACK_ERROR, 0, "Frame too small");
980 		return;
981 	}
982 
983 	S = (data[0]<<24)|(data[1]<<16)|(data[2]<<8)|data[3];
984 	L = (data[4]<<24)|(data[5]<<16)|(data[6]<<8)|data[7];
985 	N =                             (data[8]<<8)|data[9];
986 	b =                                         data[10];
987 	print("Indexed data start (S):     %" PRId32, S); newline();
988 	print("Indexed data length (L):    %" PRId32, L); newline();
989 	print("Number of index points (N): %" PRId16, N); newline();
990 	print("Bits per index point (b):   %" PRId8, b); newline();
991 	data+=11;
992 	len-=11;
993 	print("DATA: 0x");
994 #warning TODO, decode this raw data...
995 	while (len)
996 	{
997 		print("%02x", *data);
998 		data++;
999 		len--;
1000 	}
1001 	newline();
1002 }
1003 
decode_SYTC(uint8_t * data,uint32_t len)1004 static void decode_SYTC(uint8_t *data, uint32_t len)
1005 { /* ID3v220 used STC */
1006 	uint8_t format;
1007 	print("Synchronised tempo codes"); newline();
1008 
1009 	if (len < 1)
1010 	{
1011 		stack_message(STACK_ERROR, 0, "Frame too small");
1012 		return;
1013 	}
1014 	format = *data;
1015 	data++;
1016 	len--;
1017 	if ((format < 1) || (format > 2))
1018 	{
1019 		stack_message(STACK_ERROR, 0, "Format out of range");
1020 		return;
1021 	}
1022 
1023 	while (len)
1024 	{
1025 		uint16_t value = *data;
1026 		uint32_t timestamp;
1027 		data++;
1028 		len--;
1029 		if (value == 255)
1030 		{
1031 			if (len < 1)
1032 			{
1033 				stack_message(STACK_ERROR, 0, "Out of data reading second byte of value");
1034 				return;
1035 			}
1036 			value += *data;
1037 			data++;
1038 			len--;
1039 		}
1040 		if (len < 4)
1041 		{
1042 			stack_message(STACK_ERROR, 0, "Out of data reading timestamp");
1043 			break;
1044 		}
1045 		timestamp = (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | data[3];
1046 		data+=4;
1047 		len-=4;
1048 		print("%" PRId32 "%s -- ", timestamp, (format==1)?"mpeg frames":"ms");
1049 		if (value == 0)
1050 		{
1051 			print("beat-free");
1052 		} else if (value == 1)
1053 		{
1054 			print("single beat");
1055 		} else {
1056 			print("%d BPM", (int)value);
1057 		}
1058 		newline();
1059 	}
1060 
1061 	if (len)
1062 	{
1063 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1064 	}
1065 }
1066 
decode_SYLT(uint8_t * data,uint32_t len,int version)1067 static void decode_SYLT(uint8_t *data, uint32_t len, int version)
1068 { /* ID3v220 used SLT */
1069 	int error;
1070 	uint8_t text_encoding, format;
1071 	int first = 1;
1072 	print("Synchronised lyrics/text");
1073 	newline();
1074 
1075 	if (len < 6)
1076 	{
1077 		stack_message(STACK_ERROR, 0, "Frame too small");
1078 		return;
1079 	}
1080 
1081 	text_encoding = data[0];
1082 	if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
1083 	{
1084 		stack_message(STACK_ERROR, 0, "Text_encoding out of range");
1085 		return;
1086 	}
1087 
1088 	if ((data[1]<0x20)||(data[1]>=0x80)||
1089 	    (data[2]<0x20)||(data[2]>=0x80)||
1090 	    (data[3]<0x20)||(data[3]>=0x80))
1091 	{
1092 		print("language is invalid 0x%02x 0x%02x 0x%02x", data[1], data[2], data[3]);
1093 	} else {
1094 		print("language: \"%c%c%c\"", data[1], data[2], data[3]);
1095 	}
1096 	newline();
1097 
1098 	format = data[4];
1099 	if ((format < 0) || (format > 2))
1100 	{
1101 		stack_message(STACK_ERROR, 0, "Time stamp format out of range");
1102 		return;
1103 	}
1104 	switch (data[5])
1105 	{
1106 		case 0x00: print("Content type: other"); newline(); break;
1107 		case 0x01: print("Content type: lyrics"); newline(); break;
1108 		case 0x02: print("Content type: text transcription"); newline(); break;
1109 		case 0x03: print("Content type: movement/part name (e.g. \"Adagio\")"); newline(); break;
1110 		case 0x04: print("Content type: events (e.g. \"Don Quijote enters the stage\")"); newline(); break;
1111 		case 0x05: print("Content type: chord (e.g. \"Bb F Fsus\")"); newline(); break;
1112 		case 0x06: print("Content type: trivia/'pop up' information"); newline(); break;
1113 		case 0x07: print("Content type: URLs to webpages"); newline(); break;
1114 		case 0x08: print("Content type: URLs to images"); newline(); break;
1115 		default: stack_message(STACK_WARNING, 0, "Content type out of range"); break;
1116 	}
1117 	data+= 6;
1118 	len-=6;
1119 
1120 	while (len)
1121 	{
1122 		uint32_t timecode;
1123 		switch (text_encoding)
1124 		{
1125 			case 0x00:
1126 				print("LATIN1 ");
1127 				error = decode_print_iso8859_1 (&data, &len, 1);
1128 				break;
1129 			case 0x01:
1130 				print("UCS2 ");
1131 				error = decode_print_UCS2 (&data, &len, 1, first);
1132 				first = 0;
1133 				break;
1134 			case 0x02:
1135 				print("UTF-16 ");
1136 				error=decode_print_UTF16 (&data, &len, 1);
1137 				break;
1138 			case 0x03:
1139 				print("UTF-8 ");
1140 				error=decode_print_UTF8 (&data, &len, 1);
1141 				break;
1142 		}
1143 		if (error)
1144 		{
1145 			newline();
1146 			return;
1147 		}
1148 		if (len < 4)
1149 		{
1150 			newline();
1151 			stack_message(STACK_ERROR, 0, "Ran out of data");
1152 			break;
1153 		}
1154 		timecode = (data[0]<<24)|(data[1]<<16)|(data[2]<<8)|data[1];
1155 		data+=4;
1156 		len-=4;
1157 		print(" %" PRId32 " %s", timecode, (format==1)?"mpeg frames":"ms"); newline();
1158 	}
1159 
1160 	if (len)
1161 	{
1162 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1163 	}
1164 }
1165 
decode_USLT(uint8_t * data,uint32_t len,int version)1166 static void decode_USLT(uint8_t *data, uint32_t len, int version)
1167 { /* ID3v220 used ULT */
1168 	int error;
1169 	uint8_t text_encoding;
1170 	print("Unsynchronised lyrics/text transcription"); newline();
1171 
1172 	if (len < 4)
1173 	{
1174 		stack_message(STACK_ERROR, 0, "Frame too small");
1175 		return;
1176 	}
1177 
1178 	text_encoding = data[0];
1179 	if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
1180 	{
1181 		stack_message(STACK_ERROR, 0, "Text_encoding out of range");
1182 		return;
1183 	}
1184 
1185 	if ((data[1]<0x20)||(data[1]>=0x80)||
1186 	    (data[2]<0x20)||(data[2]>=0x80)||
1187 	    (data[3]<0x20)||(data[3]>=0x80))
1188 	{
1189 		print("language is invalid 0x%02x 0x%02x 0x%02x", data[1], data[2], data[3]);
1190 	} else {
1191 		print("language: \"%c%c%c\"", data[1], data[2], data[3]);
1192 	}
1193 	newline();
1194 
1195 	print("Content-Descriptor: ");
1196 	switch (text_encoding)
1197 	{
1198 		case 0x00:
1199 			print("LATIN1 ");
1200 			error = decode_print_iso8859_1 (&data, &len, 1);
1201 			break;
1202 		case 0x01:
1203 			print("UCS2 ");
1204 			error = decode_print_UCS2 (&data, &len, 1, 1);
1205 			break;
1206 		case 0x02:
1207 			print("UTF-16 ");
1208 			error = decode_print_UTF16 (&data, &len, 1);
1209 			break;
1210 		case 0x03:
1211 			print("UTF-8 ");
1212 			error = decode_print_UTF8 (&data, &len, 1);
1213 			break;
1214 	}
1215 	newline();
1216 	if (error)
1217 	{
1218 		return;
1219 	}
1220 	print("Lyrics/text: ");
1221 	switch (text_encoding)
1222 	{
1223 		case 0x00:
1224 			print("LATIN1 "); /* we are laxed on require NULL here */
1225 			error = decode_print_iso8859_1 (&data, &len, 0);
1226 			break;
1227 		case 0x01:
1228 			print("UCS2 ");
1229 			error = decode_print_UCS2 (&data, &len, 0, 0);
1230 			break;
1231 		case 0x02:
1232 			print("UTF-16 ");
1233 			error = decode_print_UTF16 (&data, &len, 0);
1234 			break;
1235 		case 0x03:
1236 			print("UTF-8 ");
1237 			error = decode_print_UTF8 (&data, &len, 0);
1238 			break;
1239 	}
1240 	newline();
1241 	if (error)
1242 	{
1243 		return;
1244 	}
1245 	if (len)
1246 	{
1247 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1248 	}
1249 }
1250 
decode_RVAD(uint8_t * data,uint32_t len,int version)1251 static void decode_RVAD(uint8_t *data, uint32_t len, int version)
1252 { /* ID3v220 used RVA, replaced with RVA2 in ID3v240 */
1253 	uint8_t flags;
1254 	uint8_t bits;
1255 	uint8_t bytesperchannel;
1256 	int i;
1257 	print("Relative volume adjustment"); newline();
1258 
1259 	if (len < 2)
1260 	{
1261 		stack_message(STACK_ERROR, 0, "Frame too small");
1262 		return;
1263 	}
1264 
1265 	flags = data[0];
1266 	bits = data[1];
1267 	data+=2;
1268 	len-=2;
1269 
1270 	if ((bits==0) || (bits > 64))
1271 	{
1272 		stack_message(STACK_ERROR, 0, "\"Bits used for volume descr.\" is out of range");
1273 		return;
1274 	}
1275 	bytesperchannel = (bits + 7)>>3;
1276 
1277 	if (flags & 0x03)
1278 	{
1279 		if (len < (bytesperchannel * 2 * ( (!!(flags & 0x01)) + (!!(flags & 0x02)) ) ) )
1280 		{
1281 			stack_message(STACK_ERROR, 0, "Ran out of data");
1282 			return;
1283 		}
1284 		if (flags & 0x01)
1285 		{
1286 			print(" Relative volume change, right: 0x");
1287 			for (i=0; i < bytesperchannel; i++)
1288 			{
1289 				print("%02x", data[0]);
1290 				data++;
1291 				len--;
1292 			}
1293 			newline();
1294 		}
1295 		if (flags & 0x02)
1296 		{
1297 			print("Relative volume change, left: 0x");
1298 			for (i=0; i < bytesperchannel; i++)
1299 			{
1300 				print("%02x", data[0]);
1301 				data++;
1302 				len--;
1303 			}
1304 			newline();
1305 		}
1306 		if (flags & 0x01)
1307 		{
1308 			print("Peak volume right:             0x");
1309 			for (i=0; i < bytesperchannel; i++)
1310 			{
1311 				print("%02x", data[0]);
1312 				data++;
1313 				len--;
1314 			}
1315 			newline();
1316 		}
1317 		if (flags & 0x02)
1318 		{
1319 			print("Peak volume left:             0x");
1320 			for (i=0; i < bytesperchannel; i++)
1321 			{
1322 				print("%02x", data[0]);
1323 				data++;
1324 				len--;
1325 			}
1326 			newline();
1327 		}
1328 	}
1329 
1330 	if (version < 3)
1331 	{
1332 		if (len)
1333 		{
1334 			stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1335 		}
1336 		return;
1337 	}
1338 
1339 	if (flags & 0x0c)
1340 	{
1341 		if (len < (bytesperchannel * 2 * ( (!!(flags & 0x08)) + (!!(flags & 0x04)) ) ) )
1342 		{
1343 			stack_message(STACK_ERROR, 0, "Ran out of data");
1344 			return;
1345 		}
1346 		if (flags & 0x04)
1347 		{
1348 			print("Relative volume change, right back: 0x");
1349 			for (i=0; i < bytesperchannel; i++)
1350 			{
1351 				print("%02x", data[0]);
1352 				data++;
1353 				len--;
1354 			}
1355 			newline();
1356 		}
1357 		if (flags & 0x08)
1358 		{
1359 			print("Relative volume change, left back: 0x");
1360 			for (i=0; i < bytesperchannel; i++)
1361 			{
1362 				print("%02x", data[0]);
1363 				data++;
1364 				len--;
1365 			}
1366 			newline();
1367 		}
1368 		if (flags & 0x04)
1369 		{
1370 			print("Peak volume right back:             0x");
1371 			for (i=0; i < bytesperchannel; i++)
1372 			{
1373 				print("%02x", data[0]);
1374 				data++;
1375 				len--;
1376 			}
1377 			newline();
1378 		}
1379 		if (flags & 0x08)
1380 		{
1381 			print("Peak volume left back:             0x");
1382 			for (i=0; i < bytesperchannel; i++)
1383 			{
1384 				print("%02x", data[0]);
1385 				data++;
1386 				len--;
1387 			}
1388 			newline();
1389 		}
1390 	}
1391 
1392 	if (flags & 0x10)
1393 	{
1394 		if (len < (bytesperchannel * 2) )
1395 		{
1396 			stack_message(STACK_ERROR, 0, "Ran out of data");
1397 			return;
1398 		}
1399 		print("Relative volume change, center: 0x");
1400 		for (i=0; i < bytesperchannel; i++)
1401 		{
1402 			print("%02x", data[0]);
1403 			data++;
1404 			len--;
1405 		}
1406 		newline();
1407 		print("Peak volume center:             0x");
1408 		for (i=0; i < bytesperchannel; i++)
1409 		{
1410 			print("%02x", data[0]);
1411 			data++;
1412 			len--;
1413 		}
1414 		newline();
1415 	}
1416 
1417 	if (flags & 0x20)
1418 	{
1419 		if (len < (bytesperchannel * 2) )
1420 		{
1421 			stack_message(STACK_ERROR, 0, "Ran out of data");
1422 			return;
1423 		}
1424 		print("Relative volume change, bass: 0x");
1425 		for (i=0; i < bytesperchannel; i++)
1426 		{
1427 			print("%02x", data[0]);
1428 			data++;
1429 			len--;
1430 		}
1431 		newline();
1432 		print("Peak volume bass:             0x");
1433 		for (i=0; i < bytesperchannel; i++)
1434 		{
1435 			print("%02x", data[0]);
1436 			data++;
1437 			len--;
1438 		}
1439 		newline();
1440 	}
1441 
1442 	if (len)
1443 	{
1444 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1445 	}
1446 }
1447 
decode_RVRB(uint8_t * data,uint32_t len)1448 static void decode_RVRB(uint8_t *data, uint32_t len)
1449 { /* ID3v220 used REV */
1450 	print("Reverb"); newline();
1451 
1452 	if (len < 12)
1453 	{
1454 		stack_message(STACK_ERROR, 0, "Frame too small");
1455 		return;
1456 	}
1457 
1458 	print("Reverb left (ms)                 %d ms", (data[0]<<8)|data[1]); newline();
1459 	print("Reverb right (ms)                %d ms", (data[2]<<8)|data[3]); newline();
1460 	print("Reverb bounces, left             %d/255", data[4]); newline();
1461 	print("Reverb bounces, right            %d/255", data[5]); newline();
1462 	print("Reverb feedback, left to left    %d/255", data[6]); newline();
1463 	print("Reverb feedback, left to right   %d/255", data[7]); newline();
1464 	print("Reverb feedback, right to right  %d/255", data[8]); newline();
1465 	print("Reverb feedback, right to left   %d/255", data[9]); newline();
1466 	print("Premix left to right             %d/255", data[10]); newline();
1467 	print("Premix right to left             %d/255", data[11]); newline();
1468 
1469 	data+=12;
1470 	len-=12;
1471 
1472 	if (len)
1473 	{
1474 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1475 	}
1476 }
1477 
decode_RVA2(uint8_t * data,uint32_t len)1478 static void decode_RVA2(uint8_t *data, uint32_t len)
1479 {
1480 	int error;
1481 	print("Relative volume adjustment (2)"); newline();
1482 
1483 	print("Identification: ");
1484 	error=decode_print_iso8859_1(&data, &len, 1);
1485 	newline();
1486 	if (error)
1487 	{
1488 		return;
1489 	}
1490 
1491 	while (len > 4)
1492 	{
1493 		uint16_t peakvolume = 0;
1494 		switch (data[0])
1495 		{
1496 			case 0x00: print("Type of channel:        Other"); break;
1497 			case 0x01: print("Type of channel:        Master volume"); break;
1498 			case 0x02: print("Type of channel:        Front right"); break;
1499 			case 0x03: print("Type of channel:        Front left"); break;
1500 			case 0x04: print("Type of channel:        Back right"); break;
1501 			case 0x05: print("Type of channel:        Back left"); break;
1502 			case 0x06: print("Type of channel:        Front centre"); break;
1503 			case 0x07: print("Type of channel:        Back centre"); break;
1504 			case 0x08: print("Type of channel:        Subwooder"); break;
1505 			default:   print("Type of channel:        (%d) Unknown", data[0]); break;
1506 		}
1507 		newline();
1508 
1509 		print("Volume adjustment:      %d", (data[1]<<8)|data[2]); newline();
1510 		print("Bits representing peak: %d", data[3]); newline();
1511 		data+=4;
1512 		len-=4;
1513 		while (data[0] == 0xff)
1514 		{
1515 			if (!len)
1516 			{
1517 				stack_message(STACK_ERROR, 0, "Ran out of data");
1518 				return;
1519 			}
1520 			peakvolume+=data[0];
1521 			data++;
1522 			len--;
1523 		}
1524 		if (!len)
1525 		{
1526 			stack_message(STACK_ERROR, 0, "Ran out of data");
1527 			return;
1528 		}
1529 		peakvolume+=data[0];
1530 		data++;
1531 		len--;
1532 		print("Peak volume:            %" PRId16, peakvolume); newline();
1533 	}
1534 
1535 	if (len)
1536 	{
1537 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1538 	}
1539 }
1540 
decode_POPM(uint8_t * data,uint32_t len)1541 static void decode_POPM(uint8_t *data, uint32_t len)
1542 { /* ID3v220 used POP */
1543 	int error;
1544 	print("Popularimeter");
1545 
1546 	if (!len)
1547 	{
1548 		stack_message(STACK_ERROR, 0, "Frame too small");
1549 		newline();
1550 		return;
1551 	}
1552 
1553 	print("Email to user: ");
1554 	error=decode_print_iso8859_1 (&data, &len, 1);
1555 	newline();
1556 	if (error)
1557 	{
1558 		return;
1559 	}
1560 
1561 	if (!len)
1562 	{
1563 		stack_message(STACK_ERROR, 0, "No space for rating");
1564 		return;
1565 	}
1566 	if (*data)
1567 	{
1568 		print("Rating: %d", *data);
1569 	} else {
1570 		print("Rating: unknown");
1571 	}
1572 	newline();
1573 	data++;
1574 	len--;
1575 
1576 	if (!len)
1577 	{
1578 		print("Counter: omitted");
1579 	} else {
1580 		uint64_t counter = 0;
1581 		while (len)
1582 		{
1583 			counter<<=8;
1584 			counter |= *data;
1585 			data++;
1586 			len--;
1587 		}
1588 		print("Counter: %"PRId64, counter);
1589 	}
1590 	newline();
1591 }
1592 
decode_LINK(uint8_t * data,uint32_t len)1593 static void decode_LINK(uint8_t *data, uint32_t len)
1594 { /* ID3v220 used LEN */
1595 	int error;
1596 	print("Link"); newline();
1597 
1598 	if (!len)
1599 	{
1600 		stack_message(STACK_ERROR, 0, "Frame too small");
1601 		return;
1602 	}
1603 
1604 	print("URL: ");
1605 	error = decode_print_iso8859_1 (&data, &len, 1);
1606 	newline();
1607 	if (error)
1608 	{
1609 		return;
1610 	}
1611 
1612 	print(" ID and additional data: "); /* we are laxed on the last zero here */
1613 	error=decode_print_iso8859_1 (&data, &len, 0);
1614 	newline();
1615 	if (error)
1616 	{
1617 		return;
1618 	}
1619 
1620 	if (len)
1621 	{
1622 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1623 	}
1624 }
1625 
decode_PCNT(uint8_t * data,uint32_t len)1626 static void decode_PCNT(uint8_t *data, uint32_t len)
1627 { /* ID3v220 used CNT */
1628 	uint64_t counter = 0;
1629 	print("Play Counter");
1630 
1631 	while (len)
1632 	{
1633 		counter<<=8;
1634 		counter |= *data;
1635 		data++;
1636 		len--;
1637 	}
1638 	print(" - Counter: %"PRId64, counter);
1639 	newline();
1640 }
1641 
decode_AENC(uint8_t * data,uint32_t len)1642 static void decode_AENC(uint8_t *data, uint32_t len)
1643 { /* ID3v220 used CRA */
1644 	int error;
1645 	print("Audio encryption"); newline();
1646 
1647 	print("Owner identifier: ");
1648 	error = decode_print_iso8859_1 (&data, &len, 1);
1649 	newline();
1650 	if (error)
1651 	{
1652 		return;
1653 	}
1654 	if (len < 4)
1655 	{
1656 		stack_message(STACK_ERROR, 0, "Ran out of data");
1657 		return;
1658 	}
1659 	print("Preview start: %d MPEG frames", (data[0]<<8)|data[1]); newline();
1660 	print("Preview length: %d MPEG frames", (data[2]<<8)|data[3]); newline();
1661 	print("Encryption info: 0x");
1662 	data+=4;
1663 	len-=4;
1664 	while (len)
1665 	{
1666 		print("%02x", data[0]);
1667 		data++;
1668 		len--;
1669 	}
1670 	newline();
1671 }
1672 
decode_COMM(uint8_t * data,uint32_t len,int version)1673 static void decode_COMM(uint8_t *data, uint32_t len, int version)
1674 { /* ID3v220 used COM */
1675 	uint8_t text_encoding;
1676 	int error;
1677 	print("Comments"); newline();
1678 
1679 	if (len < 4)
1680 	{
1681 		stack_message(STACK_ERROR, 0, "Frame too small");
1682 		return;
1683 	}
1684 
1685 	text_encoding = data[0];
1686 	if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
1687 	{
1688 		stack_message(STACK_ERROR, 0, "Text_encoding out of range");
1689 		return;
1690 	}
1691 	if ((data[1]<0x20)||(data[1]>=0x80)||
1692 	    (data[2]<0x20)||(data[2]>=0x80)||
1693 	    (data[3]<0x20)||(data[3]>=0x80))
1694 	{
1695 		print("language is invalid 0x%02x 0x%02x 0x%02x", data[1], data[2], data[3]);
1696 	} else {
1697 		print("language: \"%c%c%c\"", data[1], data[2], data[3]);
1698 	}
1699 	newline();
1700 
1701 	data+=4;
1702 	len-=4;
1703 
1704 	print("Content-Descriptor: ");
1705 	switch (text_encoding)
1706 	{
1707 		case 0x00:
1708 			print("LATIN1 ");
1709 			error=decode_print_iso8859_1 (&data, &len, 1);
1710 			break;
1711 		case 0x01:
1712 			print("UCS2 ");
1713 			error=decode_print_UCS2 (&data, &len, 1, 1);
1714 			break;
1715 		case 0x02:
1716 			print("UTF-16 ");
1717 			error=decode_print_UTF16 (&data, &len, 1);
1718 			break;
1719 		case 0x03:
1720 			print("UTF-8 ");
1721 			error=decode_print_UTF8 (&data, &len, 1);
1722 			break;
1723 	}
1724 	newline();
1725 	if (error)
1726 	{
1727 		return;
1728 	}
1729 	print("Comment/text: ");
1730 	switch (text_encoding)
1731 	{
1732 		case 0x00:
1733 			print("LATIN1 "); /* we are laxed on require NL here */
1734 			error=decode_print_iso8859_1 (&data, &len, 0);
1735 			break;
1736 		case 0x01:
1737 			print("UCS2 ");
1738 			error=decode_print_UCS2 (&data, &len, 0, 0);
1739 			break;
1740 		case 0x02:
1741 			print("UTF-16 ");
1742 			error=decode_print_UTF16 (&data, &len, 0);
1743 			break;
1744 		case 0x03:
1745 			print("UTF-8 ");
1746 			error=decode_print_UTF8 (&data, &len, 0);
1747 			break;
1748 	}
1749 	newline();
1750 	if (error)
1751 	{
1752 		return;
1753 	}
1754 
1755 	if (len)
1756 	{
1757 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1758 	}
1759 }
1760 
decode_PRIV(uint8_t * data,uint32_t len)1761 static void decode_PRIV(uint8_t *data, uint32_t len)
1762 { /* ID3v220 used COM */
1763 	int error;
1764 	print("Private"); newline();
1765 
1766 	print("Owner identifier:");
1767 	error=decode_print_iso8859_1 (&data, &len, 1);
1768 	newline();
1769 	if (error)
1770 	{
1771 		return;
1772 	}
1773 
1774 	print("The private data: 0x");
1775 	while (len)
1776 	{
1777 		print("%02x", data[0]);
1778 		data++;
1779 		len--;
1780 	}
1781 	newline();
1782 }
1783 
1784 
decode_USER(uint8_t * data,uint32_t len,int version)1785 static void decode_USER(uint8_t *data, uint32_t len, int version)
1786 {
1787 	int error;
1788 	uint8_t text_encoding;
1789 	print("Terms of use"); newline();
1790 
1791 	if (len < 4)
1792 	{
1793 		stack_message(STACK_ERROR, 0, "Frame too small");
1794 		return;
1795 	}
1796 
1797 	text_encoding = data[0];
1798 	if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
1799 	{
1800 		stack_message(STACK_ERROR, 0, "Text_encoding out of range");
1801 		return;
1802 	}
1803 	if ((data[1]<0x20)||(data[1]>=0x80)||
1804 	    (data[2]<0x20)||(data[2]>=0x80)||
1805 	    (data[3]<0x20)||(data[3]>=0x80))
1806 	{
1807 		print("language is invalid 0x%02x 0x%02x 0x%02x", data[1], data[2], data[3]);
1808 	} else {
1809 		print("language: \"%c%c%c\"", data[1], data[2], data[3]);
1810 	}
1811 	newline();
1812 	data+=4;
1813 	len-=4;
1814 
1815 	print("text: ");
1816 	switch (text_encoding)
1817 	{
1818 		case 0x00:
1819 			print("LATIN1 "); /* we are laxed on require NL here */
1820 			error = decode_print_iso8859_1 (&data, &len, 0);
1821 			break;
1822 		case 0x01:
1823 			print("UCS2 ");
1824 			error = decode_print_UCS2 (&data, &len, 0, 1);
1825 			break;
1826 		case 0x02:
1827 			print("UTF-16 ");
1828 			error=decode_print_UTF16 (&data, &len, 0);
1829 			break;
1830 		case 0x03:
1831 			print("UTF-8 ");
1832 			error=decode_print_UTF8 (&data, &len, 0);
1833 			break;
1834 	}
1835 	newline();
1836 	if (error)
1837 	{
1838 		return;
1839 	}
1840 
1841 	if (len)
1842 	{
1843 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1844 	}
1845 }
1846 
decode_COMR(uint8_t * data,uint32_t len,int version)1847 static void decode_COMR(uint8_t *data, uint32_t len, int version)
1848 {
1849 	int error;
1850 	uint8_t text_encoding;
1851 	print("Commercial frame"); newline();
1852 
1853 	if (len < 4)
1854 	{
1855 		stack_message(STACK_ERROR, 0, "Frame too small");
1856 		return;
1857 	}
1858 
1859 	text_encoding = data[0];
1860 	if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
1861 	{
1862 		stack_message(STACK_ERROR, 0, "Text_encoding out of range");
1863 		return;
1864 	}
1865 
1866 	print("Price string: ");
1867 	error = decode_print_iso8859_1 (&data, &len, 1);
1868 	newline();
1869 	if (error)
1870 	{
1871 		return;
1872 	}
1873 
1874 	if (len < 8)
1875 	{
1876 		stack_message(STACK_ERROR, 0, "Frame too small to contain field \"Valid until\"");
1877 		return;
1878 	}
1879 	print("Valid Until: \"%c%c%c%c%c%c%c%c\"", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); newline();
1880 	data+=8;
1881 	len-=8;
1882 
1883 	print("Contact URL: ");
1884 	error = decode_print_iso8859_1 (&data, &len, 1);
1885 	newline();
1886 	if (error)
1887 	{
1888 		return;
1889 	}
1890 
1891 	if (len < 1)
1892 	{
1893 		stack_message(STACK_ERROR, 0, "Frame too small to contain field \"Received as\"");
1894 		return;
1895 	}
1896 	switch (data[0])
1897 	{
1898 		case 0x00: print("Received as: Other"); break;
1899 		case 0x01: print("Received as: Standard CD album with other songs"); break;
1900 		case 0x02: print("Received as: Compressed audio on CD"); break;
1901 		case 0x03: print("Received as: File over the Internet"); break;
1902 		case 0x04: print("Received as: Stream over the Internet"); break;
1903 		case 0x05: print("Received as: As note sheets"); break;
1904 		case 0x06: print("Received as: As note sheets in a book with other sheets"); break;
1905 		case 0x07: print("Received as: Music on other media"); break;
1906 		case 0x08: print("Received as: Non-musical merchandise"); break;
1907 		default:   print("Received as: (%d)Unknown", data[0]); break;
1908 	}
1909 	newline();
1910 	data++;
1911 	len--;
1912 
1913 
1914 	print("name of seller: ");
1915 	switch (text_encoding)
1916 	{
1917 		case 0x00:
1918 			print("LATIN1 ");
1919 			error = decode_print_iso8859_1 (&data, &len, 1);
1920 			break;
1921 		case 0x01:
1922 			print("UCS2 ");
1923 			error = decode_print_UCS2 (&data, &len, 1, 1);
1924 			break;
1925 		case 0x02:
1926 			print("UTF-16 ");
1927 			error = decode_print_UTF16 (&data, &len, 1);
1928 			break;
1929 		case 0x03:
1930 			print("UTF-8 ");
1931 			error = decode_print_UTF8 (&data, &len, 1);
1932 			break;
1933 	}
1934 	newline();
1935 	if (error)
1936 	{
1937 		return;
1938 	}
1939 
1940 	print("Description: ");
1941 	switch (text_encoding)
1942 	{
1943 		case 0x00:
1944 			print("LATIN1 "); /* we are laxed on require NL here */
1945 			error = decode_print_iso8859_1 (&data, &len, 0);
1946 			break;
1947 		case 0x01:
1948 			print("UCS2 ");
1949 			error = decode_print_UCS2 (&data, &len, 0, 0);
1950 			break;
1951 		case 0x02:
1952 			print("UTF-16 ");
1953 			error = decode_print_UTF16 (&data, &len, 0);
1954 			break;
1955 		case 0x03:
1956 			print("UTF-8 ");
1957 			error = decode_print_UTF8 (&data, &len, 0);
1958 			break;
1959 	}
1960 	newline();
1961 	if (error)
1962 	{
1963 		return;
1964 	}
1965 
1966 	if (!len)
1967 	{
1968 		print("(Picture data omitted)"); newline();
1969 		return;
1970 	}
1971 
1972 	print("Picture MIME type: ");
1973 	error = decode_print_iso8859_1 (&data, &len, 1);
1974 	newline();
1975 	if (error)
1976 	{
1977 		return;
1978 	}
1979 	print("Seller logo: 0x");
1980 	while (len)
1981 	{
1982 		print("%02x", data[0]);
1983 		data++;
1984 		len--;
1985 	}
1986 	newline();
1987 }
1988 
decode_OWNE(uint8_t * data,uint32_t len,int version)1989 static void decode_OWNE(uint8_t *data, uint32_t len, int version)
1990 {
1991 	int error;
1992 	uint8_t text_encoding;
1993 	print("Ownership"); newline();
1994 
1995 	if (len < 4)
1996 	{
1997 		stack_message(STACK_ERROR, 0, "Frame too small");
1998 		return;
1999 	}
2000 
2001 	text_encoding = data[0];
2002 	if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
2003 	{
2004 		stack_message(STACK_ERROR, 0, "Text_encoding out of range");
2005 		return;
2006 	}
2007 
2008 	print("Price Payed: ");
2009 	error = decode_print_iso8859_1 (&data, &len, 1);
2010 	newline();
2011 	if (error)
2012 	{
2013 		return;
2014 	}
2015 
2016 	if (len < 8)
2017 	{
2018 		stack_message(STACK_ERROR, 0, "Frame too small to contain field \"Date of purchase\"");
2019 		return;
2020 	}
2021 	print("Date of purchase: \"%c%c%c%c%c%c%c%c\"", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); newline();
2022 	data+=8;
2023 	len-=8;
2024 
2025 	print("Seller: ");
2026 	switch (text_encoding)
2027 	{
2028 		case 0x00:
2029 			print(" LATIN1 "); /* we are laxed on require NL here */
2030 			error = decode_print_iso8859_1 (&data, &len, 0);
2031 			break;
2032 		case 0x01:
2033 			print(" UCS2 ");
2034 			error = decode_print_UCS2 (&data, &len, 0, 1);
2035 			break;
2036 		case 0x02:
2037 			print(" UTF-16 ");
2038 			error = decode_print_UTF16 (&data, &len, 0);
2039 			break;
2040 		case 0x03:
2041 			print(" UTF-8 ");
2042 			error = decode_print_UTF8 (&data, &len, 0);
2043 			break;
2044 	}
2045 	newline();
2046 	if (error)
2047 	{
2048 		return;
2049 	}
2050 
2051 	if (len)
2052 	{
2053 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
2054 	}
2055 }
2056 
decode_GRID(uint8_t * data,uint32_t len)2057 static void decode_GRID(uint8_t *data, uint32_t len)
2058 {
2059 	int error;
2060 
2061 	print("Group ID registration"); newline();
2062 
2063 	print("Owner identifier: ");
2064 	error = decode_print_iso8859_1 (&data, &len, 1);
2065 	newline();
2066 	if (error)
2067 	{
2068 		return;
2069 	}
2070 
2071 	if (!len)
2072 	{
2073 		stack_message(STACK_ERROR, 0, "Frame too small to contain field \"Group symbol\"");
2074 		return;
2075 	}
2076 	print("Group symbol: 0x%02x", data[0]); newline();
2077 	data++;
2078 	len--;
2079 	print("Group dependent data: 0x");
2080 	while (len)
2081 	{
2082 		print("%02x", data[0]);
2083 		data++;
2084 		len--;
2085 	}
2086 	newline();
2087 }
2088 
decode_ENCR(uint8_t * data,uint32_t len)2089 static void decode_ENCR(uint8_t *data, uint32_t len)
2090 {
2091 	int error;
2092 	print("Encryption method registration"); newline();
2093 
2094 	print("Owner identifier: ");
2095 	error = decode_print_iso8859_1 (&data, &len, 1);
2096 	newline();
2097 	if (error)
2098 	{
2099 		return;
2100 	}
2101 
2102 	if (!len)
2103 	{
2104 		stack_message(STACK_ERROR, 0, "Frame too small to contain field \"Group symbol\"");
2105 		return;
2106 	}
2107 	print("Method symbol: 0x%02x", data[0]); newline();
2108 	data++;
2109 	len--;
2110 
2111 	print("Encryption data: 0x");
2112 	while (len)
2113 	{
2114 		print("%02x", data[0]);
2115 		data++;
2116 		len--;
2117 	}
2118 	newline();
2119 }
2120 
decode_SIGN(uint8_t * data,uint32_t len)2121 static void decode_SIGN(uint8_t *data, uint32_t len)
2122 {
2123 	print("Signature"); newline();
2124 	if (!len)
2125 	{
2126 		stack_message(STACK_ERROR, 0, "Frame too small to contain field \"Group symbol\"");
2127 		return;
2128 	}
2129 
2130 	print("Group symbol: 0x%02x", data[0]); newline();
2131 	data++;
2132 	len--;
2133 
2134 	print("Signature data: 0x");
2135 	while (len)
2136 	{
2137 		print("%02x", data[0]);
2138 		data++;
2139 		len--;
2140 	}
2141 	newline();
2142 }
2143 
decode_CRM(uint8_t * data,uint32_t len)2144 static void decode_CRM(uint8_t *data, uint32_t len)
2145 { /* ID3v220 only */
2146 	int error;
2147 	print("Encrypted meta frame"); newline();
2148 
2149 	print("   Owner identifier: ");
2150 	error = decode_print_iso8859_1 (&data, &len, 1);
2151 	newline();
2152 
2153 	if (error)
2154 	{
2155 		return;
2156 	}
2157 
2158 	print("Content/explanation: ");
2159 	error = decode_print_iso8859_1 (&data, &len, 1);
2160 	newline();
2161 
2162 	if (error)
2163 	{
2164 		return;
2165 	}
2166 
2167 	print("Content: 0x");
2168 	while (len)
2169 	{
2170 		print("%02x", data[0]);
2171 		data++;
2172 		len--;
2173 	}
2174 	newline();
2175 }
2176 
decode_APIC(uint8_t * data,uint32_t len,int version)2177 static void decode_APIC(uint8_t *data, uint32_t len, int version)
2178 { /* ID3v220 used PIC */
2179 	uint8_t text_encoding;
2180 	int error;
2181 
2182 	print("Attached picture"); newline();
2183 
2184 	if (len < 1)
2185 	{
2186 		stack_message(STACK_ERROR, 0, "No space for \"text_encoding\"");
2187 		return;
2188 	}
2189 
2190 	text_encoding = data[0];
2191 	data++;
2192 	len--;
2193 
2194 	if ((text_encoding >= 2 && version < 4) || (text_encoding >= 4))
2195 	{
2196 		stack_message(STACK_ERROR, 0, "Text_encoding out of range");
2197 		return;
2198 	}
2199 
2200 	if (version <= 2)
2201 	{
2202 		if (len<3)
2203 		{
2204 			stack_message(STACK_ERROR, 0, "No space for \"Image format\"");
2205 			return;
2206 		}
2207 		print("Image format: \"%c%c%c\"", data[0], data[1], data[2]);newline();
2208 		len+=3;
2209 	} else {
2210 		int error;
2211 		print("MIME/type: ");
2212 		error = decode_print_iso8859_1(&data, &len, 1); newline();
2213 		if (error)
2214 		{
2215 			return;
2216 		}
2217 	}
2218 
2219 	if (len < 1)
2220 	{
2221 		stack_message(STACK_ERROR, 0, "No space for \"Picture Type\"");
2222 		return;
2223 	}
2224 	switch (data[0])
2225 	{
2226 		case 0x00: print("Picture type: Other"); break;
2227 		case 0x01: print("Picture type: 32x32 pixels 'file icon' (PNG only)"); break;
2228 		case 0x02: print("Picture type: Other file icon"); break;
2229 		case 0x03: print("Picture type: Cover (front)"); break;
2230 		case 0x04: print("Picture type: Cover (back)"); break;
2231 		case 0x05: print("Picture type: Leaflet page"); break;
2232 		case 0x06: print("Picture type: Media (e.g. lable side of CD)"); break;
2233 		case 0x07: print("Picture type: Lead artist/lead performer/soloist"); break;
2234 		case 0x08: print("Picture type: Artist/performer"); break;
2235 		case 0x09: print("Picture type: Conductor"); break;
2236 		case 0x0A: print("Picture type: Band/Orchestra"); break;
2237 		case 0x0B: print("Picture type: Composer"); break;
2238 		case 0x0C: print("Picture type: Lyricist/text writer"); break;
2239 		case 0x0D: print("Picture type: Recording Location"); break;
2240 		case 0x0E: print("Picture type: During recording"); break;
2241 		case 0x0F: print("Picture type: During performance"); break;
2242 		case 0x10: print("Picture type: Movie/video screen capture"); break;
2243 		case 0x11: print("Picture type: A bright coloured fish"); break;
2244 		case 0x12: print("Picture type: Illustration"); break;
2245 		case 0x13: print("Picture type: Band/artist logotype"); break;
2246 		case 0x14: print("Picture type: Publisher/Studio logotype"); break;
2247 		default:   print("Picture type: (%d)unknown", data[0]); break;
2248 	}
2249 	newline();
2250 	data++;
2251 	len--;
2252 
2253 	print("Description: ");
2254 	switch (text_encoding)
2255 	{
2256 		case 0x00:
2257 			print("LATIN1 ");
2258 			error = decode_print_iso8859_1(&data, &len, 1);
2259 			break;
2260 		case 0x01:
2261 			print("UCS-2 ");
2262 			error = decode_print_UCS2(&data, &len, 1, 1);
2263 			break;
2264 		case 0x02:
2265 			print("UTF-16 ");
2266 			error = decode_print_UTF16(&data, &len, 1);
2267 			break;
2268 		case 0x03:
2269 			print("UTF-8 ");
2270 			error = decode_print_UTF8(&data, &len, 1);
2271 			break;
2272 	}
2273 	newline();
2274 	if (error)
2275 	{
2276 		return;
2277 	}
2278 	print("Picture data: 0x");
2279 	while (len)
2280 	{
2281 		print("%02x", data[0]);
2282 		data++;
2283 		len--;
2284 	}
2285 	newline();
2286 }
2287 
decode_T(const char * description,uint8_t * data,uint32_t len,int version)2288 static void decode_T(const char *description, uint8_t *data, uint32_t len, int version)
2289 {
2290 	int added = 0;
2291 	int first = 1;
2292 	uint8_t text_encoding;
2293 
2294 	print("\"%-60s\" ", description);
2295 
2296 	if (len < 1)
2297 	{
2298 		stack_message(STACK_ERROR, 0, "No space for \"Text encoding\"");
2299 		return;
2300 	}
2301 
2302 	text_encoding = data[0];
2303 	data++;
2304 	len--;
2305 
2306 	if ((text_encoding >= 2 && version < 4) || (text_encoding >= 4))
2307 	{
2308 		stack_message(STACK_ERROR, 0, "Text_encoding out of range");
2309 		newline();
2310 	}
2311 
2312 	while (1)
2313 	{
2314 		int error = 1;
2315 		switch (text_encoding)
2316 		{
2317 			case 0x00:
2318 				print("LATIN1 ");
2319 				error = decode_print_iso8859_1(&data, &len, 0);
2320 				break;
2321 			case 0x01:
2322 				print("UCS-2 ");
2323 				error = decode_print_UCS2(&data, &len, 0, first);
2324 				break;
2325 			case 0x02:
2326 				print("UTF-16 ");
2327 				error = decode_print_UTF16(&data, &len, 0);
2328 				break;
2329 			case 0x03:
2330 				print("UTF-8 ");
2331 				error = decode_print_UTF8(&data, &len, 0);
2332 				break;
2333 		}
2334 		newline();
2335 		if (error || (!len))
2336 		{
2337 			indent -= added;
2338 			return;
2339 		}
2340 		if (version < 4)
2341 		{
2342 			if (len)
2343 			{
2344 				stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
2345 			}
2346 			indent -= added;
2347 			return;
2348 		}
2349 		if (first)
2350 		{
2351 			first=0;
2352 			added=10;
2353 			indent+=added;
2354 		}
2355 	}
2356 }
2357 
decode_TXXX(uint8_t * data,uint32_t len,int version)2358 static void decode_TXXX(uint8_t *data, uint32_t len, int version)
2359 {
2360 	int error;
2361 	uint8_t text_encoding;
2362 	print("Private text");
2363 
2364 	if (len < 1)
2365 	{
2366 		stack_message(STACK_ERROR, 0 , "No space for \"Text encoding\"");
2367 		return;
2368 	}
2369 
2370 	text_encoding = data[0];
2371 	data++;
2372 	len--;
2373 
2374 	if ((text_encoding >= 2 && version < 4) || (text_encoding >= 4))
2375 	{
2376 		stack_message(STACK_ERROR, 0, "Text_encoding out of range");
2377 		return;
2378 	}
2379 
2380 	switch (text_encoding)
2381 	{
2382 		case 0x00:
2383 			print("LATIN1 ");
2384 			error=decode_print_iso8859_1(&data, &len, 1);
2385 			break;
2386 		case 0x01:
2387 			print("UCS-2 ");
2388 			error=decode_print_UCS2(&data, &len, 1, 1);
2389 			break;
2390 		case 0x02:
2391 			print("UTF-16 ");
2392 			error=decode_print_UTF16(&data, &len, 1);
2393 			break;
2394 		case 0x03:
2395 			print("UTF-8 ");
2396 			error=decode_print_UTF8(&data, &len, 1);
2397 			break;
2398 	}
2399 	if (error)
2400 	{
2401 		newline();
2402 		return;
2403 	}
2404 	print(" = ");
2405 	switch (text_encoding)
2406 	{
2407 		case 0x00:
2408 			print("LATIN1 ");
2409 			error = decode_print_iso8859_1(&data, &len, 0);
2410 			break;
2411 		case 0x01:
2412 			print("UCS-2 ");
2413 			error = decode_print_UCS2(&data, &len, 0, 0);
2414 			break;
2415 		case 0x02:
2416 			print("UTF-16 ");
2417 			error = decode_print_UTF16(&data, &len, 0);
2418 			break;
2419 		case 0x03:
2420 			print("UTF-8 ");
2421 			error = decode_print_UTF8(&data, &len, 0);
2422 			break;
2423 	}
2424 	newline();
2425 	if (error)
2426 	{
2427 		return;
2428 	}
2429 	if (len)
2430 	{
2431 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
2432 	}
2433 }
2434 
decode_W(const char * description,uint8_t * data,uint32_t len)2435 static void decode_W(const char *description, uint8_t *data, uint32_t len)
2436 {
2437 	print("\"%s\" ", description);
2438 
2439 	decode_print_iso8859_1(&data, &len, 0);
2440 	newline();
2441 
2442 	if (len)
2443 	{
2444 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
2445 	}
2446 }
2447 
decode_WXXX(uint8_t * data,uint32_t len,int version)2448 static void decode_WXXX(uint8_t *data, uint32_t len, int version)
2449 {
2450 	int error;
2451 	uint8_t text_encoding;
2452 	print("Private URL");
2453 	newline();
2454 
2455 	if (len < 1)
2456 	{
2457 		stack_message(STACK_ERROR, 0, "No space for \"Text encoding\"");
2458 		return;
2459 	}
2460 
2461 	text_encoding = data[0];
2462 	data++;
2463 	len--;
2464 
2465 	if ((text_encoding >= 2 && version < 4) || (text_encoding >= 4))
2466 	{
2467 		stack_message(STACK_ERROR, 0, "Text_encoding out of range");
2468 		return;
2469 	}
2470 
2471 	switch (text_encoding)
2472 	{
2473 		case 0x00:
2474 			print("LATIN1 ");
2475 			error=decode_print_iso8859_1(&data, &len, 1);
2476 			break;
2477 		case 0x01:
2478 			print("UCS-2 ");
2479 			error=decode_print_UCS2(&data, &len, 1, 1);
2480 			return;
2481 		case 0x02:
2482 			print("UTF-16 ");
2483 			error=decode_print_UTF16(&data, &len, 1);
2484 			break;
2485 		case 0x03:
2486 			print("UTF-8 ");
2487 			error=decode_print_UTF8(&data, &len, 1);
2488 			break;
2489 	}
2490 	if (error)
2491 	{
2492 		newline();
2493 		return;
2494 	}
2495 	print(" = ");
2496 	error = decode_print_iso8859_1(&data, &len, 0);
2497 	newline();
2498 	if (error)
2499 	{
2500 		return;
2501 	}
2502 
2503 	if (len)
2504 	{
2505 		stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
2506 	}
2507 }
2508 
decode_Tn(const char * description,uint8_t * data,uint32_t len,int version)2509 static void decode_Tn(const char *description, uint8_t *data, uint32_t len, int version)
2510 {
2511 	uint8_t text_encoding;
2512 	int first = 1;
2513 	print("%s", description);
2514 
2515 	if (len < 1)
2516 	{
2517 		stack_message(STACK_ERROR, 0, "No space for \"Text encoding\"");
2518 		newline();
2519 		return;
2520 	}
2521 
2522 	text_encoding = data[0];
2523 	data++;
2524 	len--;
2525 
2526 	if ((text_encoding >= 2 && version < 4) || (text_encoding >= 4))
2527 	{
2528 		stack_message(STACK_ERROR, 0, "Text_encoding out of range");
2529 		newline();
2530 	}
2531 
2532 	switch (text_encoding)
2533 	{
2534 		case 0x00:
2535 			print(" LATIN1");
2536 			newline();
2537 			while (len)
2538 			{
2539 				int error = decode_print_iso8859_1(&data, &len, 0);
2540 				newline();
2541 				if (error)
2542 				{
2543 					return;
2544 				}
2545 			}
2546 			return;
2547 		case 0x01:
2548 			print(" UCS-2");
2549 			newline();
2550 			while (len)
2551 			{
2552 				int error=decode_print_UCS2(&data, &len, 0, first);
2553 				newline();
2554 				if (error)
2555 				{
2556 					return;
2557 				}
2558 				first=0;
2559 			}
2560 			return;
2561 		case 0x02:
2562 			print(" UTF-16");
2563 			newline();
2564 			while (len)
2565 			{
2566 				int error = decode_print_UTF16(&data, &len, 0);
2567 				newline();
2568 				if (error)
2569 				{
2570 					return;
2571 				}
2572 			}
2573 			return;
2574 		case 0x03:
2575 			print(" UTF-8");
2576 			newline();
2577 			while (len)
2578 			{
2579 				int error = decode_print_UTF8(&data, &len, 0);
2580 				newline();
2581 				if (error)
2582 				{
2583 					return;
2584 				}
2585 			}
2586 			return;
2587 	}
2588 }
2589 
zalloc(void * q,unsigned int n,unsigned m)2590 static void *zalloc(void *q, unsigned int n, unsigned m)
2591 {
2592 	(void)q;
2593 	return calloc(n, m);
2594 }
2595 
zfree(void * q,void * p)2596 static void zfree(void *q, void *p)
2597 {
2598 	(void)q;
2599 	free(p);
2600 }
2601 
decode_id3v240_frame(uint8_t * ptr,uint32_t len)2602 static int32_t decode_id3v240_frame(uint8_t *ptr, uint32_t len)
2603 {
2604 	uint8_t FrameId[4];
2605 	uint32_t inputsize;
2606 	uint8_t *frameptr, *zlibptr=0;
2607 	uint32_t framelen;
2608 	uint32_t zlib_new_framelen=0xffffff;
2609 	uint16_t flags;
2610 
2611 	if (len < 11)
2612 	{
2613 		print("*-*-* ERROR, Minimum frame length is 11 bytes"); newline();
2614 		return -1;
2615 	}
2616 
2617 	FrameId[0] = ptr[0];
2618 	FrameId[1] = ptr[1];
2619 	FrameId[2] = ptr[2];
2620 	FrameId[3] = ptr[3];
2621 
2622 	if ((FrameId[0] < 0x20) || (FrameId[0] >= 0x80) ||
2623 	    (FrameId[1] < 0x20) || (FrameId[1] >= 0x80) ||
2624 	    (FrameId[2] < 0x20) || (FrameId[2] >= 0x80) ||
2625 	    (FrameId[3] < 0x20) || (FrameId[3] >= 0x80))
2626 	{
2627 		print("Invalid frame ID %02x %02x %02x %02x", FrameId[0], FrameId[1], FrameId[2], FrameId[3]); newline();
2628 		return -1;
2629 	}
2630 
2631 	flags = (ptr[8]<<8)|(ptr[9]);
2632 
2633 	if ((ptr[4] & 0x80) |
2634 	    (ptr[5] & 0x80) |
2635 	    (ptr[6] & 0x80) |
2636 	    (ptr[7] & 0x80))
2637 	{
2638 		stack_message(STACK_WARNING, 0, "Framelength not valid not valid %02x %02x %02x %02x, trying to use 2.3.0 syntax", ptr[4], ptr[5], ptr[6], ptr[7]);
2639 		framelen = inputsize = (ptr[4]<<24)|(ptr[5]<<16)|(ptr[6]<<8)|ptr[7]; /* attempt to ressurect broken FRAME, iTunes of some version*/
2640 	} else {
2641 		framelen = inputsize = (ptr[4]<<21)|(ptr[5]<<14)|(ptr[6]<<7)|ptr[7];
2642 	}
2643 	frameptr = ptr + 10;
2644 	len-=10;
2645 
2646 	print("Frame %c%c%c%c (%5"PRId32" bytes) - ", FrameId[0], FrameId[1], FrameId[2], FrameId[3], inputsize);
2647 	indent++;
2648 
2649 	if (inputsize > len)
2650 	{
2651 		stack_message(STACK_ERROR, 0, "We are missing %d of data in this frame", inputsize - len);
2652 		newline();
2653 		indent--;
2654 		return -1;
2655 	}
2656 
2657 	print("FLAGS=0x%04"PRIx16" ", flags);
2658 
2659 	/* part-1, parse header */
2660 #if 0
2661 	/* these are very noisy to see */
2662 	if (flags & 0x4000) printf (" Tag  alter preservation: Frame should be discarded.\n"); else printf (" Tag  alter preservation: Frame should be preserved.\n");
2663 	if (flags & 0x2000) printf (" File alter preservation: Frame should be discarded.\n"); else printf (" File alter preservation: Frame should be preserved.\n");
2664 	if (flags & 0x1000) printf (" Frame is Read only\n"); else printf (" Frame is Read/Write\n");
2665 #endif
2666 
2667 	if (flags & 0x0008)
2668 	{
2669 		if (!(flags & 0x0001))
2670 		{
2671 			stack_message(STACK_ERROR, 0, "Compression flag set, without data length indicicator");
2672 			newline();
2673 			goto ignoreframe;
2674 		}
2675 	}
2676 	if (flags & 0x0004)
2677 	{
2678 		uint8_t method;
2679 		if (framelen < 1)
2680 		{
2681 			stack_message(STACK_ERROR, 0, "*-*-* ERROR, Encryption set, but no space for method field");
2682 		} else {
2683 			method = frameptr[0];
2684 			frameptr++;
2685 			framelen--;
2686 			stack_message(STACK_INFO, 0, "Frame is encrypted (method %d), ignoring it", method);
2687 		}
2688 		newline();
2689 		goto ignoreframe;
2690 	}
2691 	if (flags & 0x0040)
2692 	{
2693 		if (framelen < 1)
2694 		{
2695 			stack_message(STACK_WARNING, 0, "Grouping set, but no space for Frame grouping information");
2696 		} else {
2697 			stack_message(STACK_INFO, 0, "Frame is grouped with ID=%d", frameptr[0]);
2698 			frameptr++;
2699 			framelen--;
2700 		}
2701 	}
2702 	if (flags & 0x0002)
2703 	{
2704 		stack_message(STACK_INFO, 0, "Frame is unsynced");
2705 		unsync (frameptr, &framelen);
2706 	}
2707 
2708 	if (framelen == 0)
2709 	{
2710 		stack_message(STACK_ERROR, 0, "Frame with zero-length");
2711 		flush();
2712 		indent--;
2713 		return -1;
2714 	}
2715 
2716 	if (flags & 0x0001)
2717 	{
2718 		uint32_t temp;
2719 
2720 		if (framelen < 4)
2721 		{
2722 			stack_message(STACK_ERROR, 0, "Data-Length-Indicator set, but no space for outputsize field (skipping to next frame)");
2723 			newline();
2724 			goto ignoreframe;
2725 		}
2726 
2727 		temp = (frameptr[0]<<21)|(frameptr[1]<<14)|(frameptr[2]<<7)|frameptr[3];
2728 		frameptr+=4;
2729 		framelen-=4;
2730 
2731 		if (flags & 0x0008)
2732 		{
2733 			if (temp > 32*1024*1024)
2734 			{
2735 				stack_message(STACK_WARNING, 0, "Decompression bigger than 32MB, blocking it");
2736 				newline();
2737 				goto ignoreframe;
2738 			}
2739 			zlib_new_framelen = temp;
2740 			if (!zlib_new_framelen)
2741 			{
2742 				stack_message(STACK_ERROR, 0, "Decompression size of zero bytes");
2743 				newline();
2744 				goto ignoreframe;
2745 			}
2746 		} else {
2747 			if (temp > framelen)
2748 			{
2749 				stack_message(STACK_WARNING, 0, "Data-Length-Indicator overshots the original framelen");
2750 			} else {
2751 				stack_message(STACK_INFO, 0, "framelen forcefully set from % " PRId32 " to %" PRId32 " bytes", framelen, temp);
2752 				framelen = temp;
2753 			}
2754 		}
2755 	}
2756 	/* part-2 fix the data*/
2757 	if (flags & 0x0008)
2758 	{
2759 		int result;
2760 
2761 		z_stream strm;
2762 		zlibptr = malloc (zlib_new_framelen);
2763 
2764 		strm.zalloc = zalloc;
2765 		strm.zfree = zfree;
2766 		strm.opaque = (voidpf)0;
2767 		strm.avail_in = framelen;
2768 		strm.next_in = frameptr;
2769 		strm.avail_out = zlib_new_framelen;
2770 		strm.next_out = zlibptr;
2771 		stack_message(STACK_INFO, 0, "Frame is compressed (inputsize=%" PRId32 ", outputsize=%" PRId32 ")", framelen, zlib_new_framelen);
2772 
2773 		if (inflateInit(&strm))
2774 		{
2775 			stack_message(STACK_ERROR, 0, "Zlib failed to init");
2776 			newline();
2777 			goto ignoreframe;
2778 		}
2779 		result = inflate(&strm, Z_FINISH);
2780 		if (result == Z_STREAM_ERROR ||
2781 		    result == Z_NEED_DICT ||
2782 		    result == Z_DATA_ERROR ||
2783 		    result == Z_MEM_ERROR)
2784 		{
2785 			stack_message(STACK_ERROR, 0, "Zlib failed to decompress");
2786 			if (result != Z_STREAM_ERROR)
2787 			{
2788 				inflateEnd (&strm);
2789 			}
2790 			newline();
2791 			goto ignoreframe;
2792 		}
2793 		if (strm.avail_in != 0)
2794 		{
2795 			stack_message(STACK_WARNING, 0, "Zlib did not consume the entire input, %d bytes left", (int)strm.avail_in);
2796 		}
2797 		if (strm.avail_out != 0)
2798 		{
2799 			stack_message(STACK_WARNING, 0, "Zlib did not fill the entire output, %d bytes left", (int)strm.avail_out);
2800 			memset (strm.next_out, 0, strm.avail_out);
2801 		}
2802 		inflateEnd (&strm);
2803 		frameptr = zlibptr;
2804 		framelen = zlib_new_framelen;
2805 	}
2806 
2807 	indent++;
2808 
2809 	     if (!memcmp(FrameId, "AENC", 4)) decode_AENC(                                                                frameptr, framelen);
2810 	else if (!memcmp(FrameId, "APIC", 4)) decode_APIC(                                                                frameptr, framelen, 4);
2811 	else if (!memcmp(FrameId, "ASPI", 4)) decode_ASPI(                                                                frameptr, framelen);
2812 	else if (!memcmp(FrameId, "COMM", 4)) decode_COMM(                                                                frameptr, framelen, 4);
2813 	else if (!memcmp(FrameId, "COMR", 4)) decode_COMR(                                                                frameptr, framelen, 4);
2814 	else if (!memcmp(FrameId, "ENCR", 4)) decode_ENCR(                                                                frameptr, framelen);
2815 	else if (!memcmp(FrameId, "EQU2", 4)) decode_EQU2(                                                                frameptr, framelen);
2816 	/* NOT SUPPORTED ANY MORE
2817 	else if (!memcmp(FrameId, "EQUA", 4)) decode_EQUA(                                                                frameptr, framelen);
2818 	*/
2819 	else if (!memcmp(FrameId, "ETCO", 4)) decode_ETCO(                                                                frameptr, framelen, 4);
2820 	else if (!memcmp(FrameId, "GEOB", 4)) decode_GEOB(                                                                frameptr, framelen, 4);
2821 	else if (!memcmp(FrameId, "GRID", 4)) decode_GRID(                                                                frameptr, framelen);
2822 	/* NOT SUPPORTED ANY MORE
2823 	else if (!memcmp(FrameId, "IPLS", 4)) decode_Tn  ("Involved people list",                                         frameptr, framelen, 4);
2824 	*/
2825 	else if (!memcmp(FrameId, "LINK", 4)) decode_LINK(                                                                frameptr, framelen);
2826 	else if (!memcmp(FrameId, "MCDI", 4)) decode_MCDI(                                                                frameptr, framelen);
2827 	else if (!memcmp(FrameId, "MLLT", 4)) decode_MLLT(                                                                frameptr, framelen);
2828 	else if (!memcmp(FrameId, "OWNE", 4)) decode_OWNE(                                                                frameptr, framelen, 4);
2829 	else if (!memcmp(FrameId, "PRIV", 4)) decode_PRIV(                                                                frameptr, framelen);
2830 	else if (!memcmp(FrameId, "PCNT", 4)) decode_PCNT(                                                                frameptr, framelen);
2831 	else if (!memcmp(FrameId, "POPM", 4)) decode_POPM(                                                                frameptr, framelen);
2832 	else if (!memcmp(FrameId, "POSS", 4)) decode_POSS(                                                                frameptr, framelen);
2833 	else if (!memcmp(FrameId, "RBUF", 4)) decode_RBUF(                                                                frameptr, framelen);
2834 	else if (!memcmp(FrameId, "RVA2", 4)) decode_RVA2(                                                                frameptr, framelen);
2835 	/* NOT SUPPORTED ANY MORE
2836 	else if (!memcmp(FrameId, "RVAD", 4)) decode_RVAD(                                                                frameptr, framelen, 4);
2837 	*/
2838 	else if (!memcmp(FrameId, "RVRB", 4)) decode_RVRB(                                                                frameptr, framelen);
2839 	else if (!memcmp(FrameId, "SEEK", 4)) decode_SEEK(                                                                frameptr, framelen);
2840 	else if (!memcmp(FrameId, "SIGN", 4)) decode_SIGN(                                                                frameptr, framelen);
2841 	else if (!memcmp(FrameId, "SYLT", 4)) decode_SYLT(                                                                frameptr, framelen, 4);
2842 	else if (!memcmp(FrameId, "SYTC", 3)) decode_SYTC(                                                                frameptr, framelen);
2843 	else if (!memcmp(FrameId, "TALB", 4)) decode_T   ("Album/Movie/Show title",                                       frameptr, framelen, 4);
2844 	else if (!memcmp(FrameId, "TBPM", 4)) decode_T   ("BPM",                                                          frameptr, framelen, 4);
2845 	else if (!memcmp(FrameId, "TCOM", 4)) decode_T   ("Composer(s)",                                                  frameptr, framelen, 4);
2846 	else if (!memcmp(FrameId, "TCON", 4)) decode_T   ("Content (ID3v1 (n)String encoded)",                            frameptr, framelen, 4);
2847 	else if (!memcmp(FrameId, "TCOP", 4)) decode_T   ("Copyright message",                                            frameptr, framelen, 4);
2848 	/* NOT SUPPORTED ANY MORE
2849 	else if (!memcmp(FrameId, "TDAT", 4)) decode_T   ("Date (DDMM encoded)",                                          frameptr, framelen, 4);
2850 	*/
2851 	else if (!memcmp(FrameId, "TDEN", 4)) decode_T   ("Encoding time",                                                frameptr, framelen, 4);
2852 	else if (!memcmp(FrameId, "TDLY", 4)) decode_T   ("Playlist delay",                                               frameptr, framelen, 4);
2853 	else if (!memcmp(FrameId, "TDOR", 4)) decode_T   ("Original release time",                                        frameptr, framelen, 4);
2854 	else if (!memcmp(FrameId, "TDRC", 4)) decode_T   ("Recording time",                                               frameptr, framelen, 4);
2855 	else if (!memcmp(FrameId, "TDRL", 4)) decode_T   ("Release time",                                                 frameptr, framelen, 4);
2856 	else if (!memcmp(FrameId, "TDTG", 4)) decode_T   ("Tagging time",                                                 frameptr, framelen, 4);
2857 	else if (!memcmp(FrameId, "TENC", 4)) decode_T   ("Encoded by",                                                   frameptr, framelen, 4);
2858 	else if (!memcmp(FrameId, "TEXT", 4)) decode_T   ("Lyricist(s)/text writer(s)",                                   frameptr, framelen, 4);
2859 	else if (!memcmp(FrameId, "TFLT", 4)) decode_T   ("File type",                                                    frameptr, framelen, 4);
2860 	/* NOT SUPPORTED ANY MORE
2861 	else if (!memcmp(FrameId, "TIME", 4)) decode_T   ("Time (HHMM encoded)",                                          frameptr, framelen, 4);
2862 	*/
2863 	else if (!memcmp(FrameId, "TIPL", 4)) decode_T   ("Involved people list",                                         frameptr, framelen, 4);
2864 	else if (!memcmp(FrameId, "TIT1", 4)) decode_T   ("Content group description",                                    frameptr, framelen, 4);
2865 	else if (!memcmp(FrameId, "TIT2", 4)) decode_T   ("Title/Songname/Content description",                           frameptr, framelen, 4);
2866 	else if (!memcmp(FrameId, "TIT3", 4)) decode_T   ("Subtitle/Description refinement",                              frameptr, framelen, 4);
2867 	else if (!memcmp(FrameId, "TKEY", 4)) decode_T   ("Initial key",                                                  frameptr, framelen, 4);
2868 	else if (!memcmp(FrameId, "TLAN", 4)) decode_T   ("Language(s) (ISO-639-2)",                                      frameptr, framelen, 4);
2869 	else if (!memcmp(FrameId, "TLEN", 4)) decode_T   ("Length (in milliseconds)",                                     frameptr, framelen, 4);
2870 	else if (!memcmp(FrameId, "TMCL", 4)) decode_T   ("Musician credits list",/*New*/                                 frameptr, framelen, 4);
2871 	else if (!memcmp(FrameId, "TMED", 4)) decode_T   ("Media type",                                                   frameptr, framelen, 4);
2872 	else if (!memcmp(FrameId, "TMOO", 4)) decode_T   ("Mood",                                                         frameptr, framelen, 4);
2873 	else if (!memcmp(FrameId, "TOAL", 4)) decode_T   ("Original album/Movie/Show title",                              frameptr, framelen, 4);
2874 	else if (!memcmp(FrameId, "TOFN", 4)) decode_T   ("Original filename",                                            frameptr, framelen, 4);
2875 	else if (!memcmp(FrameId, "TOLY", 4)) decode_T   ("Original Lyricist(s)/text writer(s)",                          frameptr, framelen, 4);
2876 	else if (!memcmp(FrameId, "TOPE", 4)) decode_T   ("Original artist(s)/performer(s)",                              frameptr, framelen, 4);
2877 	/* NOT SUPPORTED ANY MORE
2878 	else if (!memcmp(FrameId, "TORY", 4)) decode_T   ("Original release year",                                        frameptr, framelen, 4);
2879 	*/
2880 	else if (!memcmp(FrameId, "TOWN", 4)) decode_T   ("File Owner/License",/*New*/                                    frameptr, framelen, 4);
2881 	else if (!memcmp(FrameId, "TPE1", 4)) decode_T   ("Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group", frameptr, framelen, 4);
2882 	else if (!memcmp(FrameId, "TPE2", 4)) decode_T   ("Band/Orchestra/Accompaniment",                                 frameptr, framelen, 4);
2883 	else if (!memcmp(FrameId, "TPE3", 4)) decode_T   ("Conductor",                                                    frameptr, framelen, 4);
2884 	else if (!memcmp(FrameId, "TPE4", 4)) decode_T   ("Interpreted, remixed, or otherwise modified by",               frameptr, framelen, 4);
2885 	else if (!memcmp(FrameId, "TPOS", 4)) decode_T   ("Part of a set",                                                frameptr, framelen, 4);
2886 	else if (!memcmp(FrameId, "TPRO", 4)) decode_T   ("Produced notice",                                              frameptr, framelen, 4);
2887 	else if (!memcmp(FrameId, "TPUB", 4)) decode_T   ("Publisher",                                                    frameptr, framelen, 4);
2888 	else if (!memcmp(FrameId, "TRCK", 4)) decode_T   ("Track number/Position in set (#/total encoded)",               frameptr, framelen, 4);
2889 	/* NOT SUPPORTED ANY MORE
2890 	else if (!memcmp(FrameId, "TRDA", 4)) decode_T   ("Recording dates",                                              frameptr, framelen, 4);
2891 	*/
2892 	else if (!memcmp(FrameId, "TRSN", 4)) decode_T   ("Internet radio station name",/*New*/                           frameptr, framelen, 4);
2893 	else if (!memcmp(FrameId, "TRSO", 4)) decode_T   ("Internet radio station Owner",/*New*/                          frameptr, framelen, 4);
2894 	/* NOT SUPPORTED ANY MORE
2895 	else if (!memcmp(FrameId, "TSIZ", 4)) decode_T   ("Size (file in bytes)",                                         frameptr, framelen, 4);
2896 	*/
2897 	else if (!memcmp(FrameId, "TSOA", 4)) decode_T   ("Album sort order",                                             frameptr, framelen, 4);
2898 	else if (!memcmp(FrameId, "TSOP", 4)) decode_T   ("Performer sort order",                                         frameptr, framelen, 4);
2899 	else if (!memcmp(FrameId, "TSOT", 4)) decode_T   ("Title sort order",                                             frameptr, framelen, 4);
2900 	else if (!memcmp(FrameId, "TSRC", 4)) decode_T   ("International Standard Recording Code (ISO 3901:1986)",        frameptr, framelen, 4);
2901 	else if (!memcmp(FrameId, "TSSE", 4)) decode_T   ("Software/hardware and settings used for encoding",             frameptr, framelen, 4);
2902 	else if (!memcmp(FrameId, "TSST", 4)) decode_T   ("Set subtitle"                                    ,             frameptr, framelen, 4);
2903 	/* NOT SUPPORTED ANY MORE
2904 	else if (!memcmp(FrameId, "TYER", 4)) decode_T   ("Year (YYYY encoded)",                                          frameptr, framelen, 4);
2905 	*/
2906 	else if (!memcmp(FrameId, "TXXX", 4)) decode_TXXX(                                                                frameptr, framelen, 4);
2907 	else if (!memcmp(FrameId, "UFID", 4)) decode_UFID(                                                                frameptr, framelen);
2908 	else if (!memcmp(FrameId, "USER", 4)) decode_USER(                                                                frameptr, framelen, 4);
2909 	else if (!memcmp(FrameId, "USLT", 3)) decode_USLT(                                                                frameptr, framelen, 4);
2910 	else if (!memcmp(FrameId, "WCOM", 4)) decode_W   ("Commercial information",                                       frameptr, framelen);
2911 	else if (!memcmp(FrameId, "WCOP", 4)) decode_W   ("Copyright/Legal information",                                  frameptr, framelen);
2912 	else if (!memcmp(FrameId, "WOAF", 4)) decode_W   ("Official audio file webpage",                                  frameptr, framelen);
2913 	else if (!memcmp(FrameId, "WOAR", 4)) decode_W   ("Official artist/performer webpage",                            frameptr, framelen);
2914 	else if (!memcmp(FrameId, "WOAS", 4)) decode_W   ("Official audio source webpage",                                frameptr, framelen);
2915 	else if (!memcmp(FrameId, "WORS", 4)) decode_W   ("Official internet radio station homepage",/*New*/              frameptr, framelen);
2916 	else if (!memcmp(FrameId, "WPAY", 4)) decode_W   ("Payment",/*New*/                                               frameptr, framelen);
2917 	else if (!memcmp(FrameId, "WPUB", 4)) decode_W   ("Publishers official webpage",                                  frameptr, framelen);
2918 	else if (!memcmp(FrameId, "WXXX", 4)) decode_WXXX(                                                                frameptr, framelen,4);
2919 	else if ((FrameId[0]=='T')&&
2920 		(((FrameId[1]>='0')&&(FrameId[1]<='9'))||((FrameId[1]>='a')&&(FrameId[1]<='z'))||((FrameId[1]>='A')&&(FrameId[1]<='Z')))&&
2921 		(((FrameId[2]>='0')&&(FrameId[2]<='9'))||((FrameId[2]>='a')&&(FrameId[2]<='z'))||((FrameId[2]>='A')&&(FrameId[2]<='Z')))&&
2922 		(((FrameId[3]>='0')&&(FrameId[3]<='9'))||((FrameId[3]>='a')&&(FrameId[3]<='z'))||((FrameId[3]>='A')&&(FrameId[3]<='Z'))))
2923 	{
2924 		decode_T("Unknown Text", frameptr, framelen, 4);
2925 	}
2926 	else if ((FrameId[0]=='W')&&
2927 		(((FrameId[1]>='0')&&(FrameId[1]<='9'))||((FrameId[1]>='a')&&(FrameId[1]<='z'))||((FrameId[1]>='A')&&(FrameId[1]<='Z')))&&
2928 		(((FrameId[2]>='0')&&(FrameId[2]<='9'))||((FrameId[2]>='a')&&(FrameId[2]<='z'))||((FrameId[2]>='A')&&(FrameId[2]<='Z')))&&
2929 		(((FrameId[3]>='0')&&(FrameId[3]<='9'))||((FrameId[3]>='a')&&(FrameId[3]<='z'))||((FrameId[3]>='A')&&(FrameId[3]<='Z'))))
2930 	{
2931 		decode_W("Unknown URL", frameptr, framelen);
2932 	} else {
2933 		print("Unknown frame"); newline();
2934 	}
2935 	flush();
2936 	indent--;
2937 ignoreframe:
2938 	indent--;
2939 	if (zlibptr)
2940 	{
2941 		free (zlibptr);
2942 		zlibptr = 0;
2943 	}
2944 	return (int32_t)(inputsize + 10);
2945 }
2946 
decode_id3v240(uint8_t * data,uint32_t _length,int fd)2947 static void decode_id3v240(uint8_t *data, uint32_t _length, int fd)
2948 {
2949 	uint8_t *ptr = data;
2950 	uint32_t len = _length;
2951 	uint8_t flags = data[5];
2952 
2953 	ptr = data;
2954 	len = _length;
2955 
2956 	if (flags & 0x80)
2957 	{
2958 		print(" UNSYNC");
2959 		unsync(ptr, &len);
2960 	}
2961 	if (flags & 0x20)
2962 	{
2963 		print(" EXPERIMENTAL");
2964 	}
2965 	if (flags & 0x10)
2966 	{
2967 		print(" FOOTER");
2968 	}
2969 
2970 	ptr+=10;
2971 	len-=10;
2972 
2973 	indent++;
2974 
2975 	if (flags & 0x40)
2976 	{ /* extended header */
2977 		uint32_t _elength, elen;
2978 		uint8_t *eptr = ptr;
2979 		uint8_t eflags;
2980 
2981 		print(" EXTENDED HEADER");newline();
2982 
2983 		if ((eptr[0] & 0x80) ||
2984 		    (eptr[1] & 0x80) ||
2985 		    (eptr[2] & 0x80) ||
2986 		    (eptr[3] & 0x80))
2987 		{
2988 			stack_message(STACK_ERROR, 0, "Extended header length has a MSB set 0x%02x 0x%02x 0x%02x 0x%02x", eptr[0], eptr[1], eptr[2], eptr[3]);
2989 			flush();
2990 			indent--;
2991 			return;
2992 		}
2993 		_elength = (eptr[0] << 21) |
2994 		           (eptr[1] << 14) |
2995 		           (eptr[2] << 7) |
2996 		           (eptr[3]);
2997 		if (_elength < 6)
2998 		{
2999 			stack_message(STACK_ERROR, 0, "Extended header length too small: %"PRId32, _elength);
3000 			flush();
3001 			indent--;
3002 			return;
3003 		}
3004 		if (_elength >= len)
3005 		{
3006 			stack_message(STACK_ERROR, 0, "Extended header length too big: %"PRId32" > %"PRId32, _elength, len);
3007 			flush();
3008 			indent--;
3009 			return;
3010 		}
3011 		elen = _elength;
3012 		if (eptr[4] != 0x01)
3013 		{
3014 			stack_message(STACK_WARNING, 0, "Non-standard number of flag bytes: %"PRId32" != 0", eptr[4]);
3015 			flush();
3016 			goto skip_eheader_v240;
3017 		}
3018 		eflags = eptr[5];
3019 
3020 		eptr += 6;
3021 		elen -= 6;
3022 
3023 		if (eflags & 0x40)
3024 		{
3025 			if (elen < 1)
3026 			{
3027 				stack_message(STACK_WARNING, 0, "Extended header ran out of space");
3028 				flush();
3029 				goto skip_eheader_v240;
3030 			}
3031 			if (eptr[0] != 0x00)
3032 			{
3033 				stack_message(STACK_WARNING, 0, "\"update_flags\" should not have data");
3034 				flush();
3035 				goto skip_eheader_v240;
3036 			}
3037 			print("ID3 TAG IS AN UPDATE OF EARLIER DATA"); newline();
3038 		} else {
3039 			print("ID3 TAG IS A REPLACEMENT OF EARLIER DATA"); newline();
3040 		}
3041 
3042 		if (eflags & 0x20)
3043 		{
3044 			if (elen < 6)
3045 			{
3046 				stack_message(STACK_WARNING, 0, "Extended header ran out of space");
3047 				flush();
3048 				goto skip_eheader_v240;
3049 			}
3050 			if (eptr[0] != 0x05)
3051 			{
3052 				stack_message(STACK_WARNING, 0, "CRC should have 5 bytes of data: %d", eptr[0]);
3053 				flush();
3054 				goto skip_eheader_v240;
3055 			}
3056 			if ((eptr[1] & 0xf0) ||
3057 			    (eptr[2] & 0x80) ||
3058 			    (eptr[3] & 0x80) ||
3059 			    (eptr[4] & 0x80) ||
3060 			    (eptr[5] & 0x80))
3061 			{
3062 				stack_message(STACK_WARNING, 0, "CRC data stream not valid, MSB set: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", eptr[1], eptr[2], eptr[3], eptr[4], eptr[5]);
3063 				flush();
3064 				goto skip_eheader_v240;
3065 			}
3066 			uint32_t crc = (eptr[1] << 28) |
3067 			               (eptr[2] << 21) |
3068 			               (eptr[3] << 14) |
3069 			               (eptr[4] << 7) |
3070 			               (eptr[5]);
3071 			print("CRC = 0x%08" PRIx32, crc); newline();
3072 			eptr += 6;
3073 			elen -= 6;
3074 		}
3075 		if (eflags & 0x10)
3076 		{
3077 			if (elen < 2)
3078 			{
3079 				stack_message(STACK_WARNING, 0, "Extended header ran out of space");
3080 				flush();
3081 				goto skip_eheader_v240;
3082 			}
3083 			if (eptr[0] != 0x01)
3084 			{
3085 				stack_message(STACK_WARNING, 0, "\"Restrictions\" should have 1 bytes of data: %d", eptr[0]);
3086 				flush();
3087 				goto skip_eheader_v240;
3088 			}
3089 			print("RESTRICTIONS IN TAG"); newline();
3090 			switch (eptr[1] & 0xc0)
3091 			{
3092 				case 0x00: print("No more than 128 frames and 1 MB total tag size."); break;
3093 				case 0x40: print("No more than 64 frames and 128 KB total tag size."); break;
3094 				case 0x80: print("No more than 32 frames and 40 KB total tag size."); break;
3095 				case 0xc0: print("No more than 32 frames and 4 KB total tag size."); break;
3096 			}
3097 			newline();
3098 			switch (eptr[1] & 0x40)
3099 			{
3100 				case 0x00: print("Text encoding not restricted."); break;
3101 				case 0x40: print("Strings are only encoded with ISO-8859-1 [ISO-8859-1] or UTF-8 [UTF-8]."); break;
3102 			}
3103 			newline();
3104 			switch (eptr[1] & 0x0c)
3105 			{
3106 				case 0x00: print("Text lengths not restricted."); break;
3107 				case 0x04: print("No string is longer than 1024 characters."); break;
3108 				case 0x08: print("No string is longer than 128 characters."); break;
3109 				case 0x0c: print("No string is longer than 30 characters."); break;
3110 			}
3111 			newline();
3112 			switch (eptr[1] & 0x04)
3113 			{
3114 				case 0x00: print("Image encoding not restricted."); break;
3115 				case 0x04: print("Images are encoded only with PNG [PNG] or JPEG [JFIF]."); break;
3116 			}
3117 			newline();
3118 			switch (eptr[1] & 0x03)
3119 			{
3120 				case 0x00: print("Image resolution not restricted."); break;
3121 				case 0x01: print("All images are 256x256 pixels or smaller."); break;
3122 				case 0x02: print("All images are 64x64 pixels or smaller."); break;
3123 				case 0x03: print("All images are exactly 64x64 pixels, unless required otherwise."); break;
3124 			}
3125 			newline();
3126 
3127 			eptr += 2;
3128 			elen -= 2;
3129 		}
3130 		if (elen != 0)
3131 		{
3132 			stack_message(STACK_WARNING, 0, "Unused data in extended header: %" PRId32 "bytes left", elen);
3133 			flush();
3134 		}
3135 skip_eheader_v240:
3136 		ptr += _elength;
3137 		len -= _elength;
3138 	}
3139 
3140 	while (len > 10)
3141 	{
3142 		int32_t framelen;
3143 
3144 		if (ptr[0] == 0)
3145 		{
3146 			break;
3147 		}
3148 
3149 		indent++;
3150 		framelen = decode_id3v240_frame (ptr, len);
3151 		indent--;
3152 		if (framelen < 0)
3153 		{
3154 			indent--;
3155 			return;
3156 		}
3157 
3158 		ptr += framelen;
3159 		len -= framelen;
3160 	}
3161 
3162 	if (len)
3163 	{
3164 		if (flags & 0x10)
3165 		{
3166 			stack_message(STACK_WARNING, 0, "PADDING + FOOTER %d bytes", (int) len);
3167 		} else {
3168 			stack_message(STACK_INFO, 0, "%d bytes of PADDING to inspect", (int)len);
3169 		}
3170 	}
3171 	while (len)
3172 	{
3173 		if (ptr[0])
3174 		{
3175 			stack_message(STACK_WARNING, 0, "Non-zero data in padding: 0x%02x", ptr[0]);
3176 		}
3177 		ptr++;
3178 		len--;
3179 	}
3180 
3181 	{
3182 		uint8_t fdata[10];
3183 		if (read (fd, fdata, 10) != 10)
3184 		{
3185 			if (flags & 0x10)
3186 			{
3187 				stack_message(STACK_ERROR, 0, "Unable to read FOOTER"); flush();
3188 			}
3189 			indent--;
3190 			return;
3191 		}
3192 		if ((fdata[0] == '3') &&
3193 		    (fdata[1] == 'D') &&
3194 		    (fdata[2] == 'I'))
3195 		{
3196 			print("%08lx FOOTER v2.%d.%d 10 bytes", (long) lseek (fd, 0, SEEK_CUR)-10, fdata[3], fdata[4]); newline();
3197 			if (fdata[5] != data[5]) {stack_message(STACK_WARNING, 0, "Flags does not match the copy from the header"); flush(); }
3198 			if ((fdata[6] != data[6]) ||
3199 			    (fdata[7] != data[7]) ||
3200 			    (fdata[8] != data[8]) ||
3201 			    (fdata[9] != data[9])) {stack_message(STACK_WARNING, 0, "Size does not match the copy from the header"); flush(); }
3202 		}
3203 	}
3204 	indent--;
3205 }
3206 
decode_id3v230_frame(uint8_t * ptr,uint32_t len)3207 static int32_t decode_id3v230_frame(uint8_t *ptr, uint32_t len)
3208 {
3209 	uint8_t FrameId[4];
3210 	uint32_t inputsize;
3211 	uint8_t *frameptr, *zlibptr=0;
3212 	uint32_t framelen;
3213 	uint32_t zlib_new_framelen = 0xffffff;
3214 	uint16_t flags;
3215 
3216 	if (len < 11)
3217 	{
3218 		stack_message(STACK_ERROR, 0, "Minimum frame length is 11 bytes");
3219 		newline();
3220 		return -1;
3221 	}
3222 
3223 	FrameId[0] = ptr[0];
3224 	FrameId[1] = ptr[1];
3225 	FrameId[2] = ptr[2];
3226 	FrameId[3] = ptr[3];
3227 
3228 	if ((FrameId[0] < 0x20) || (FrameId[0] >= 0x80) ||
3229 	    (FrameId[1] < 0x20) || (FrameId[1] >= 0x80) ||
3230 	    (FrameId[2] < 0x20) || (FrameId[2] >= 0x80) ||
3231 	    (FrameId[3] < 0x20) || (FrameId[3] >= 0x80))
3232 	{
3233 		stack_message(STACK_ERROR, 0, "Invalid frame ID %02x %02x %02x %02x", FrameId[0], FrameId[1], FrameId[2], FrameId[3]);
3234 		newline();
3235 		return -1;
3236 	}
3237 
3238 	flags = (ptr[8]<<8)|(ptr[9]);
3239 
3240 	framelen = inputsize = (ptr[4]<<24)|(ptr[5]<<16)|(ptr[6]<<8)|ptr[7];
3241 
3242 	frameptr = ptr + 10;
3243 	len-=10;
3244 
3245 	print("Frame %c%c%c%c (%5"PRId32" bytes) - ", FrameId[0], FrameId[1], FrameId[2], FrameId[3], inputsize);
3246 	indent++;
3247 
3248 	if (inputsize > len)
3249 	{
3250 		stack_message(STACK_ERROR, 0, "We are missing %d of data in this frame", inputsize - len);
3251 		newline();
3252 		indent--;
3253 		return -1;
3254 	}
3255 
3256 	print("FLAGS=0x%04"PRIx16" ", flags);
3257 
3258 	/* part-1, parse header */
3259 #if 0
3260 	print("flags=0x%04", flags);
3261 #endif
3262 #if 0
3263 	/* these are very noisy to see */
3264 	if (flags & 0x8000) stack_message("Tag  alter preservation: Frame should be discarded."); else stack_message("Tag  alter preservation: Frame should be preserved.");
3265 	if (flags & 0x4000) stack_message("File alter preservation: Frame should be discarded."); else stack_message("File alter preservation: Frame should be preserved.");
3266 	if (flags & 0x2000) stack_message("Frame is Read only"); else stack_message(" Frame is Read/Write");
3267 #endif
3268 
3269 	if (flags & 0x0080)
3270 	{
3271 		if (framelen < 4)
3272 		{
3273 			stack_message(STACK_ERROR, 0, "Compression set, but no space for outputsize field");
3274 			newline();
3275 			goto ignoreframe;
3276 		}
3277 		zlib_new_framelen  = (frameptr[0]<<24)|(frameptr[1]<<16)|(frameptr[2]<<8)|frameptr[3];
3278 		if (zlib_new_framelen > 32*1024*1024)
3279 		{
3280 			stack_message(STACK_WARNING, 0, "Decompression bigger than 32MB, blocking it");
3281 			newline();
3282 			goto ignoreframe;
3283 		}
3284 		if (!zlib_new_framelen)
3285 		{
3286 			stack_message(STACK_WARNING, 0, "Decompression size of zero bytes");
3287 			newline();
3288 			goto ignoreframe;
3289 		}
3290 		frameptr+=4;
3291 		framelen-=4;
3292 	}
3293 	if (flags & 0x0040)
3294 	{
3295 		uint8_t method;
3296 		if (framelen < 1)
3297 		{
3298 			stack_message(STACK_WARNING, 0, "Encryption set, but not space for method field");
3299 		}
3300 		method = frameptr[0];
3301 		frameptr++;
3302 		framelen--;
3303 		stack_message(STACK_INFO, 0, "Frame is encrypted (method %d), ignoring it", method);
3304 		newline();
3305 		goto ignoreframe;
3306 	}
3307 	if (flags & 0x0020)
3308 	{
3309 		if (framelen < 1)
3310 		{
3311 			stack_message(STACK_WARNING, 0, "Grouping set, but no space for Frame grouping information");
3312 		}
3313 		stack_message(STACK_INFO, 0, "Frame is grouped with ID=%d", frameptr[0]);
3314 		frameptr++;
3315 		framelen--;
3316 	}
3317 	/* part-2 fix the data*/
3318 
3319 	if (framelen == 0)
3320 	{
3321 		stack_message(STACK_ERROR, 0, "Frame with zero-length");
3322 		indent--;
3323 		flush();
3324 		return -1;
3325 	}
3326 
3327 	if (flags & 0x0080)
3328 	{
3329 		int result;
3330 
3331 		z_stream strm;
3332 		zlibptr = malloc (zlib_new_framelen);
3333 
3334 		strm.zalloc = zalloc;
3335 		strm.zfree = zfree;
3336 		strm.opaque = (voidpf)0;
3337 		strm.avail_in = framelen;
3338 		strm.next_in = frameptr;
3339 		strm.avail_out = zlib_new_framelen;
3340 		strm.next_out = zlibptr;
3341 
3342 		stack_message(STACK_INFO, 0, "Frame is compressed (inputsize=%" PRId32 ", outputsize=%" PRId32 ")", framelen, zlib_new_framelen);
3343 
3344 		if (inflateInit(&strm))
3345 		{
3346 			stack_message(STACK_ERROR, 0, "Zlib failed to init");
3347 			newline();
3348 			goto ignoreframe;
3349 		}
3350 		result = inflate(&strm, Z_FINISH);
3351 		if (result == Z_STREAM_ERROR ||
3352 		    result == Z_NEED_DICT ||
3353 		    result == Z_DATA_ERROR ||
3354 		    result == Z_MEM_ERROR)
3355 		{
3356 			stack_message(STACK_ERROR, 0, "Zlib failed to decompress");
3357 			if (result != Z_STREAM_ERROR)
3358 			{
3359 				inflateEnd (&strm);
3360 			}
3361 			newline();
3362 			goto ignoreframe;
3363 		}
3364 		if (strm.avail_in != 0)
3365 		{
3366 			stack_message(STACK_WARNING, 0, "Zlib did not consume the entire input, %d bytes left", (int)strm.avail_in);
3367 		}
3368 		if (strm.avail_out != 0)
3369 		{
3370 			stack_message(STACK_WARNING, 0, "Zlib did not fill the entire output, %d bytes left", (int)strm.avail_out);
3371 			memset (strm.next_out, 0, strm.avail_out);
3372 		}
3373 		inflateEnd (&strm);
3374 		frameptr = zlibptr;
3375 		framelen = zlib_new_framelen;
3376 	}
3377 
3378 	indent++;
3379 
3380 	     if (!memcmp(FrameId, "AENC", 4)) decode_AENC(                                                                frameptr, framelen);
3381 	else if (!memcmp(FrameId, "APIC", 4)) decode_APIC(                                                                frameptr, framelen, 3);
3382 	else if (!memcmp(FrameId, "COMM", 4)) decode_COMM(                                                                frameptr, framelen, 3);
3383 	else if (!memcmp(FrameId, "COMR", 4)) decode_COMR(                                                                frameptr, framelen, 3);
3384 	else if (!memcmp(FrameId, "ENCR", 4)) decode_ENCR(                                                                frameptr, framelen);
3385 	else if (!memcmp(FrameId, "EQUA", 4)) decode_EQUA(                                                                frameptr, framelen);
3386 	else if (!memcmp(FrameId, "ETCO", 4)) decode_ETCO(                                                                frameptr, framelen, 3);
3387 	else if (!memcmp(FrameId, "GEOB", 4)) decode_GEOB(                                                                frameptr, framelen, 3);
3388 	else if (!memcmp(FrameId, "GRID", 4)) decode_GRID(                                                                frameptr, framelen);
3389 	else if (!memcmp(FrameId, "IPLS", 4)) decode_Tn  ("Involved people list",                                         frameptr, framelen, 3);
3390 	else if (!memcmp(FrameId, "LINK", 4)) decode_LINK(                                                                frameptr, framelen);
3391 	else if (!memcmp(FrameId, "MCDI", 4)) decode_MCDI(                                                                frameptr, framelen);
3392 	else if (!memcmp(FrameId, "MLLT", 4)) decode_MLLT(                                                                frameptr, framelen);
3393 	else if (!memcmp(FrameId, "OWNE", 4)) decode_OWNE(                                                                frameptr, framelen, 3);
3394 	else if (!memcmp(FrameId, "PRIV", 4)) decode_PRIV(                                                                frameptr, framelen);
3395 	else if (!memcmp(FrameId, "PCNT", 4)) decode_PCNT(                                                                frameptr, framelen);
3396 	else if (!memcmp(FrameId, "POPM", 4)) decode_POPM(                                                                frameptr, framelen);
3397 	else if (!memcmp(FrameId, "POSS", 4)) decode_POSS(                                                                frameptr, framelen);
3398 	else if (!memcmp(FrameId, "RBUF", 4)) decode_RBUF(                                                                frameptr, framelen);
3399 	else if (!memcmp(FrameId, "RVAD", 4)) decode_RVAD(                                                                frameptr, framelen, 3);
3400 	else if (!memcmp(FrameId, "RVRB", 4)) decode_RVRB(                                                                frameptr, framelen);
3401 	else if (!memcmp(FrameId, "SYLT", 4)) decode_SYLT(                                                                frameptr, framelen, 3);
3402 	else if (!memcmp(FrameId, "SYTC", 3)) decode_SYTC(                                                                frameptr, framelen);
3403 	else if (!memcmp(FrameId, "TALB", 4)) decode_T   ("Album/Movie/Show title",                                       frameptr, framelen, 3);
3404 	else if (!memcmp(FrameId, "TBPM", 4)) decode_T   ("BPM",                                                          frameptr, framelen, 3);
3405 	else if (!memcmp(FrameId, "TCOM", 4)) decode_T   ("Composer(s)",                                                  frameptr, framelen, 3);
3406 	else if (!memcmp(FrameId, "TCON", 4)) decode_T   ("Content (ID3v1 (n)String encoded)",                            frameptr, framelen, 3);
3407 	else if (!memcmp(FrameId, "TCOP", 4)) decode_T   ("Copyright message",                                            frameptr, framelen, 3);
3408 	else if (!memcmp(FrameId, "TDAT", 4)) decode_T   ("Date (DDMM encoded)",                                          frameptr, framelen, 3);
3409 	else if (!memcmp(FrameId, "TDLY", 4)) decode_T   ("Playlist delay",                                               frameptr, framelen, 3);
3410 	else if (!memcmp(FrameId, "TENC", 4)) decode_T   ("Encoded by",                                                   frameptr, framelen, 3);
3411 	else if (!memcmp(FrameId, "TEXT", 4)) decode_T   ("Lyricist(s)/text writer(s)",                                   frameptr, framelen, 3);
3412 	else if (!memcmp(FrameId, "TFLT", 4)) decode_T   ("File type",                                                    frameptr, framelen, 3);
3413 	else if (!memcmp(FrameId, "TIME", 4)) decode_T   ("Time (HHMM encoded)",                                          frameptr, framelen, 2);
3414 	else if (!memcmp(FrameId, "TIT1", 4)) decode_T   ("Content group description",                                    frameptr, framelen, 3);
3415 	else if (!memcmp(FrameId, "TIT2", 4)) decode_T   ("Title/Songname/Content description",                           frameptr, framelen, 3);
3416 	else if (!memcmp(FrameId, "TIT3", 4)) decode_T   ("Subtitle/Description refinement",                              frameptr, framelen, 3);
3417 	else if (!memcmp(FrameId, "TKEY", 4)) decode_T   ("Initial key",                                                  frameptr, framelen, 3);
3418 	else if (!memcmp(FrameId, "TLAN", 4)) decode_T   ("Language(s) (ISO-639-2)",                                      frameptr, framelen, 3);
3419 	else if (!memcmp(FrameId, "TLEN", 4)) decode_T   ("Length (in milliseconds)",                                     frameptr, framelen, 3);
3420 	else if (!memcmp(FrameId, "TMED", 4)) decode_T   ("Media type",                                                   frameptr, framelen, 3);
3421 	else if (!memcmp(FrameId, "TOAL", 4)) decode_T   ("Original album/Movie/Show title",                              frameptr, framelen, 3);
3422 	else if (!memcmp(FrameId, "TOFN", 4)) decode_T   ("Original filename",                                            frameptr, framelen, 3);
3423 	else if (!memcmp(FrameId, "TOLY", 4)) decode_T   ("Original Lyricist(s)/text writer(s)",                          frameptr, framelen, 3);
3424 	else if (!memcmp(FrameId, "TOPE", 4)) decode_T   ("Original artist(s)/performer(s)",                              frameptr, framelen, 3);
3425 	else if (!memcmp(FrameId, "TORY", 4)) decode_T   ("Original release year",                                        frameptr, framelen, 3);
3426 	else if (!memcmp(FrameId, "TOWN", 4)) decode_T   ("File Owner/License",/*New*/                                    frameptr, framelen, 3);
3427 	else if (!memcmp(FrameId, "TPE1", 4)) decode_T   ("Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group", frameptr, framelen, 3);
3428 	else if (!memcmp(FrameId, "TPE2", 4)) decode_T   ("Band/Orchestra/Accompaniment",                                 frameptr, framelen, 3);
3429 	else if (!memcmp(FrameId, "TPE3", 4)) decode_T   ("Conductor",                                                    frameptr, framelen, 3);
3430 	else if (!memcmp(FrameId, "TPE4", 4)) decode_T   ("Interpreted, remixed, or otherwise modified by",               frameptr, framelen, 3);
3431 	else if (!memcmp(FrameId, "TPOS", 4)) decode_T   ("Part of a set",                                                frameptr, framelen, 3);
3432 	else if (!memcmp(FrameId, "TPUB", 4)) decode_T   ("Publisher",                                                    frameptr, framelen, 3);
3433 	else if (!memcmp(FrameId, "TRCK", 4)) decode_T   ("Track number/Position in set (#/total encoded)",               frameptr, framelen, 3);
3434 	else if (!memcmp(FrameId, "TRDA", 4)) decode_T   ("Recording dates",                                              frameptr, framelen, 3);
3435 	else if (!memcmp(FrameId, "TRSN", 4)) decode_T   ("Internet radio station name",/*New*/                           frameptr, framelen, 3);
3436 	else if (!memcmp(FrameId, "TRSO", 4)) decode_T   ("Internet radio station Owner",/*New*/                          frameptr, framelen, 3);
3437 	else if (!memcmp(FrameId, "TSIZ", 4)) decode_T   ("Size (file in bytes)",                                         frameptr, framelen, 3);
3438 	else if (!memcmp(FrameId, "TSRC", 4)) decode_T   ("International Standard Recording Code (ISO 3901:1986)",        frameptr, framelen, 3);
3439 	else if (!memcmp(FrameId, "TSSE", 4)) decode_T   ("Software/hardware and settings used for encoding",             frameptr, framelen, 3);
3440 	else if (!memcmp(FrameId, "TYER", 4)) decode_T   ("Year (YYYY encoded)",                                          frameptr, framelen, 3);
3441 	else if (!memcmp(FrameId, "TXXX", 4)) decode_TXXX(                                                                frameptr, framelen, 3);
3442 	else if (!memcmp(FrameId, "UFID", 4)) decode_UFID(                                                                frameptr, framelen);
3443 	else if (!memcmp(FrameId, "USER", 4)) decode_USER(                                                                frameptr, framelen, 3);
3444 	else if (!memcmp(FrameId, "USLT", 3)) decode_USLT(                                                                frameptr, framelen, 3);
3445 	else if (!memcmp(FrameId, "WCOM", 4)) decode_W   ("Commercial information",                                       frameptr, framelen);
3446 	else if (!memcmp(FrameId, "WCOP", 4)) decode_W   ("Copyright/Legal information",                                  frameptr, framelen);
3447 	else if (!memcmp(FrameId, "WOAF", 4)) decode_W   ("Official audio file webpage",                                  frameptr, framelen);
3448 	else if (!memcmp(FrameId, "WOAR", 4)) decode_W   ("Official artist/performer webpage",                            frameptr, framelen);
3449 	else if (!memcmp(FrameId, "WOAS", 4)) decode_W   ("Official audio source webpage",                                frameptr, framelen);
3450 	else if (!memcmp(FrameId, "WORS", 4)) decode_W   ("Official internet radio station homepage",/*New*/              frameptr, framelen);
3451 	else if (!memcmp(FrameId, "WPAY", 4)) decode_W   ("Payment",/*New*/                                               frameptr, framelen);
3452 	else if (!memcmp(FrameId, "WPUB", 4)) decode_W   ("Publishers official webpage",                                  frameptr, framelen);
3453 	else if (!memcmp(FrameId, "WXXX", 4)) decode_WXXX(                                                                frameptr, framelen,3);
3454 	else if ((FrameId[0]=='T')&&
3455 		(((FrameId[1]>='0')&&(FrameId[1]<='9'))||((FrameId[1]>='a')&&(FrameId[1]<='z'))||((FrameId[1]>='A')&&(FrameId[1]<='Z')))&&
3456 		(((FrameId[2]>='0')&&(FrameId[2]<='9'))||((FrameId[2]>='a')&&(FrameId[2]<='z'))||((FrameId[2]>='A')&&(FrameId[2]<='Z')))&&
3457 		(((FrameId[3]>='0')&&(FrameId[3]<='9'))||((FrameId[3]>='a')&&(FrameId[3]<='z'))||((FrameId[3]>='A')&&(FrameId[3]<='Z'))))
3458 	{
3459 		decode_T("Unknown Text", frameptr, framelen, 3);
3460 	}
3461 	else if ((FrameId[0]=='W')&&
3462 		(((FrameId[1]>='0')&&(FrameId[1]<='9'))||((FrameId[1]>='a')&&(FrameId[1]<='z'))||((FrameId[1]>='A')&&(FrameId[1]<='Z')))&&
3463 		(((FrameId[2]>='0')&&(FrameId[2]<='9'))||((FrameId[2]>='a')&&(FrameId[2]<='z'))||((FrameId[2]>='A')&&(FrameId[2]<='Z')))&&
3464 		(((FrameId[3]>='0')&&(FrameId[3]<='9'))||((FrameId[3]>='a')&&(FrameId[3]<='z'))||((FrameId[3]>='A')&&(FrameId[3]<='Z'))))
3465 	{
3466 		decode_W("Unknown URL", frameptr, framelen);
3467 	} else {
3468 		print("Unknown frame"); newline();
3469 	}
3470 	flush();
3471 	indent--;
3472 ignoreframe:
3473 	indent--;
3474 	if (zlibptr)
3475 	{
3476 		free (zlibptr);
3477 		zlibptr = 0;
3478 	}
3479 	ptr += inputsize;
3480 	len -= inputsize;
3481 
3482 	return (int32_t)(inputsize + 10);
3483 }
3484 
decode_id3v230(uint8_t * data,uint32_t _length)3485 static void decode_id3v230(uint8_t *data, uint32_t _length)
3486 {
3487 	uint8_t *ptr;
3488 	uint32_t len;
3489 	uint8_t flags = data[5];
3490 	uint32_t v3_paddinglength=0;
3491 
3492 	ptr = data;
3493 	len = _length;
3494 
3495 	if (flags & 0x80)
3496 	{
3497 		print(" UNSYNC");
3498 		unsync(ptr, &len);
3499 	}
3500 	if (flags & 0x20)
3501 	{
3502 		print(" EXPERIMENTAL");
3503 	}
3504 	if (flags & 0x1f)
3505 	{
3506 		print(" UNKNOWN_FLAGS(This will probably fail to parse)");
3507 	}
3508 	newline();
3509 
3510 	ptr+=10;
3511 	len-=10;
3512 
3513 	indent++;
3514 	if (flags & 0x40)
3515 	{
3516 		uint32_t _elength;
3517 		uint8_t *eptr = ptr;
3518 
3519 		print(" EXTENDED HEADER");newline();
3520 
3521 		_elength = (eptr[0] << 24) |
3522 		           (eptr[1] << 16) |
3523 		           (eptr[2] << 8) |
3524 		           (eptr[3]);
3525 
3526 		if ((_elength != 6) && (_elength != 10))
3527 		{
3528 			stack_message(STACK_ERROR, 0, "Extended header length should be 6 or 10");
3529 			indent--;
3530 			return;
3531 		}
3532 
3533 		if ((_elength + 4) > len)
3534 		{
3535 			stack_message(STACK_ERROR, 0, "Extended header length too big");
3536 			indent--;
3537 			return;
3538 		}
3539 		if (eptr[4] == 0x00)
3540 		{
3541 			if (_elength != 6)
3542 			{
3543 				stack_message(STACK_WARNING, 0, "CRC disabled and length = 6");
3544 				goto skip_eheader_v230;
3545 			}
3546 			v3_paddinglength = (eptr[6] << 24) |
3547 			                   (eptr[7] << 16) |
3548 			                   (eptr[8] << 8) |
3549 			                    eptr[9] ;
3550 			len -= v3_paddinglength;
3551 			print("PADDING=%" PRId32 " BYTES", v3_paddinglength);
3552 		} else if (eptr[4] == 0x80)
3553 		{
3554 			uint32_t crc;
3555 			if (_elength != 10)
3556 			{
3557 				stack_message(STACK_WARNING, 0, "CRC enabled and length != 10");
3558 				goto skip_eheader_v230;
3559 			}
3560 			v3_paddinglength = (eptr[6] << 24) |
3561 			                   (eptr[7] << 16) |
3562 			                   (eptr[8] << 8) |
3563 			                   (eptr[9]);
3564 			crc = (eptr[10]<<24) |
3565 			      (eptr[11]<<16) |
3566 			      (eptr[12]<<8) |
3567 			       eptr[13];
3568 
3569 			print("CRC=0x%08"PRIx32, crc);
3570 		} else {
3571 			stack_message(STACK_WARNING, 0, "FLAGS[0] is out of range");
3572 			goto skip_eheader_v230;
3573 		}
3574 		if (eptr[5] != 0x00)
3575 		{
3576 			stack_message(STACK_WARNING, 0, "FLAGS[0] is out of range");
3577 			goto skip_eheader_v230;
3578 		}
3579 skip_eheader_v230:
3580 		ptr += _elength+4;
3581 		len -= _elength+4;
3582 	}
3583 
3584 	while (len > 10)
3585 	{
3586 		int32_t framelen;
3587 
3588 		if (ptr[0] == 0)
3589 		{
3590 			stack_message(STACK_WARNING, 0, "Hit zero data, should have been marked as padding");
3591 			break;
3592 		}
3593 
3594 		indent++;
3595 		framelen = decode_id3v230_frame (ptr, len);
3596 		indent--;
3597 		if (framelen < 0)
3598 		{
3599 			indent--;
3600 			return;
3601 		}
3602 
3603 		ptr += framelen;
3604 		len -= framelen;
3605 	}
3606 
3607 	len += v3_paddinglength;
3608 	if (len)
3609 	{
3610 		stack_message(STACK_INFO, 0, "%d bytes of PADDING to inspect", (int)len);
3611 	}
3612 	while (len)
3613 	{
3614 		if (ptr[0])
3615 		{
3616 			stack_message(STACK_WARNING, 0, "Non-zero data in padding: 0x%02x", ptr[0]);
3617 		}
3618 		ptr++;
3619 		len--;
3620 	}
3621 }
3622 
decode_id3v220_frame(uint8_t * ptr,uint32_t len)3623 static int32_t decode_id3v220_frame(uint8_t *ptr, uint32_t len)
3624 {
3625 	uint8_t FrameId[3];
3626 	uint32_t framelen;
3627 
3628 	if (len < 7)
3629 	{
3630 		print("*-*-* ERROR, Minimum frame length is 7 bytes"); newline();
3631 		return -1;
3632 	}
3633 
3634 	FrameId[0] = ptr[0];
3635 	FrameId[1] = ptr[1];
3636 	FrameId[2] = ptr[2];
3637 
3638 	if ((FrameId[0] < 0x20) || (FrameId[0] >= 0x80) ||
3639 	    (FrameId[1] < 0x20) || (FrameId[1] >= 0x80) ||
3640 	    (FrameId[2] < 0x20) || (FrameId[2] >= 0x80))
3641 	{
3642 		stack_message(STACK_ERROR, 0, "Invalid frame ID %02x %02x %02x", FrameId[0], FrameId[1], FrameId[2]);
3643 		newline();
3644 		return -1;
3645 	}
3646 
3647 	framelen = (ptr[3]<<16) | (ptr[4]<<8) | ptr[5];
3648 
3649 	if (framelen == 0)
3650 	{
3651 		stack_message(STACK_ERROR, 1, "Frame with zero-length");
3652 		newline();
3653 		return -1;
3654 	}
3655 
3656 	ptr += 6;
3657 	len -= 6;
3658 
3659 	print("Frame %c%c%c (%5"PRId32" bytes) - ", FrameId[0], FrameId[1], FrameId[2], framelen);
3660 	indent++;
3661 
3662 	if (framelen > len)
3663 	{
3664 		stack_message(STACK_ERROR, 0, "We are missing %d of data in this frame", framelen - len);
3665 		newline();
3666 		indent--;
3667 		return -1;
3668 	}
3669 	indent++;
3670 
3671 	     if (!memcmp(FrameId, "UFI", 3)) decode_UFID(                                                                ptr, framelen);
3672 	else if (!memcmp(FrameId, "TT1", 3)) decode_T   ("Content group description",                                    ptr, framelen, 2);
3673 	else if (!memcmp(FrameId, "TT2", 3)) decode_T   ("Title/Songname/Content description",                           ptr, framelen, 2);
3674 	else if (!memcmp(FrameId, "TT3", 3)) decode_T   ("Subtitle/Description refinement",                              ptr, framelen, 2);
3675 	else if (!memcmp(FrameId, "TP1", 3)) decode_T   ("Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group", ptr, framelen, 2);
3676 	else if (!memcmp(FrameId, "TP2", 3)) decode_T   ("Band/Orchestra/Accompaniment",                                 ptr, framelen, 2);
3677 	else if (!memcmp(FrameId, "TP3", 3)) decode_T   ("Conductor",                                                    ptr, framelen, 2);
3678 	else if (!memcmp(FrameId, "TP4", 3)) decode_T   ("Interpreted, remixed, or otherwise modified by",               ptr, framelen, 2);
3679 	else if (!memcmp(FrameId, "TCM", 3)) decode_T   ("Composer(s)",                                                  ptr, framelen, 2);
3680 	else if (!memcmp(FrameId, "TXT", 3)) decode_T   ("Lyricist(s)/text writer(s)",                                   ptr, framelen, 2);
3681 	else if (!memcmp(FrameId, "TLA", 3)) decode_T   ("Language(s) (ISO-639-2)",                                      ptr, framelen, 2);
3682 	else if (!memcmp(FrameId, "TCO", 3)) decode_T   ("Content (ID3v1 (n)String encoded)",                            ptr, framelen, 2);
3683 	else if (!memcmp(FrameId, "TAL", 3)) decode_T   ("Album/Movie/Show title",                                       ptr, framelen, 2);
3684 	else if (!memcmp(FrameId, "TPA", 3)) decode_T   ("Part of a set",                                                ptr, framelen, 2);
3685 	else if (!memcmp(FrameId, "TRK", 3)) decode_T   ("Track number/Position in set (#/total encoded)",               ptr, framelen, 2);
3686 	else if (!memcmp(FrameId, "TRC", 3)) decode_T   ("International Standard Recording Code (ISO 3901:1986)",        ptr, framelen, 2);
3687 	else if (!memcmp(FrameId, "TYE", 3)) decode_T   ("Year (YYYY encoded)",                                          ptr, framelen, 2);
3688 	else if (!memcmp(FrameId, "TDA", 3)) decode_T   ("Date (DDMM encoded)",                                          ptr, framelen, 2);
3689 	else if (!memcmp(FrameId, "TIM", 3)) decode_T   ("Time (HHMM encoded)",                                          ptr, framelen, 2);
3690 	else if (!memcmp(FrameId, "TRD", 3)) decode_T   ("Recording dates",                                              ptr, framelen, 2);
3691 	else if (!memcmp(FrameId, "TMT", 3)) decode_T   ("Media type",                                                   ptr, framelen, 2);
3692 	else if (!memcmp(FrameId, "TFT", 3)) decode_T   ("File type",                                                    ptr, framelen, 2);
3693 	else if (!memcmp(FrameId, "TBP", 3)) decode_T   ("BPM",                                                          ptr, framelen, 2);
3694 	else if (!memcmp(FrameId, "TCR", 3)) decode_T   ("Copyright message",                                            ptr, framelen, 2);
3695 	else if (!memcmp(FrameId, "TPB", 3)) decode_T   ("Publisher",                                                    ptr, framelen, 2);
3696 	else if (!memcmp(FrameId, "TEN", 3)) decode_T   ("Encoded by",                                                   ptr, framelen, 2);
3697 	else if (!memcmp(FrameId, "TSS", 3)) decode_T   ("Software/hardware and settings used for encoding",             ptr, framelen, 2);
3698 	else if (!memcmp(FrameId, "TOF", 3)) decode_T   ("Original filename",                                            ptr, framelen, 2);
3699 	else if (!memcmp(FrameId, "TLE", 3)) decode_T   ("Length (in milliseconds)",                                     ptr, framelen, 2);
3700 	else if (!memcmp(FrameId, "TSI", 3)) decode_T   ("Size (file in bytes)",                                         ptr, framelen, 2);
3701 	else if (!memcmp(FrameId, "TDY", 3)) decode_T   ("Playlist delay",                                               ptr, framelen, 2);
3702 	else if (!memcmp(FrameId, "TKE", 3)) decode_T   ("Initial key",                                                  ptr, framelen, 2);
3703 	else if (!memcmp(FrameId, "TOT", 3)) decode_T   ("Original album/Movie/Show title",                              ptr, framelen, 2);
3704 	else if (!memcmp(FrameId, "TOA", 3)) decode_T   ("Original artist(s)/performer(s)",                              ptr, framelen, 2);
3705 	else if (!memcmp(FrameId, "TOL", 3)) decode_T   ("Original Lyricist(s)/text writer(s)",                          ptr, framelen, 2);
3706 	else if (!memcmp(FrameId, "TOR", 3)) decode_T   ("Original release year",                                        ptr, framelen, 2);
3707 	else if (!memcmp(FrameId, "TXX", 3)) decode_TXXX(                                                                ptr, framelen, 2);
3708 	else if (!memcmp(FrameId, "WAF", 3)) decode_W   ("Official audio file webpage",                                  ptr, framelen);
3709 	else if (!memcmp(FrameId, "WAR", 3)) decode_W   ("Official artist/performer webpage",                            ptr, framelen);
3710 	else if (!memcmp(FrameId, "WAS", 3)) decode_W   ("Official audio source webpage",                                ptr, framelen);
3711 	else if (!memcmp(FrameId, "WCM", 3)) decode_W   ("Commercial information",                                       ptr, framelen);
3712 	else if (!memcmp(FrameId, "WCP", 3)) decode_W   ("Copyright/Legal information",                                  ptr, framelen);
3713 	else if (!memcmp(FrameId, "WPB", 3)) decode_W   ("Publishers official webpage",                                  ptr, framelen);
3714 	else if (!memcmp(FrameId, "WXX", 3)) decode_WXXX(                                                                ptr, framelen, 2);
3715 	else if (!memcmp(FrameId, "IPL", 3)) decode_Tn  ("Involved people list",                                         ptr, framelen, 2);
3716 	else if (!memcmp(FrameId, "MCI", 3)) decode_MCDI(                                                                ptr, framelen);
3717 	else if (!memcmp(FrameId, "ETC", 3)) decode_ETCO(                                                                ptr, framelen, 2);
3718 	else if (!memcmp(FrameId, "MLL", 3)) decode_MLLT(                                                                ptr, framelen);
3719 	else if (!memcmp(FrameId, "STC", 3)) decode_SYTC(                                                                ptr, framelen);
3720 	else if (!memcmp(FrameId, "ULT", 3)) decode_USLT(                                                                ptr, framelen, 2);
3721 	else if (!memcmp(FrameId, "SLT", 3)) decode_SYLT(                                                                ptr, framelen, 2);
3722 	else if (!memcmp(FrameId, "COM", 3)) decode_COMM(                                                                ptr, framelen, 2);
3723 	else if (!memcmp(FrameId, "RVA", 3)) decode_RVAD(                                                                ptr, framelen, 2);
3724 	else if (!memcmp(FrameId, "EQU", 3)) decode_EQUA(                                                                ptr, framelen);
3725 	else if (!memcmp(FrameId, "REV", 3)) decode_RVRB(                                                                ptr, framelen);
3726 	else if (!memcmp(FrameId, "PIC", 3)) decode_APIC(                                                                ptr, framelen, 2);
3727 	else if (!memcmp(FrameId, "GEO", 3)) decode_GEOB(                                                                ptr, framelen, 2);
3728 	else if (!memcmp(FrameId, "CNT", 3)) decode_PCNT(                                                                ptr, framelen);
3729 	else if (!memcmp(FrameId, "POP", 3)) decode_POPM(                                                                ptr, framelen);
3730 	else if (!memcmp(FrameId, "BUF", 3)) decode_RBUF(                                                                ptr, framelen);
3731 	else if (!memcmp(FrameId, "CRM", 3)) decode_CRM (                                                                ptr, framelen); /* ID3v2.3.0 changed layout */
3732 	else if (!memcmp(FrameId, "CRA", 3)) decode_AENC(                                                                ptr, framelen);
3733 	else if (!memcmp(FrameId, "LNK", 3)) decode_LINK(                                                                ptr, framelen);
3734 	else if ((ptr[0]=='T')&&
3735 		(((ptr[1]>='0')&&(ptr[1]<='9'))||((ptr[1]>='a')&&(ptr[1]<='z'))||((ptr[1]>='A')&&(ptr[1]<='Z')))&&
3736 		(((ptr[2]>='0')&&(ptr[2]<='9'))||((ptr[2]>='a')&&(ptr[2]<='z'))||((ptr[2]>='A')&&(ptr[1]<='Z'))) )
3737 	{
3738 		decode_T("Unknown Text", ptr+6, framelen, 2);
3739 	}
3740 	else if ((ptr[0]=='W')&&
3741 		(((ptr[1]>='0')&&(ptr[1]<='9'))||((ptr[1]>='a')&&(ptr[1]<='z'))||((ptr[1]>='A')&&(ptr[1]<='Z')))&&
3742 		(((ptr[2]>='0')&&(ptr[2]<='9'))||((ptr[2]>='a')&&(ptr[2]<='z'))||((ptr[2]>='A')&&(ptr[1]<='Z'))))
3743 	{
3744 		decode_W("Unknown URL", ptr+6, framelen);
3745 	} else {
3746 		print("Unknown frame"); newline();
3747 	}
3748 	flush();
3749 	indent-=2;
3750 
3751 	return 6 + framelen;
3752 }
3753 
decode_id3v220(uint8_t * data,uint32_t _length)3754 static void decode_id3v220(uint8_t *data, uint32_t _length)
3755 {
3756 	uint8_t *ptr;
3757 	uint32_t len;
3758 	uint8_t flags = data[5];
3759 
3760 	ptr = data;
3761 	len = _length;
3762 
3763 	if (flags & 0x80)
3764 	{
3765 		print(" UNSYNC");
3766 		unsync(ptr, &len);
3767 	}
3768 	if (flags & 0x40)
3769 	{
3770 		print(" COMPRESSION?(This is not defined yet)");
3771 	}
3772 	if (flags & 0x3f)
3773 	{
3774 		print(" UNKNOWN_FLAGS(This will probably fail to parse)");
3775 	}
3776 	newline();
3777 
3778 	ptr+=10;
3779 	len-=10;
3780 
3781 	while (len > 6)
3782 	{
3783 		int32_t framelen;
3784 
3785 		if (ptr[0] == 0)
3786 		{
3787 			break;
3788 		}
3789 
3790 		indent++;
3791 		framelen = decode_id3v220_frame (ptr, len);
3792 		indent--;
3793 		if (framelen < 0)
3794 		{
3795 			indent--;
3796 			return;
3797 		}
3798 
3799 		ptr += framelen;
3800 		len -= framelen;
3801 	}
3802 
3803 	if (len)
3804 	{
3805 		stack_message(STACK_INFO, 0, "(%d bytes of PADDING to inspect)", (int)len);
3806 	}
3807 	while (len)
3808 	{
3809 		if (ptr[0])
3810 		{
3811 			stack_message(STACK_WARNING,0, "Non-zero data in padding: 0x%02x", ptr[0]);
3812 		}
3813 		ptr++;
3814 		len--;
3815 	}
3816 }
3817 
decode_id3v2x(int fd,uint8_t data[10],off_t offset)3818 static off_t decode_id3v2x(int fd, uint8_t data[10], off_t offset)
3819 {
3820 	unsigned char *ndata;
3821 	uint32_t   length;
3822 	uint32_t  hlength = 10;
3823 	off_t p;
3824 
3825 	if (!(((data[3] == 2) && (data[4]==0)) ||
3826 	      ((data[3] == 3) && (data[4]==0)) ||
3827 	      ((data[3] == 4) && (data[4]==0)) ) )
3828 	{ /* False positive or unknown version */
3829 		return 0;
3830 	}
3831 
3832 	if (data[5] & 0x0f)
3833 	{
3834 		/* The lower nibble will never be set - also why FLAGS byte is never unsyncronized */
3835 		return 0;
3836 	}
3837 
3838 	if ((data[6] & 0x80) ||
3839 	    (data[7] & 0x80) ||
3840 	    (data[8] & 0x80) ||
3841 	    (data[9] & 0x80))
3842 	{
3843 		/* size is stored as 'syncsafe integer'. MSB will never be set */
3844 		return 0;
3845 	}
3846 
3847 	length = (((unsigned char *)data)[6]<<21) |
3848 	         (((unsigned char *)data)[7]<<14) |
3849 	         (((unsigned char *)data)[8]<<7) |
3850 	         (((unsigned char *)data)[9]);
3851 
3852 	if (length < (10 + ((data[5] & 0x40)?6:0)))
3853 	{
3854 		/* must fit atleast the header */
3855 		return 0;
3856 	}
3857 
3858 	print("0x%08lx ID3v2.%d.%d %ld bytes", (long) offset, ((unsigned char *)data)[3], ((unsigned char *)data)[4], (long)length);
3859 
3860 	ndata = malloc (length + hlength);
3861 	p = lseek(fd, 0, SEEK_CUR);
3862 	lseek(fd, offset, SEEK_SET);
3863 	{
3864 		int result = read (fd, ndata, (length+hlength));
3865 		if (result != (length + hlength))
3866 		{
3867 			stack_message(STACK_WARNING, 0, "Unable to read entire tag from disk");
3868 			if (result < 0) result = 0;
3869 			memset (ndata + result, 0, (length+hlength)-result);
3870 		}
3871 
3872 		/* Different versions have different rules for extended header, and sync-safe integers */
3873 		if (data[3] == 2)
3874 		{
3875 			indent++;
3876 			decode_id3v220(ndata, length+hlength);
3877 			indent--;
3878 		} else if(data[3] == 3)
3879 		{
3880 			indent++;
3881 			decode_id3v230(ndata, length+hlength);
3882 			indent--;
3883 		} else if (data[3] == 4)
3884 		{
3885 			indent++;
3886 			decode_id3v240(ndata, length+hlength, fd); /* FD, to probe for footer */
3887 			indent--;
3888 		}
3889 		flush();
3890 	}
3891 
3892 	free (ndata);
3893 	lseek (fd, p, SEEK_SET);
3894 	return length + hlength;
3895 }
3896 
decode_id3v12(uint8_t data[128],off_t offset)3897 static void decode_id3v12(uint8_t data[128], off_t offset)
3898 {
3899 	uint8_t  *d;
3900 	uint32_t l;
3901 
3902 	print("%08lx ID3v1.2 (extends more text onto ID3v1.0/ID3v1.1 128 bytes", (long) offset); newline();
3903 	indent++;
3904 	print("..SongName: "); d=data+  3; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
3905 	print("..Artist:   "); d=data+ 33; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
3906 	print("..Album:    "); d=data+ 63; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
3907 	print("..Comment:  "); d=data+ 93; l=15; decode_print_iso8859_1(&d, &l, 0); newline();
3908 	print("SubGenre:   "); d=data+108; l=20; decode_print_iso8859_1(&d, &l, 0); newline();
3909 	indent--;
3910 }
3911 
decode_id3v1x(uint8_t data[128],off_t offset)3912 static void decode_id3v1x(uint8_t data[128], off_t offset)
3913 {
3914 	uint8_t  *d;
3915 	uint32_t l;
3916 	const char *genre[] =
3917 	{
3918 		"Blues",
3919 		"Classic Rock",
3920 		"Country",
3921 		"Dance",
3922 		"Disco",
3923 		"Funk",
3924 		"Grunge",
3925 		"Hip-Hop",
3926 		"Jazz",
3927 		"Metal",
3928 		"New Age",
3929 		"Oldies",
3930 		"Other",
3931 		"Pop",
3932 		"R&B",
3933 		"Rap",
3934 		"Reggae",
3935 		"Rock",
3936 		"Techno",
3937 		"Industrial",
3938 		"Alternative",
3939 		"Ska",
3940 		"Death Metal",
3941 		"Pranks",
3942 		"Soundtrack",
3943 		"Euro-Techno",
3944 		"Ambient",
3945 		"Trip-Hop",
3946 		"Vocal",
3947 		"Jazz+Funk",
3948 		"Fusion",
3949 		"Trance",
3950 		"Classical",
3951 		"Instrumental",
3952 		"Acid",
3953 		"House",
3954 		"Game",
3955 		"Sound Clip",
3956 		"Gospel",
3957 		"Noise",
3958 		"AlternRock",
3959 		"Bass",
3960 		"Soul",
3961 		"Punk",
3962 		"Space",
3963 		"Meditative",
3964 		"Instrumental Pop",
3965 		"Instrumental Rock",
3966 		"Ethnic",
3967 		"Gothic",
3968 		"Darkwave",
3969 		"Techno-Industrial",
3970 		"Electronic",
3971 		"Pop-Folk",
3972 		"Eurodance",
3973 		"Dream",
3974 		"Southern Rock",
3975 		"Comedy",
3976 		"Cult",
3977 		"Gangsta",
3978 		"Top 40",
3979 		"Christian Rap",
3980 		"Pop/Funk",
3981 		"Jungle",
3982 		"Native American",
3983 		"Cabaret",
3984 		"New Wave",
3985 		"Psychadelic",
3986 		"Rave",
3987 		"Showtunes",
3988 		"Trailer",
3989 		"Lo-Fi",
3990 		"Tribal",
3991 		"Acid Punk",
3992 		"Acid Jazz",
3993 		"Polka",
3994 		"Retro",
3995 		"Musical",
3996 		"Rock & Roll",
3997 		"Hard Rock",
3998 		"Folk (Winamp extension)",
3999 		"Folk-Rock (Winamp extension)",
4000 		"National Folk (Winamp extension)",
4001 		"Swing (Winamp extension)",
4002 		"Fast Fusion (Winamp extension)",
4003 		"Bebob (Winamp extension)",
4004 		"Latin (Winamp extension)",
4005 		"Revival (Winamp extension)",
4006 		"Celtic (Winamp extension)",
4007 		"Bluegrass (Winamp extension)",
4008 		"Avantgarde (Winamp extension)",
4009 		"Gothic Rock (Winamp extension)",
4010 		"Progressive Rock (Winamp extension)",
4011 		"Psychedelic Rock (Winamp extension)",
4012 		"Symphonic Rock (Winamp extension)",
4013 		"Slow Rock (Winamp extension)",
4014 		"Big Band (Winamp extension)",
4015 		"Chorus (Winamp extension)",
4016 		"Easy Listening (Winamp extension)",
4017 		"Acoustic (Winamp extension)",
4018 		"Humour (Winamp extension)",
4019 		"Speech (Winamp extension)",
4020 		"Chanson (Winamp extension)",
4021 		"Opera (Winamp extension)",
4022 		"Chamber Music (Winamp extension)",
4023 		"Sonata (Winamp extension)",
4024 		"Symphony (Winamp extension)",
4025 		"Booty Bass (Winamp extension)",
4026 		"Primus (Winamp extension)",
4027 		"Porn Groove (Winamp extension)",
4028 		"Satire (Winamp extension)",
4029 		"Slow Jam (Winamp extension)",
4030 		"Club (Winamp extension)",
4031 		"Tango (Winamp extension)",
4032 		"Samba (Winamp extension)",
4033 		"Folklore (Winamp extension)",
4034 		"Ballad (Winamp extension)",
4035 		"Power Ballad (Winamp extension)",
4036 		"Rhythmic Soul (Winamp extension)",
4037 		"Freestyle (Winamp extension)",
4038 		"Duet (Winamp extension)",
4039 		"Punk Rock (Winamp extension)",
4040 		"Drum Solo (Winamp extension)",
4041 		"A capella (Winamp extension)",
4042 		"Euro-House (Winamp extension)",
4043 		"Dance Hall (Winamp extension"
4044 	};
4045 
4046 	if ((!data[125]) && data[126])
4047 	{
4048 		print("%08lx ID3v1.1 128 bytes", (long) offset); newline();
4049 	} else {
4050 		print("%08lx ID3v1 128 bytes", (long) offset); newline();
4051 	}
4052 	indent++;
4053 
4054 	print("SongName:     "); d=data+  3; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
4055 	print("Artist:       "); d=data+ 33; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
4056 	print("Album:        "); d=data+ 63; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
4057 	print("Year:         "); d=data+ 93; l= 4; decode_print_iso8859_1(&d, &l, 0); newline();
4058 
4059 	if ((!data[125]) && data[126])
4060 	{
4061 		print("Comment:      "); d=data+ 97; l=27; decode_print_iso8859_1(&d, &l, 0); newline();
4062 		print("Track number: %d", data[126]); newline();
4063 	} else {
4064 
4065 		print("Comment:      "); d=data+ 97; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
4066 	}
4067 	print("Genre:        %d \"%s\"", data[127], (data[127]>=(sizeof(genre)/sizeof(genre[0])))?"Unknown":genre[data[127]]); newline();
4068 
4069 	indent--;
4070 }
4071 
decode_etag(uint8_t data[227],off_t offset)4072 static void decode_etag(uint8_t data[227], off_t offset)
4073 {
4074 	uint8_t  *d;
4075 	uint32_t l;
4076 
4077 	print("%08lx ETAG 227 bytes", (long) offset);newline();
4078 	indent++;
4079 
4080 	print("Title:      "); d=data+  4; l=60; decode_print_iso8859_1(&d, &l, 0); newline();
4081 	print("Artist:     "); d=data+ 64; l=60; decode_print_iso8859_1(&d, &l, 0); newline();
4082 	print("Album:      "); d=data+124; l=60; decode_print_iso8859_1(&d, &l, 0); newline();
4083 	switch (data[184])
4084 	{
4085 		case 0x00: print("Speed:      (unset)"); newline(); break;
4086 		case 0x01: print("Speed:      slow"); newline();  break;
4087 		case 0x02: print("Speed:      medium"); newline(); break;
4088 		case 0x03: print("Speed:      fast"); newline(); break;
4089 		case 0x04: print("Speed:      hardcore"); newline(); break;
4090 		default:   print("Speed:      (%d) Unknown", data[184]); newline(); break;
4091 	}
4092 	print("Genre:      "); d=data+185; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
4093 	print("Start-Time: "); d=data+215; l=6; decode_print_iso8859_1(&d, &l, 0); newline();
4094 	print("Stop-Time:  "); d=data+221; l=6; decode_print_iso8859_1(&d, &l, 0); newline();
4095 
4096 	indent--;
4097 }
4098 
scanfile(const char * filename)4099 static void scanfile(const char *filename)
4100 {
4101 	int fd;
4102 	uint8_t prehead[65536];
4103 	int fill;
4104 	int need_sync = 1;
4105 
4106 	printf ("FILE: %s\n", filename);
4107 	fd = open (filename, O_RDONLY);
4108 	if (fd < 0)
4109 	{
4110 		fprintf (stderr, "Failed to open %s\n", filename);
4111 		return;
4112 	}
4113 
4114 	if (read (fd, prehead, 3) != 3)
4115 	{
4116 		fprintf (stderr, "Failed to read offset 0, count 3\n");
4117 		close (fd);
4118 		return;
4119 	}
4120 
4121 	if (!memcmp (prehead, "TAG", 3))
4122 	{
4123 		if (read (fd, prehead + 3, 128-3) != (128-3))
4124 		{
4125 			fprintf (stderr, "Failed to read offset 3, count 125\n");
4126 			close (fd);
4127 			return;
4128 		}
4129 		fprintf (stderr, "NON STANDARD ID3v1 tag at the start of the file!!!\n");
4130 		decode_id3v1x (prehead, 0);
4131 	}
4132 
4133 	if (lseek (fd, -128, SEEK_END) != (off_t)-1)
4134 	{
4135 		read (fd, prehead, 3);
4136 		if (!memcmp (prehead, "TAG", 3))
4137 		{
4138 			if (read (fd, prehead + 3, 128-3) != (128-3))
4139 			{
4140 				fprintf (stderr, "Failed to read offset -125, count 125\n");
4141 				close (fd);
4142 				return;
4143 			}
4144 			decode_id3v1x (prehead, lseek(fd, 0, SEEK_CUR)-128);
4145 
4146 			lseek (fd, -256, SEEK_END);
4147 			read (fd, prehead, 3);
4148 			if (!memcmp (prehead, "EXT", 3))
4149 			{
4150 				if (read (fd, prehead + 3, 125) != (125))
4151 				{
4152 					fprintf (stderr, "Failed to read offset -351, count 223\n");
4153 					close (fd);
4154 					return;
4155 				}
4156 				decode_id3v12 (prehead, lseek(fd, 0, SEEK_CUR)-256);
4157 			}
4158 
4159 			lseek (fd, -355, SEEK_END);
4160 			read (fd, prehead, 4);
4161 			if (!memcmp (prehead, "TAG+", 4))
4162 			{
4163 				if (read (fd, prehead + 4, 227-4) != (227-4))
4164 				{
4165 					fprintf (stderr, "Failed to read offset -351, count 223\n");
4166 					close (fd);
4167 					return;
4168 				}
4169 				decode_etag (prehead, lseek(fd, 0, SEEK_CUR)-355);
4170 			}
4171 		}
4172 	}
4173 	lseek (fd, 0, SEEK_SET);
4174 	fill=0;
4175 	while (1)
4176 	{
4177 read_more:
4178 		fill += read (fd, prehead + fill, sizeof(prehead) - fill);
4179 		if (fill < 10)
4180 		{
4181 			break;
4182 		}
4183 		while (fill >= 10)
4184 		{
4185 			uint8_t *loc;
4186 
4187 			if (need_sync)
4188 			{
4189 				if (memcmp(prehead, "ID3", 3))
4190 				{
4191 					if (prehead[0] != 0xff)
4192 					{
4193 						printf ("offset=0x%08lx not sync yet: %02x\n", lseek(fd, 0, SEEK_CUR)-fill, prehead[0]);
4194 						fill -= 1;
4195 						memmove (prehead, prehead+1, fill);
4196 						continue;
4197 					} else {
4198 						need_sync = 0;
4199 					}
4200 				}
4201 			}
4202 
4203 
4204 			if ((loc = memmem (prehead, fill - 6, "ID3", 3)))
4205 			{
4206 				off_t decode_length;
4207 				//printf ("fill=%d offset=0x%08lx loc-prehead=%d realoffset=0x%08lx\n", fill, (long int) lseek(fd, 0, SEEK_CUR), loc-prehead, lseek(fd, 0, SEEK_CUR)-fill+(loc-prehead));
4208 				decode_length = decode_id3v2x(fd, loc, lseek(fd, 0, SEEK_CUR)-fill+(loc-prehead));
4209 				if (decode_length)
4210 				{
4211 					lseek (fd, - fill + (loc-prehead) + decode_length, SEEK_CUR);
4212 					fill = 0;
4213 					need_sync = 1;
4214 					goto read_more;
4215 				} else {
4216 					fill -= (loc-prehead)+10;
4217 					memmove (prehead, loc+10, fill);
4218 				}
4219 			} else {
4220 				break;
4221 			}
4222 		}
4223 		memmove (prehead, prehead + fill - 9, 9);
4224 		fill = 9;
4225 	}
4226 
4227 	close (fd);
4228 	fflush(stdout);
4229 }
4230 
main(int argc,char * argv[])4231 int main(int argc, char *argv[])
4232 {
4233 	int i;
4234 
4235 	if (argc < 2)
4236 	{
4237 		fprintf (stderr, "Usage: %s file\n", argv[0]);
4238 		return -1;
4239 	}
4240 	if (!strcmp (argv[1], "-2"))
4241 	{
4242 		uint8_t buffer[65536];
4243 		uint32_t fill;
4244 		int32_t result;
4245 		int fd;
4246 		for (i=2; i < argc; i++)
4247 		{
4248 			fd = open (argv[i], O_RDONLY);
4249 			if (fd < 0)
4250 			{
4251 				continue;
4252 			}
4253 			fill = read (fd, buffer, sizeof (buffer));
4254 			close (fd);
4255 			print("ID3v2.2.0 frame file: %s", argv[i]);newline();
4256 			result = decode_id3v220_frame (buffer, fill);
4257 			if (result < 0)
4258 			{
4259 			} else if (result != fill)
4260 			{
4261 				print("(EXTRA DATA AFTER FRAME: %d bytes", fill - result); newline();
4262 			}
4263 			flush();
4264 		}
4265 	} else if (!strcmp (argv[1], "-3"))
4266 	{
4267 		uint8_t buffer[65536];
4268 		uint32_t fill;
4269 		int32_t result;
4270 		int fd;
4271 		for (i=2; i < argc; i++)
4272 		{
4273 			fd = open (argv[i], O_RDONLY);
4274 			if (fd < 0)
4275 			{
4276 				continue;
4277 			}
4278 			fill = read (fd, buffer, sizeof (buffer));
4279 			close (fd);
4280 			print("ID3v2.3.0 frame file: %s", argv[i]);newline();
4281 			result = decode_id3v230_frame (buffer, fill);
4282 			if (result < 0)
4283 			{
4284 			} else if (result != fill)
4285 			{
4286 				print("(EXTRA DATA AFTER FRAME: %d bytes", fill - result); newline();
4287 			}
4288 			flush();
4289 		}
4290 	} else if (!strcmp (argv[1], "-4"))
4291 	{
4292 		uint8_t buffer[65536];
4293 		uint32_t fill;
4294 		int32_t result;
4295 		int fd;
4296 		for (i=2; i < argc; i++)
4297 		{
4298 			fd = open (argv[i], O_RDONLY);
4299 			if (fd < 0)
4300 			{
4301 				continue;
4302 			}
4303 			fill = read (fd, buffer, sizeof (buffer));
4304 			close (fd);
4305 			print("ID3v2.4.0 frame file: %s", argv[i]);newline();
4306 			result = decode_id3v240_frame (buffer, fill);
4307 			if (result < 0)
4308 			{
4309 			} else if (result != fill)
4310 			{
4311 				print("(EXTRA DATA AFTER FRAME: %d bytes", fill - result); newline();
4312 			}
4313 			flush();
4314 		}
4315 	} else {
4316 		for (i=1; i < argc; i++)
4317 		{
4318 			scanfile(argv[i]);
4319 			flush();
4320 		}
4321 	}
4322 	return 0;
4323 }
4324