Bug Summary

File:libs/libsndfile/src/sd2.c
Location:line 166, column 2
Description:Use of memory after it is freed

Annotated Source Code

1/*
2** Copyright (C) 2001-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
3** Copyright (C) 2004 Paavo Jumppanen
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU Lesser General Public License as published by
7** the Free Software Foundation; either version 2.1 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU Lesser General Public License for more details.
14**
15** You should have received a copy of the GNU Lesser General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18*/
19
20/*
21** The sd2 support implemented in this file was partially sponsored
22** (financially) by Paavo Jumppanen.
23*/
24
25/*
26** Documentation on the Mac resource fork was obtained here :
27** http://developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html
28*/
29
30#include "sfconfig.h"
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <ctype.h>
36
37#include "sndfile.h"
38#include "sfendian.h"
39#include "common.h"
40
41/*------------------------------------------------------------------------------
42 * Markers.
43*/
44
45#define Sd2f_MARKER((uint32_t) (('S') | (('d') << 8) | (('2') << 16)
| (((uint32_t) ('f')) << 24)))
MAKE_MARKER ('S', 'd', '2', 'f')((uint32_t) (('S') | (('d') << 8) | (('2') << 16)
| (((uint32_t) ('f')) << 24)))
46#define Sd2a_MARKER((uint32_t) (('S') | (('d') << 8) | (('2') << 16)
| (((uint32_t) ('a')) << 24)))
MAKE_MARKER ('S', 'd', '2', 'a')((uint32_t) (('S') | (('d') << 8) | (('2') << 16)
| (((uint32_t) ('a')) << 24)))
47#define ALCH_MARKER((uint32_t) (('A') | (('L') << 8) | (('C') << 16)
| (((uint32_t) ('H')) << 24)))
MAKE_MARKER ('A', 'L', 'C', 'H')((uint32_t) (('A') | (('L') << 8) | (('C') << 16)
| (((uint32_t) ('H')) << 24)))
48#define lsf1_MARKER((uint32_t) (('l') | (('s') << 8) | (('f') << 16)
| (((uint32_t) ('1')) << 24)))
MAKE_MARKER ('l', 's', 'f', '1')((uint32_t) (('l') | (('s') << 8) | (('f') << 16)
| (((uint32_t) ('1')) << 24)))
49
50#define STR_MARKER((uint32_t) (('S') | (('T') << 8) | (('R') << 16)
| (((uint32_t) (' ')) << 24)))
MAKE_MARKER ('S', 'T', 'R', ' ')((uint32_t) (('S') | (('T') << 8) | (('R') << 16)
| (((uint32_t) (' ')) << 24)))
51#define sdML_MARKER((uint32_t) (('s') | (('d') << 8) | (('M') << 16)
| (((uint32_t) ('L')) << 24)))
MAKE_MARKER ('s', 'd', 'M', 'L')((uint32_t) (('s') | (('d') << 8) | (('M') << 16)
| (((uint32_t) ('L')) << 24)))
52
53enum
54{ RSRC_STR = 111,
55 RSRC_BIN
56} ;
57
58typedef struct
59{ unsigned char * rsrc_data ;
60 int rsrc_len ;
61 int need_to_free_rsrc_data ;
62
63 int data_offset, data_length ;
64 int map_offset, map_length ;
65
66 int type_count, type_offset ;
67 int item_offset ;
68
69 int str_index, str_count ;
70
71 int string_offset ;
72
73 /* All the above just to get these three. */
74 int sample_size, sample_rate, channels ;
75} SD2_RSRC ;
76
77typedef struct
78{ int type ;
79 int id ;
80 char name [32] ;
81 char value [32] ;
82 int value_len ;
83} STR_RSRC ;
84
85/*------------------------------------------------------------------------------
86 * Private static functions.
87*/
88
89static int sd2_close (SF_PRIVATE *psf) ;
90
91static int sd2_parse_rsrc_fork (SF_PRIVATE *psf) ;
92static int parse_str_rsrc (SF_PRIVATE *psf, SD2_RSRC * rsrc) ;
93
94static int sd2_write_rsrc_fork (SF_PRIVATE *psf, int calc_length) ;
95
96/*------------------------------------------------------------------------------
97** Public functions.
98*/
99
100int
101sd2_open (SF_PRIVATE *psf)
102{ int subformat, error = 0, valid ;
103
104 /* SD2 is always big endian. */
105 psf->endian = SF_ENDIAN_BIG ;
106
107 if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->rsrclength > 0))
1
Taking true branch
108 { psf_use_rsrc (psf, SF_TRUE) ;
109 valid = psf_file_valid (psf) ;
110 psf_use_rsrc (psf, SF_FALSE) ;
111 if (! valid)
2
Assuming 'valid' is not equal to 0
3
Taking false branch
112 { psf_log_printf (psf, "sd2_open : psf->rsrc.filedes < 0\n") ;
113 return SFE_SD2_BAD_RSRC ;
114 } ;
115
116 error = sd2_parse_rsrc_fork (psf) ;
4
Calling 'sd2_parse_rsrc_fork'
10
Returning; memory was released via 1st parameter
117
118 if (error)
11
Taking true branch
119 goto error_cleanup ;
12
Control jumps to line 166
120 } ;
121
122 if ((SF_CONTAINER (psf->sf.format)((psf->sf.format) & SF_FORMAT_TYPEMASK)) != SF_FORMAT_SD2)
123 { error = SFE_BAD_OPEN_FORMAT ;
124 goto error_cleanup ;
125 } ;
126
127 subformat = SF_CODEC (psf->sf.format)((psf->sf.format) & SF_FORMAT_SUBMASK) ;
128 psf->dataoffset = 0 ;
129
130 /* Only open and write the resource in RDWR mode is its current length is zero. */
131 if (psf->file.mode == SFM_WRITE || (psf->file.mode == SFM_RDWR && psf->rsrclength == 0))
132 { psf->rsrc.mode = psf->file.mode ;
133 psf_open_rsrc (psf) ;
134
135 error = sd2_write_rsrc_fork (psf, SF_FALSE) ;
136
137 if (error)
138 goto error_cleanup ;
139
140 /* Not needed. */
141 psf->write_header = NULL((void*)0) ;
142 } ;
143
144 psf->container_close = sd2_close ;
145
146 psf->blockwidth = psf->bytewidth * psf->sf.channels ;
147
148 switch (subformat)
149 { case SF_FORMAT_PCM_S8 : /* 8-bit linear PCM. */
150 case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
151 case SF_FORMAT_PCM_24 : /* 24-bit linear PCM */
152 case SF_FORMAT_PCM_32 : /* 32-bit linear PCM */
153 error = pcm_init (psf) ;
154 break ;
155
156 default :
157 error = SFE_UNIMPLEMENTED ;
158 break ;
159 } ;
160
161 psf_fseek (psf, psf->dataoffset, SEEK_SET0) ;
162
163error_cleanup:
164
165 /* Close the resource fork regardless. We won't need it again. */
166 psf_close_rsrc (psf) ;
13
Use of memory after it is freed
167
168 return error ;
169} /* sd2_open */
170
171/*------------------------------------------------------------------------------
172*/
173
174static int
175sd2_close (SF_PRIVATE *psf)
176{
177 if (psf->file.mode == SFM_WRITE)
178 { /* Now we know for certain the audio_length of the file we can re-write
179 ** correct values for the FORM, 8SVX and BODY chunks.
180 */
181
182 } ;
183
184 return 0 ;
185} /* sd2_close */
186
187/*------------------------------------------------------------------------------
188*/
189
190static inline void
191write_char (unsigned char * data, int offset, char value)
192{ data [offset] = value ;
193} /* write_char */
194
195static inline void
196write_short (unsigned char * data, int offset, short value)
197{ data [offset] = value >> 8 ;
198 data [offset + 1] = value ;
199} /* write_char */
200
201static inline void
202write_int (unsigned char * data, int offset, int value)
203{ data [offset] = value >> 24 ;
204 data [offset + 1] = value >> 16 ;
205 data [offset + 2] = value >> 8 ;
206 data [offset + 3] = value ;
207} /* write_int */
208
209static inline void
210write_marker (unsigned char * data, int offset, int value)
211{
212 if (CPU_IS_BIG_ENDIAN0)
213 { data [offset] = value >> 24 ;
214 data [offset + 1] = value >> 16 ;
215 data [offset + 2] = value >> 8 ;
216 data [offset + 3] = value ;
217 }
218 else
219 { data [offset] = value ;
220 data [offset + 1] = value >> 8 ;
221 data [offset + 2] = value >> 16 ;
222 data [offset + 3] = value >> 24 ;
223 } ;
224} /* write_marker */
225
226static void
227write_str (unsigned char * data, int offset, const char * buffer, int buffer_len)
228{ memcpy (data + offset, buffer, buffer_len) ;
229} /* write_str */
230
231static int
232sd2_write_rsrc_fork (SF_PRIVATE *psf, int UNUSED (calc_length)UNUSED_calc_length __attribute__ ((unused)))
233{ SD2_RSRC rsrc ;
234 STR_RSRC str_rsrc [] =
235 { { RSRC_STR, 1000, "_sample-size", "", 0 },
236 { RSRC_STR, 1001, "_sample-rate", "", 0 },
237 { RSRC_STR, 1002, "_channels", "", 0 },
238 { RSRC_BIN, 1000, "_Markers", "", 8 }
239 } ;
240
241 int k, str_offset, data_offset, next_str ;
242
243 psf_use_rsrc (psf, SF_TRUE) ;
244
245 memset (&rsrc, 0, sizeof (rsrc)) ;
246
247 rsrc.sample_rate = psf->sf.samplerate ;
248 rsrc.sample_size = psf->bytewidth ;
249 rsrc.channels = psf->sf.channels ;
250
251 rsrc.rsrc_data = psf->header ;
252 rsrc.rsrc_len = sizeof (psf->header) ;
253 memset (rsrc.rsrc_data, 0xea, rsrc.rsrc_len) ;
254
255 snprintf (str_rsrc [0].value, sizeof (str_rsrc [0].value), "_%d", rsrc.sample_size)__builtin___snprintf_chk (str_rsrc [0].value, sizeof (str_rsrc
[0].value), 2 - 1, __builtin_object_size (str_rsrc [0].value
, 2 > 1), "_%d", rsrc.sample_size)
;
256 snprintf (str_rsrc [1].value, sizeof (str_rsrc [1].value), "_%d.000000", rsrc.sample_rate)__builtin___snprintf_chk (str_rsrc [1].value, sizeof (str_rsrc
[1].value), 2 - 1, __builtin_object_size (str_rsrc [1].value
, 2 > 1), "_%d.000000", rsrc.sample_rate)
;
257 snprintf (str_rsrc [2].value, sizeof (str_rsrc [2].value), "_%d", rsrc.channels)__builtin___snprintf_chk (str_rsrc [2].value, sizeof (str_rsrc
[2].value), 2 - 1, __builtin_object_size (str_rsrc [2].value
, 2 > 1), "_%d", rsrc.channels)
;
258
259 for (k = 0 ; k < ARRAY_LEN (str_rsrc)((int) (sizeof (str_rsrc) / sizeof ((str_rsrc) [0]))) ; k++)
260 { if (str_rsrc [k].value_len == 0)
261 { str_rsrc [k].value_len = strlen (str_rsrc [k].value) ;
262 str_rsrc [k].value [0] = str_rsrc [k].value_len - 1 ;
263 } ;
264
265 /* Turn name string into a pascal string. */
266 str_rsrc [k].name [0] = strlen (str_rsrc [k].name) - 1 ;
267 } ;
268
269 rsrc.data_offset = 0x100 ;
270
271 /*
272 ** Calculate data length :
273 ** length of strings, plus the length of the sdML chunk.
274 */
275 rsrc.data_length = 0 ;
276 for (k = 0 ; k < ARRAY_LEN (str_rsrc)((int) (sizeof (str_rsrc) / sizeof ((str_rsrc) [0]))) ; k++)
277 rsrc.data_length += str_rsrc [k].value_len + 4 ;
278
279 rsrc.map_offset = rsrc.data_offset + rsrc.data_length ;
280
281 /* Very start of resource fork. */
282 write_int (rsrc.rsrc_data, 0, rsrc.data_offset) ;
283 write_int (rsrc.rsrc_data, 4, rsrc.map_offset) ;
284 write_int (rsrc.rsrc_data, 8, rsrc.data_length) ;
285
286 write_char (rsrc.rsrc_data, 0x30, strlen (psf->file.name.c)) ;
287 write_str (rsrc.rsrc_data, 0x31, psf->file.name.c, strlen (psf->file.name.c)) ;
288
289 write_short (rsrc.rsrc_data, 0x50, 0) ;
290 write_marker (rsrc.rsrc_data, 0x52, Sd2f_MARKER((uint32_t) (('S') | (('d') << 8) | (('2') << 16)
| (((uint32_t) ('f')) << 24)))
) ;
291 write_marker (rsrc.rsrc_data, 0x56, lsf1_MARKER((uint32_t) (('l') | (('s') << 8) | (('f') << 16)
| (((uint32_t) ('1')) << 24)))
) ;
292
293 /* Very start of resource map. */
294 write_int (rsrc.rsrc_data, rsrc.map_offset + 0, rsrc.data_offset) ;
295 write_int (rsrc.rsrc_data, rsrc.map_offset + 4, rsrc.map_offset) ;
296 write_int (rsrc.rsrc_data, rsrc.map_offset + 8, rsrc.data_length) ;
297
298 /* These I don't currently understand. */
299 if (1)
300 { write_char (rsrc.rsrc_data, rsrc.map_offset+ 16, 1) ;
301 /* Next resource map. */
302 write_int (rsrc.rsrc_data, rsrc.map_offset + 17, 0x12345678) ;
303 /* File ref number. */
304 write_short (rsrc.rsrc_data, rsrc.map_offset + 21, 0xabcd) ;
305 /* Fork attributes. */
306 write_short (rsrc.rsrc_data, rsrc.map_offset + 23, 0) ;
307 } ;
308
309 /* Resource type offset. */
310 rsrc.type_offset = rsrc.map_offset + 30 ;
311 write_short (rsrc.rsrc_data, rsrc.map_offset + 24, rsrc.type_offset - rsrc.map_offset - 2) ;
312
313 /* Type index max. */
314 rsrc.type_count = 2 ;
315 write_short (rsrc.rsrc_data, rsrc.map_offset + 28, rsrc.type_count - 1) ;
316
317 rsrc.item_offset = rsrc.type_offset + rsrc.type_count * 8 ;
318
319 rsrc.str_count = ARRAY_LEN (str_rsrc)((int) (sizeof (str_rsrc) / sizeof ((str_rsrc) [0]))) ;
320 rsrc.string_offset = rsrc.item_offset + (rsrc.str_count + 1) * 12 - rsrc.map_offset ;
321 write_short (rsrc.rsrc_data, rsrc.map_offset + 26, rsrc.string_offset) ;
322
323 /* Write 'STR ' resource type. */
324 rsrc.str_count = 3 ;
325 write_marker (rsrc.rsrc_data, rsrc.type_offset, STR_MARKER((uint32_t) (('S') | (('T') << 8) | (('R') << 16)
| (((uint32_t) (' ')) << 24)))
) ;
326 write_short (rsrc.rsrc_data, rsrc.type_offset + 4, rsrc.str_count - 1) ;
327 write_short (rsrc.rsrc_data, rsrc.type_offset + 6, 0x12) ;
328
329 /* Write 'sdML' resource type. */
330 write_marker (rsrc.rsrc_data, rsrc.type_offset + 8, sdML_MARKER((uint32_t) (('s') | (('d') << 8) | (('M') << 16)
| (((uint32_t) ('L')) << 24)))
) ;
331 write_short (rsrc.rsrc_data, rsrc.type_offset + 12, 0) ;
332 write_short (rsrc.rsrc_data, rsrc.type_offset + 14, 0x36) ;
333
334 str_offset = rsrc.map_offset + rsrc.string_offset ;
335 next_str = 0 ;
336 data_offset = rsrc.data_offset ;
337 for (k = 0 ; k < ARRAY_LEN (str_rsrc)((int) (sizeof (str_rsrc) / sizeof ((str_rsrc) [0]))) ; k++)
338 { write_str (rsrc.rsrc_data, str_offset, str_rsrc [k].name, strlen (str_rsrc [k].name)) ;
339
340 write_short (rsrc.rsrc_data, rsrc.item_offset + k * 12, str_rsrc [k].id) ;
341 write_short (rsrc.rsrc_data, rsrc.item_offset + k * 12 + 2, next_str) ;
342
343 str_offset += strlen (str_rsrc [k].name) ;
344 next_str += strlen (str_rsrc [k].name) ;
345
346 write_int (rsrc.rsrc_data, rsrc.item_offset + k * 12 + 4, data_offset - rsrc.data_offset) ;
347
348 write_int (rsrc.rsrc_data, data_offset, str_rsrc [k].value_len) ;
349 write_str (rsrc.rsrc_data, data_offset + 4, str_rsrc [k].value, str_rsrc [k].value_len) ;
350 data_offset += 4 + str_rsrc [k].value_len ;
351 } ;
352
353 /* Finally, calculate and set map length. */
354 rsrc.map_length = str_offset - rsrc.map_offset ;
355 write_int (rsrc.rsrc_data, 12, rsrc.map_length) ;
356 write_int (rsrc.rsrc_data, rsrc.map_offset + 12, rsrc.map_length) ;
357
358 rsrc.rsrc_len = rsrc.map_offset + rsrc.map_length ;
359
360 psf_fwrite (rsrc.rsrc_data, rsrc.rsrc_len, 1, psf) ;
361
362 psf_use_rsrc (psf, SF_FALSE) ;
363
364 if (psf->error)
365 return psf->error ;
366
367 return 0 ;
368} /* sd2_write_rsrc_fork */
369
370/*------------------------------------------------------------------------------
371*/
372
373static inline int
374read_rsrc_char (const SD2_RSRC *prsrc, int offset)
375{ const unsigned char * data = prsrc->rsrc_data ;
376 if (offset < 0 || offset >= prsrc->rsrc_len)
377 return 0 ;
378 return data [offset] ;
379} /* read_rsrc_char */
380
381static inline int
382read_rsrc_short (const SD2_RSRC *prsrc, int offset)
383{ const unsigned char * data = prsrc->rsrc_data ;
384 if (offset < 0 || offset + 1 >= prsrc->rsrc_len)
385 return 0 ;
386 return (data [offset] << 8) + data [offset + 1] ;
387} /* read_rsrc_short */
388
389static inline int
390read_rsrc_int (const SD2_RSRC *prsrc, int offset)
391{ const unsigned char * data = prsrc->rsrc_data ;
392 if (offset < 0 || offset + 3 >= prsrc->rsrc_len)
393 return 0 ;
394 return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ;
395} /* read_rsrc_int */
396
397static inline int
398read_rsrc_marker (const SD2_RSRC *prsrc, int offset)
399{ const unsigned char * data = prsrc->rsrc_data ;
400
401 if (offset < 0 || offset + 3 >= prsrc->rsrc_len)
402 return 0 ;
403
404 if (CPU_IS_BIG_ENDIAN0)
405 return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ;
406 if (CPU_IS_LITTLE_ENDIAN1)
407 return data [offset] + (data [offset + 1] << 8) + (data [offset + 2] << 16) + (data [offset + 3] << 24) ;
408
409 return 0 ;
410} /* read_rsrc_marker */
411
412static void
413read_rsrc_str (const SD2_RSRC *prsrc, int offset, char * buffer, int buffer_len)
414{ const unsigned char * data = prsrc->rsrc_data ;
415 int k ;
416
417 memset (buffer, 0, buffer_len) ;
418
419 if (offset < 0 || offset + buffer_len >= prsrc->rsrc_len)
420 return ;
421
422 for (k = 0 ; k < buffer_len - 1 ; k++)
423 { if (psf_isprint (data [offset + k]) == 0)
424 return ;
425 buffer [k] = data [offset + k] ;
426 } ;
427 return ;
428} /* read_rsrc_str */
429
430static int
431sd2_parse_rsrc_fork (SF_PRIVATE *psf)
432{ SD2_RSRC rsrc ;
433 int k, marker, error = 0 ;
434
435 psf_use_rsrc (psf, SF_TRUE) ;
436
437 memset (&rsrc, 0, sizeof (rsrc)) ;
438
439 rsrc.rsrc_len = psf_get_filelen (psf) ;
440 psf_log_printf (psf, "Resource length : %d (0x%04X)\n", rsrc.rsrc_len, rsrc.rsrc_len) ;
441
442 if (rsrc.rsrc_len > SIGNED_SIZEOF (psf->header)((int) sizeof (psf->header)))
5
Taking false branch
443 { rsrc.rsrc_data = calloc (1, rsrc.rsrc_len) ;
444 rsrc.need_to_free_rsrc_data = SF_TRUE ;
445 }
446 else
447 rsrc.rsrc_data = psf->header ;
448
449 /* Read in the whole lot. */
450 psf_fread (rsrc.rsrc_data, rsrc.rsrc_len, 1, psf) ;
451
452 /* Reset the header storage because we have changed to the rsrcdes. */
453 psf->headindex = psf->headend = rsrc.rsrc_len ;
454
455 rsrc.data_offset = read_rsrc_int (&rsrc, 0) ;
456 rsrc.map_offset = read_rsrc_int (&rsrc, 4) ;
457 rsrc.data_length = read_rsrc_int (&rsrc, 8) ;
458 rsrc.map_length = read_rsrc_int (&rsrc, 12) ;
459
460 if (rsrc.data_offset == 0x51607 && rsrc.map_offset == 0x20000)
461 { psf_log_printf (psf, "Trying offset of 0x52 bytes.\n") ;
462 rsrc.data_offset = read_rsrc_int (&rsrc, 0x52 + 0) + 0x52 ;
463 rsrc.map_offset = read_rsrc_int (&rsrc, 0x52 + 4) + 0x52 ;
464 rsrc.data_length = read_rsrc_int (&rsrc, 0x52 + 8) ;
465 rsrc.map_length = read_rsrc_int (&rsrc, 0x52 + 12) ;
466 } ;
467
468 psf_log_printf (psf, " data offset : 0x%04X\n map offset : 0x%04X\n"
469 " data length : 0x%04X\n map length : 0x%04X\n",
470 rsrc.data_offset, rsrc.map_offset, rsrc.data_length, rsrc.map_length) ;
471
472 if (rsrc.data_offset > rsrc.rsrc_len)
6
Taking true branch
473 { psf_log_printf (psf, "Error : rsrc.data_offset (%d, 0x%x) > len\n", rsrc.data_offset, rsrc.data_offset) ;
474 error = SFE_SD2_BAD_DATA_OFFSET ;
475 goto parse_rsrc_fork_cleanup ;
7
Control jumps to line 548
476 } ;
477
478 if (rsrc.map_offset > rsrc.rsrc_len)
479 { psf_log_printf (psf, "Error : rsrc.map_offset > len\n") ;
480 error = SFE_SD2_BAD_MAP_OFFSET ;
481 goto parse_rsrc_fork_cleanup ;
482 } ;
483
484 if (rsrc.data_length > rsrc.rsrc_len)
485 { psf_log_printf (psf, "Error : rsrc.data_length > len\n") ;
486 error = SFE_SD2_BAD_DATA_LENGTH ;
487 goto parse_rsrc_fork_cleanup ;
488 } ;
489
490 if (rsrc.map_length > rsrc.rsrc_len)
491 { psf_log_printf (psf, "Error : rsrc.map_length > len\n") ;
492 error = SFE_SD2_BAD_MAP_LENGTH ;
493 goto parse_rsrc_fork_cleanup ;
494 } ;
495
496 if (rsrc.data_offset + rsrc.data_length != rsrc.map_offset || rsrc.map_offset + rsrc.map_length != rsrc.rsrc_len)
497 { psf_log_printf (psf, "Error : This does not look like a MacOSX resource fork.\n") ;
498 error = SFE_SD2_BAD_RSRC ;
499 goto parse_rsrc_fork_cleanup ;
500 } ;
501
502 if (rsrc.map_offset + 28 >= rsrc.rsrc_len)
503 { psf_log_printf (psf, "Bad map offset (%d + 28 > %d).\n", rsrc.map_offset, rsrc.rsrc_len) ;
504 error = SFE_SD2_BAD_RSRC ;
505 goto parse_rsrc_fork_cleanup ;
506 } ;
507
508 rsrc.string_offset = rsrc.map_offset + read_rsrc_short (&rsrc, rsrc.map_offset + 26) ;
509 if (rsrc.string_offset > rsrc.rsrc_len)
510 { psf_log_printf (psf, "Bad string offset (%d).\n", rsrc.string_offset) ;
511 error = SFE_SD2_BAD_RSRC ;
512 goto parse_rsrc_fork_cleanup ;
513 } ;
514
515 rsrc.type_offset = rsrc.map_offset + 30 ;
516
517 rsrc.type_count = read_rsrc_short (&rsrc, rsrc.map_offset + 28) + 1 ;
518 if (rsrc.type_count < 1)
519 { psf_log_printf (psf, "Bad type count.\n") ;
520 error = SFE_SD2_BAD_RSRC ;
521 goto parse_rsrc_fork_cleanup ;
522 } ;
523
524 rsrc.item_offset = rsrc.type_offset + rsrc.type_count * 8 ;
525 if (rsrc.item_offset < 0 || rsrc.item_offset > rsrc.rsrc_len)
526 { psf_log_printf (psf, "Bad item offset (%d).\n", rsrc.item_offset) ;
527 error = SFE_SD2_BAD_RSRC ;
528 goto parse_rsrc_fork_cleanup ;
529 } ;
530
531 rsrc.str_index = -1 ;
532 for (k = 0 ; k < rsrc.type_count ; k ++)
533 { marker = read_rsrc_marker (&rsrc, rsrc.type_offset + k * 8) ;
534
535 if (marker == STR_MARKER((uint32_t) (('S') | (('T') << 8) | (('R') << 16)
| (((uint32_t) (' ')) << 24)))
)
536 { rsrc.str_index = k ;
537 rsrc.str_count = read_rsrc_short (&rsrc, rsrc.type_offset + k * 8 + 4) + 1 ;
538 error = parse_str_rsrc (psf, &rsrc) ;
539 goto parse_rsrc_fork_cleanup ;
540 } ;
541 } ;
542
543 psf_log_printf (psf, "No 'STR ' resource.\n") ;
544 error = SFE_SD2_BAD_RSRC ;
545
546parse_rsrc_fork_cleanup :
547
548 psf_use_rsrc (psf, SF_FALSE) ;
549
550 if (rsrc.need_to_free_rsrc_data)
8
Taking true branch
551 free (rsrc.rsrc_data) ;
9
Memory is released
552
553 return error ;
554} /* sd2_parse_rsrc_fork */
555
556static int
557parse_str_rsrc (SF_PRIVATE *psf, SD2_RSRC * rsrc)
558{ char name [32], value [32] ;
559 int k, str_offset, rsrc_id, data_offset = 0, data_len = 0 ;
560
561 psf_log_printf (psf, "Finding parameters :\n") ;
562
563 str_offset = rsrc->string_offset ;
564 psf_log_printf (psf, " Offset RsrcId dlen slen Value\n") ;
565
566 for (k = 0 ; data_offset + data_len < rsrc->rsrc_len ; k++)
567 { int slen ;
568
569 slen = read_rsrc_char (rsrc, str_offset) ;
570 read_rsrc_str (rsrc, str_offset + 1, name, SF_MIN (SIGNED_SIZEOF (name), slen + 1)({ typeof (((int) sizeof (name))) sf_min_x2 = (((int) sizeof (
name))) ; typeof (slen + 1) sf_min_y2 = (slen + 1) ; (void) (
&sf_min_x2 == &sf_min_y2) ; sf_min_x2 < sf_min_y2 ?
sf_min_x2 : sf_min_y2 ; })
) ;
571 str_offset += slen + 1 ;
572
573 rsrc_id = read_rsrc_short (rsrc, rsrc->item_offset + k * 12) ;
574
575 data_offset = rsrc->data_offset + read_rsrc_int (rsrc, rsrc->item_offset + k * 12 + 4) ;
576 if (data_offset < 0 || data_offset > rsrc->rsrc_len)
577 { psf_log_printf (psf, "Exiting parser on data offset of %d.\n", data_offset) ;
578 break ;
579 } ;
580
581 data_len = read_rsrc_int (rsrc, data_offset) ;
582 if (data_len < 0 || data_len > rsrc->rsrc_len)
583 { psf_log_printf (psf, "Exiting parser on data length of %d.\n", data_len) ;
584 break ;
585 } ;
586
587 slen = read_rsrc_char (rsrc, data_offset + 4) ;
588 read_rsrc_str (rsrc, data_offset + 5, value, SF_MIN (SIGNED_SIZEOF (value), slen + 1)({ typeof (((int) sizeof (value))) sf_min_x2 = (((int) sizeof
(value))) ; typeof (slen + 1) sf_min_y2 = (slen + 1) ; (void
) (&sf_min_x2 == &sf_min_y2) ; sf_min_x2 < sf_min_y2
? sf_min_x2 : sf_min_y2 ; })
) ;
589
590 psf_log_printf (psf, " 0x%04x %4d %4d %3d '%s'\n", data_offset, rsrc_id, data_len, slen, value) ;
591
592 if (rsrc_id == 1000 && rsrc->sample_size == 0)
593 rsrc->sample_size = strtol (value, NULL((void*)0), 10) ;
594 else if (rsrc_id == 1001 && rsrc->sample_rate == 0)
595 rsrc->sample_rate = strtol (value, NULL((void*)0), 10) ;
596 else if (rsrc_id == 1002 && rsrc->channels == 0)
597 rsrc->channels = strtol (value, NULL((void*)0), 10) ;
598 } ;
599
600 psf_log_printf (psf, "Found Parameters :\n") ;
601 psf_log_printf (psf, " sample-size : %d\n", rsrc->sample_size) ;
602 psf_log_printf (psf, " sample-rate : %d\n", rsrc->sample_rate) ;
603 psf_log_printf (psf, " channels : %d\n", rsrc->channels) ;
604
605 if (rsrc->sample_rate <= 4 && rsrc->sample_size > 4)
606 { int temp ;
607
608 psf_log_printf (psf, "Geez!! Looks like sample rate and sample size got switched.\nCorrecting this screw up.\n") ;
609 temp = rsrc->sample_rate ;
610 rsrc->sample_rate = rsrc->sample_size ;
611 rsrc->sample_size = temp ;
612 } ;
613
614 if (rsrc->sample_rate < 0)
615 { psf_log_printf (psf, "Bad sample rate (%d)\n", rsrc->sample_rate) ;
616 return SFE_SD2_BAD_RSRC ;
617 } ;
618
619 if (rsrc->channels < 0)
620 { psf_log_printf (psf, "Bad channel count (%d)\n", rsrc->channels) ;
621 return SFE_SD2_BAD_RSRC ;
622 } ;
623
624 psf->sf.samplerate = rsrc->sample_rate ;
625 psf->sf.channels = rsrc->channels ;
626 psf->bytewidth = rsrc->sample_size ;
627
628 switch (rsrc->sample_size)
629 { case 1 :
630 psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_S8 ;
631 break ;
632
633 case 2 :
634 psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_16 ;
635 break ;
636
637 case 3 :
638 psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_24 ;
639 break ;
640
641 case 4 :
642 psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_32 ;
643 break ;
644
645 default :
646 psf_log_printf (psf, "Bad sample size (%d)\n", rsrc->sample_size) ;
647 return SFE_SD2_BAD_SAMPLE_SIZE ;
648 } ;
649
650 psf_log_printf (psf, "ok\n") ;
651
652 return 0 ;
653} /* parse_str_rsrc */
654