aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/nsfe_extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/nsfe_extractor.c')
-rw-r--r--src/plugins/nsfe_extractor.c63
1 files changed, 32 insertions, 31 deletions
diff --git a/src/plugins/nsfe_extractor.c b/src/plugins/nsfe_extractor.c
index 02e376f..bde1315 100644
--- a/src/plugins/nsfe_extractor.c
+++ b/src/plugins/nsfe_extractor.c
@@ -1,17 +1,17 @@
1/* 1/*
2 * This file is part of libextractor. 2 * This file is part of libextractor.
3 * Copyright (C) 2007, 2009, 2012 Toni Ruottu and Christian Grothoff 3 * Copyright (C) 2007, 2009, 2012 Toni Ruottu and Christian Grothoff
4 * 4 *
5 * libextractor is free software; you can redistribute it and/or modify 5 * libextractor is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published 6 * it under the terms of the GNU General Public License as published
7 * by the Free Software Foundation; either version 3, or (at your 7 * by the Free Software Foundation; either version 3, or (at your
8 * option) any later version. 8 * option) any later version.
9 * 9 *
10 * libextractor is distributed in the hope that it will be useful, but 10 * libextractor is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details. 13 * General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with libextractor; see the file COPYING. If not, write to the 16 * along with libextractor; see the file COPYING. If not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
@@ -52,17 +52,16 @@ struct header
52 52
53/** 53/**
54 * Read an unsigned integer at the current offset. 54 * Read an unsigned integer at the current offset.
55 * 55 *
56 * @param data input data to parse 56 * @param data input data to parse
57 * @return parsed integer 57 * @return parsed integer
58 */ 58 */
59static uint32_t 59static uint32_t
60nsfeuint (const char *data) 60nsfeuint (const char *data)
61{ 61{
62 int i;
63 uint32_t value = 0; 62 uint32_t value = 0;
64 63
65 for (i = 3; i > 0; i--) 64 for (int i = 3; i > 0; i--)
66 { 65 {
67 value += (unsigned char) data[i]; 66 value += (unsigned char) data[i];
68 value *= 0x100; 67 value *= 0x100;
@@ -81,7 +80,7 @@ nsfeuint (const char *data)
81 * @return copy of the string at data 80 * @return copy of the string at data
82 */ 81 */
83static char * 82static char *
84nsfestring (const char *data, 83nsfestring (const char *data,
85 size_t size) 84 size_t size)
86{ 85{
87 char *s; 86 char *s;
@@ -181,7 +180,7 @@ info_extract (struct EXTRACTOR_ExtractContext *ec,
181 &data, 180 &data,
182 size)) 181 size))
183 return 1; 182 return 1;
184 ichunk = data; 183 ichunk = data;
185 184
186 if (0 != (ichunk->tvflags & DUAL_FLAG)) 185 if (0 != (ichunk->tvflags & DUAL_FLAG))
187 { 186 {
@@ -192,7 +191,7 @@ info_extract (struct EXTRACTOR_ExtractContext *ec,
192 if (0 != (ichunk->tvflags & PAL_FLAG)) 191 if (0 != (ichunk->tvflags & PAL_FLAG))
193 ADD ("PAL", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); 192 ADD ("PAL", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM);
194 else 193 else
195 ADD ("NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); 194 ADD ("NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM);
196 } 195 }
197 196
198 if (0 != (ichunk->chipflags & VRCVI_FLAG)) 197 if (0 != (ichunk->chipflags & VRCVI_FLAG))
@@ -200,25 +199,25 @@ info_extract (struct EXTRACTOR_ExtractContext *ec,
200 if (0 != (ichunk->chipflags & VRCVII_FLAG)) 199 if (0 != (ichunk->chipflags & VRCVII_FLAG))
201 ADD ("VRCVII", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 200 ADD ("VRCVII", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
202 if (0 != (ichunk->chipflags & FDS_FLAG)) 201 if (0 != (ichunk->chipflags & FDS_FLAG))
203 ADD ("FDS Sound", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 202 ADD ("FDS Sound", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
204 if (0 != (ichunk->chipflags & MMC5_FLAG)) 203 if (0 != (ichunk->chipflags & MMC5_FLAG))
205 ADD ("MMC5 audio", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 204 ADD ("MMC5 audio", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
206 if (0 != (ichunk->chipflags & NAMCO_FLAG)) 205 if (0 != (ichunk->chipflags & NAMCO_FLAG))
207 ADD ("Namco 106", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 206 ADD ("Namco 106", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
208 if (0 != (ichunk->chipflags & SUNSOFT_FLAG)) 207 if (0 != (ichunk->chipflags & SUNSOFT_FLAG))
209 ADD ("Sunsoft FME-07", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 208 ADD ("Sunsoft FME-07", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
210 209
211 if (size < sizeof (struct infochunk)) 210 if (size < sizeof (struct infochunk))
212 { 211 {
213 ADD ("1", EXTRACTOR_METATYPE_SONG_COUNT); 212 ADD ("1", EXTRACTOR_METATYPE_SONG_COUNT);
214 return 0; 213 return 0;
215 } 214 }
216 snprintf (songs, 215 snprintf (songs,
217 sizeof (songs), 216 sizeof (songs),
218 "%d", 217 "%d",
219 ichunk->songs); 218 ichunk->songs);
220 ADD (songs, EXTRACTOR_METATYPE_SONG_COUNT); 219 ADD (songs, EXTRACTOR_METATYPE_SONG_COUNT);
221 snprintf (songs, 220 snprintf (songs,
222 sizeof (songs), 221 sizeof (songs),
223 "%d", 222 "%d",
224 ichunk->firstsong); 223 ichunk->firstsong);
@@ -249,14 +248,14 @@ tlbl_extract (struct EXTRACTOR_ExtractContext *ec,
249 &data, 248 &data,
250 size)) 249 size))
251 return 1; 250 return 1;
252 cdata = data; 251 cdata = data;
253 252
254 left = size; 253 left = size;
255 while (left > 0) 254 while (left > 0)
256 { 255 {
257 title = nsfestring (&cdata[size - left], left); 256 title = nsfestring (&cdata[size - left], left);
258 if (NULL == title) 257 if (NULL == title)
259 return 0; 258 return 0;
260 length = strlen (title) + 1; 259 length = strlen (title) + 1;
261 ADDF (title, EXTRACTOR_METATYPE_TITLE); 260 ADDF (title, EXTRACTOR_METATYPE_TITLE);
262 left -= length; 261 left -= length;
@@ -291,15 +290,15 @@ auth_extract (struct EXTRACTOR_ExtractContext *ec,
291 &data, 290 &data,
292 size)) 291 size))
293 return 1; 292 return 1;
294 cdata = data; 293 cdata = data;
295 294
296 album = nsfestring (&cdata[size - left], left); 295 album = nsfestring (&cdata[size - left], left);
297 if (NULL != album) 296 if (NULL != album)
298 { 297 {
299 left -= (strlen (album) + 1); 298 left -= (strlen (album) + 1);
300 ADDF (album, EXTRACTOR_METATYPE_ALBUM); 299 ADDF (album, EXTRACTOR_METATYPE_ALBUM);
301 if (left < 1) 300 if (left < 1)
302 return 0; 301 return 0;
303 } 302 }
304 303
305 artist = nsfestring (&cdata[size - left], left); 304 artist = nsfestring (&cdata[size - left], left);
@@ -307,7 +306,7 @@ auth_extract (struct EXTRACTOR_ExtractContext *ec,
307 { 306 {
308 left -= (strlen (artist) + 1); 307 left -= (strlen (artist) + 1);
309 ADDF (artist, EXTRACTOR_METATYPE_ARTIST); 308 ADDF (artist, EXTRACTOR_METATYPE_ARTIST);
310 if (left < 1) 309 if (left < 1)
311 return 0; 310 return 0;
312 } 311 }
313 312
@@ -342,24 +341,24 @@ EXTRACTOR_nsfe_extract_method (struct EXTRACTOR_ExtractContext *ec)
342 uint64_t off; 341 uint64_t off;
343 uint32_t chunksize; 342 uint32_t chunksize;
344 int ret; 343 int ret;
345 344
346 if (sizeof (struct header) > 345 if (sizeof (struct header) >
347 ec->read (ec->cls, 346 ec->read (ec->cls,
348 &data, 347 &data,
349 sizeof (struct header))) 348 sizeof (struct header)))
350 return; 349 return;
351 head = data; 350 head = data;
352 if (0 != memcmp (head->magicid, "NSFE", 4)) 351 if (0 != memcmp (head->magicid, "NSFE", 4))
353 return; 352 return;
354 353
355 if (0 != ec->proc (ec->cls, 354 if (0 != ec->proc (ec->cls,
356 "nsfe", 355 "nsfe",
357 EXTRACTOR_METATYPE_MIMETYPE, 356 EXTRACTOR_METATYPE_MIMETYPE,
358 EXTRACTOR_METAFORMAT_UTF8, 357 EXTRACTOR_METAFORMAT_UTF8,
359 "text/plain", 358 "text/plain",
360 "audio/x-nsfe", 359 "audio/x-nsfe",
361 strlen ("audio/x-nsfe") + 1)) 360 strlen ("audio/x-nsfe") + 1))
362 return; 361 return;
363 off = sizeof (struct header); 362 off = sizeof (struct header);
364 ret = 0; 363 ret = 0;
365 while (0 == ret) 364 while (0 == ret)
@@ -374,11 +373,13 @@ EXTRACTOR_nsfe_extract_method (struct EXTRACTOR_ExtractContext *ec)
374 8)) 373 8))
375 break; 374 break;
376 chunksize = nsfeuint (data); 375 chunksize = nsfeuint (data);
376 if (off + chunksize + 8 <= off)
377 break; /* protect against looping */
377 off += 8 + chunksize; 378 off += 8 + chunksize;
378 if (0 == memcmp (data + 4, "INFO", 4)) 379 if (0 == memcmp (data + 4, "INFO", 4))
379 ret = info_extract (ec, chunksize); 380 ret = info_extract (ec, chunksize);
380 else if (0 == memcmp (data + 4, "auth", 4)) 381 else if (0 == memcmp (data + 4, "auth", 4))
381 ret = auth_extract (ec, chunksize); 382 ret = auth_extract (ec, chunksize);
382 else if (0 == memcmp (data + 4, "tlbl", 4)) 383 else if (0 == memcmp (data + 4, "tlbl", 4))
383 ret = tlbl_extract (ec, chunksize); 384 ret = tlbl_extract (ec, chunksize);
384 /* Ignored chunks: DATA, NEND, plst, time, fade, BANK */ 385 /* Ignored chunks: DATA, NEND, plst, time, fade, BANK */