diff options
Diffstat (limited to 'src/plugins/nsfe_extractor.c')
-rw-r--r-- | src/plugins/nsfe_extractor.c | 63 |
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 | */ |
59 | static uint32_t | 59 | static uint32_t |
60 | nsfeuint (const char *data) | 60 | nsfeuint (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 | */ |
83 | static char * | 82 | static char * |
84 | nsfestring (const char *data, | 83 | nsfestring (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 */ |