diff options
Diffstat (limited to 'src/plugins/old/real_extractor.c')
-rw-r--r-- | src/plugins/old/real_extractor.c | 421 |
1 files changed, 213 insertions, 208 deletions
diff --git a/src/plugins/old/real_extractor.c b/src/plugins/old/real_extractor.c index 0ca343c..cfac031 100644 --- a/src/plugins/old/real_extractor.c +++ b/src/plugins/old/real_extractor.c | |||
@@ -77,9 +77,9 @@ typedef struct | |||
77 | 77 | ||
78 | 78 | ||
79 | static int | 79 | static int |
80 | processMediaProperties (const Media_Properties * prop, | 80 | processMediaProperties (const Media_Properties *prop, |
81 | EXTRACTOR_MetaDataProcessor proc, | 81 | EXTRACTOR_MetaDataProcessor proc, |
82 | void *proc_cls) | 82 | void *proc_cls) |
83 | { | 83 | { |
84 | 84 | ||
85 | UINT8 mime_type_size; | 85 | UINT8 mime_type_size; |
@@ -95,28 +95,29 @@ processMediaProperties (const Media_Properties * prop, | |||
95 | return 0; | 95 | return 0; |
96 | 96 | ||
97 | mime_type_size = prop->data[prop->stream_name_size]; | 97 | mime_type_size = prop->data[prop->stream_name_size]; |
98 | if (prop_size > prop->stream_name_size + sizeof (UINT8) + | 98 | if (prop_size > prop->stream_name_size + sizeof (UINT8) |
99 | +mime_type_size + sizeof (Media_Properties)) | 99 | + +mime_type_size + sizeof (Media_Properties)) |
100 | { | 100 | { |
101 | char data[mime_type_size + 1]; | 101 | char data[mime_type_size + 1]; |
102 | memcpy (data, &prop->data[prop->stream_name_size + 1], mime_type_size); | 102 | memcpy (data, &prop->data[prop->stream_name_size + 1], mime_type_size); |
103 | data[mime_type_size] = '\0'; | 103 | data[mime_type_size] = '\0'; |
104 | 104 | ||
105 | return proc (proc_cls, | 105 | return proc (proc_cls, |
106 | "real", | 106 | "real", |
107 | EXTRACTOR_METATYPE_MIMETYPE, | 107 | EXTRACTOR_METATYPE_MIMETYPE, |
108 | EXTRACTOR_METAFORMAT_UTF8, | 108 | EXTRACTOR_METAFORMAT_UTF8, |
109 | "text/plain", | 109 | "text/plain", |
110 | data, | 110 | data, |
111 | strlen (data)); | 111 | strlen (data)); |
112 | } | 112 | } |
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
115 | 115 | ||
116 | |||
116 | static int | 117 | static int |
117 | processContentDescription (const Content_Description * prop, | 118 | processContentDescription (const Content_Description *prop, |
118 | EXTRACTOR_MetaDataProcessor proc, | 119 | EXTRACTOR_MetaDataProcessor proc, |
119 | void *proc_cls) | 120 | void *proc_cls) |
120 | { | 121 | { |
121 | UINT16 author_len; | 122 | UINT16 author_len; |
122 | UINT16 copyright_len; | 123 | UINT16 copyright_len; |
@@ -137,23 +138,23 @@ processContentDescription (const Content_Description * prop, | |||
137 | title_len = ntohs (prop->title_len); | 138 | title_len = ntohs (prop->title_len); |
138 | if (prop_size <= title_len + sizeof (UINT16) + sizeof (Content_Description)) | 139 | if (prop_size <= title_len + sizeof (UINT16) + sizeof (Content_Description)) |
139 | return 0; | 140 | return 0; |
140 | author_len = ntohs (*(UINT16 *) & prop->data[title_len]); | 141 | author_len = ntohs (*(UINT16 *) &prop->data[title_len]); |
141 | if (prop_size <= title_len + sizeof (UINT16) | 142 | if (prop_size <= title_len + sizeof (UINT16) |
142 | + author_len + sizeof (Content_Description)) | 143 | + author_len + sizeof (Content_Description)) |
143 | return 0; | 144 | return 0; |
144 | 145 | ||
145 | copyright_len = ntohs (*(UINT16 *) & prop->data[title_len + | 146 | copyright_len = ntohs (*(UINT16 *) &prop->data[title_len |
146 | author_len + | 147 | + author_len |
147 | sizeof (UINT16)]); | 148 | + sizeof (UINT16)]); |
148 | 149 | ||
149 | if (prop_size <= title_len + 2 * sizeof (UINT16) | 150 | if (prop_size <= title_len + 2 * sizeof (UINT16) |
150 | + author_len + copyright_len + sizeof (Content_Description)) | 151 | + author_len + copyright_len + sizeof (Content_Description)) |
151 | return 0; | 152 | return 0; |
152 | 153 | ||
153 | comment_len = ntohs (*(UINT16 *) & prop->data[title_len + | 154 | comment_len = ntohs (*(UINT16 *) &prop->data[title_len |
154 | author_len + | 155 | + author_len |
155 | copyright_len + | 156 | + copyright_len |
156 | 2 * sizeof (UINT16)]); | 157 | + 2 * sizeof (UINT16)]); |
157 | 158 | ||
158 | if (prop_size < title_len + 3 * sizeof (UINT16) | 159 | if (prop_size < title_len + 3 * sizeof (UINT16) |
159 | + author_len + copyright_len + comment_len | 160 | + author_len + copyright_len + comment_len |
@@ -163,78 +164,79 @@ processContentDescription (const Content_Description * prop, | |||
163 | ret = 0; | 164 | ret = 0; |
164 | title = malloc (title_len + 1); | 165 | title = malloc (title_len + 1); |
165 | if (title != NULL) | 166 | if (title != NULL) |
166 | { | 167 | { |
167 | memcpy (title, &prop->data[0], title_len); | 168 | memcpy (title, &prop->data[0], title_len); |
168 | title[title_len] = '\0'; | 169 | title[title_len] = '\0'; |
169 | ret = proc (proc_cls, | 170 | ret = proc (proc_cls, |
170 | "real", | 171 | "real", |
171 | EXTRACTOR_METATYPE_TITLE, | 172 | EXTRACTOR_METATYPE_TITLE, |
172 | EXTRACTOR_METAFORMAT_UTF8, | 173 | EXTRACTOR_METAFORMAT_UTF8, |
173 | "text/plain", | 174 | "text/plain", |
174 | title, | 175 | title, |
175 | strlen (title)+1); | 176 | strlen (title) + 1); |
176 | free (title); | 177 | free (title); |
177 | } | 178 | } |
178 | if (ret != 0) | 179 | if (ret != 0) |
179 | return ret; | 180 | return ret; |
180 | 181 | ||
181 | author = malloc (author_len + 1); | 182 | author = malloc (author_len + 1); |
182 | if (author != NULL) | 183 | if (author != NULL) |
183 | { | 184 | { |
184 | memcpy (author, &prop->data[title_len + sizeof (UINT16)], author_len); | 185 | memcpy (author, &prop->data[title_len + sizeof (UINT16)], author_len); |
185 | author[author_len] = '\0'; | 186 | author[author_len] = '\0'; |
186 | ret = proc (proc_cls, | 187 | ret = proc (proc_cls, |
187 | "real", | 188 | "real", |
188 | EXTRACTOR_METATYPE_AUTHOR_NAME, | 189 | EXTRACTOR_METATYPE_AUTHOR_NAME, |
189 | EXTRACTOR_METAFORMAT_UTF8, | 190 | EXTRACTOR_METAFORMAT_UTF8, |
190 | "text/plain", | 191 | "text/plain", |
191 | author, | 192 | author, |
192 | strlen (author)+1); | 193 | strlen (author) + 1); |
193 | free (author); | 194 | free (author); |
194 | } | 195 | } |
195 | if (ret != 0) | 196 | if (ret != 0) |
196 | return ret; | 197 | return ret; |
197 | 198 | ||
198 | copyright = malloc (copyright_len + 1); | 199 | copyright = malloc (copyright_len + 1); |
199 | if (copyright != NULL) | 200 | if (copyright != NULL) |
200 | { | 201 | { |
201 | memcpy (copyright, | 202 | memcpy (copyright, |
202 | &prop->data[title_len + sizeof (UINT16) * 2 + author_len], | 203 | &prop->data[title_len + sizeof (UINT16) * 2 + author_len], |
203 | copyright_len); | 204 | copyright_len); |
204 | copyright[copyright_len] = '\0'; | 205 | copyright[copyright_len] = '\0'; |
205 | ret = proc (proc_cls, | 206 | ret = proc (proc_cls, |
206 | "real", | 207 | "real", |
207 | EXTRACTOR_METATYPE_COPYRIGHT, | 208 | EXTRACTOR_METATYPE_COPYRIGHT, |
208 | EXTRACTOR_METAFORMAT_UTF8, | 209 | EXTRACTOR_METAFORMAT_UTF8, |
209 | "text/plain", | 210 | "text/plain", |
210 | copyright, | 211 | copyright, |
211 | strlen (copyright)+1); | 212 | strlen (copyright) + 1); |
212 | free (copyright); | 213 | free (copyright); |
213 | } | 214 | } |
214 | if (ret != 0) | 215 | if (ret != 0) |
215 | return ret; | 216 | return ret; |
216 | 217 | ||
217 | comment = malloc (comment_len + 1); | 218 | comment = malloc (comment_len + 1); |
218 | if (comment != NULL) | 219 | if (comment != NULL) |
219 | { | 220 | { |
220 | memcpy (comment, | 221 | memcpy (comment, |
221 | &prop->data[title_len + sizeof (UINT16) * 3 + author_len + | 222 | &prop->data[title_len + sizeof (UINT16) * 3 + author_len |
222 | copyright_len], comment_len); | 223 | + copyright_len], comment_len); |
223 | comment[comment_len] = '\0'; | 224 | comment[comment_len] = '\0'; |
224 | ret = proc (proc_cls, | 225 | ret = proc (proc_cls, |
225 | "real", | 226 | "real", |
226 | EXTRACTOR_METATYPE_COMMENT, | 227 | EXTRACTOR_METATYPE_COMMENT, |
227 | EXTRACTOR_METAFORMAT_UTF8, | 228 | EXTRACTOR_METAFORMAT_UTF8, |
228 | "text/plain", | 229 | "text/plain", |
229 | comment, | 230 | comment, |
230 | strlen (comment)+1); | 231 | strlen (comment) + 1); |
231 | free (comment); | 232 | free (comment); |
232 | } | 233 | } |
233 | if (ret != 0) | 234 | if (ret != 0) |
234 | return ret; | 235 | return ret; |
235 | return 0; | 236 | return 0; |
236 | } | 237 | } |
237 | 238 | ||
239 | |||
238 | typedef struct RAFF4_header | 240 | typedef struct RAFF4_header |
239 | { | 241 | { |
240 | unsigned short version; | 242 | unsigned short version; |
@@ -281,13 +283,14 @@ stndup (const char *str, size_t n) | |||
281 | return tmp; | 283 | return tmp; |
282 | } | 284 | } |
283 | 285 | ||
286 | |||
284 | /* audio/vnd.rn-realaudio */ | 287 | /* audio/vnd.rn-realaudio */ |
285 | int | 288 | int |
286 | EXTRACTOR_real_extract (const unsigned char *data, | 289 | EXTRACTOR_real_extract (const unsigned char *data, |
287 | size_t size, | 290 | size_t size, |
288 | EXTRACTOR_MetaDataProcessor proc, | 291 | EXTRACTOR_MetaDataProcessor proc, |
289 | void *proc_cls, | 292 | void *proc_cls, |
290 | const char *options) | 293 | const char *options) |
291 | { | 294 | { |
292 | const unsigned char *pos; | 295 | const unsigned char *pos; |
293 | const unsigned char *end; | 296 | const unsigned char *end; |
@@ -303,132 +306,134 @@ EXTRACTOR_real_extract (const unsigned char *data, | |||
303 | if (size <= 2 * sizeof (int)) | 306 | if (size <= 2 * sizeof (int)) |
304 | return 0; | 307 | return 0; |
305 | if (RAFF4_HEADER == ntohl (*(int *) data)) | 308 | if (RAFF4_HEADER == ntohl (*(int *) data)) |
309 | { | ||
310 | /* HELIX */ | ||
311 | if (size <= RAFF4_HDR_SIZE + 16 + 4) | ||
312 | return 0; | ||
313 | if (0 != proc (proc_cls, | ||
314 | "real", | ||
315 | EXTRACTOR_METATYPE_MIMETYPE, | ||
316 | EXTRACTOR_METAFORMAT_UTF8, | ||
317 | "text/plain", | ||
318 | "audio/vnd.rn-realaudio", | ||
319 | strlen ("audio/vnd.rn-realaudio") + 1)) | ||
320 | return 1; | ||
321 | hdr = (const RAFF4_header *) &data[16]; | ||
322 | if (ntohs (hdr->header_length) + 16 > size) | ||
323 | return 0; | ||
324 | tlen = data[16 + RAFF4_HDR_SIZE]; | ||
325 | if (tlen + RAFF4_HDR_SIZE + 20 > size) | ||
326 | return 0; | ||
327 | alen = data[17 + tlen + RAFF4_HDR_SIZE]; | ||
328 | if (tlen + alen + RAFF4_HDR_SIZE + 20 > size) | ||
329 | return 0; | ||
330 | clen = data[18 + tlen + alen + RAFF4_HDR_SIZE]; | ||
331 | if (tlen + alen + clen + RAFF4_HDR_SIZE + 20 > size) | ||
332 | return 0; | ||
333 | aplen = data[19 + tlen + clen + alen + RAFF4_HDR_SIZE]; | ||
334 | if (tlen + alen + clen + aplen + RAFF4_HDR_SIZE + 20 > size) | ||
335 | return 0; | ||
336 | ret = 0; | ||
337 | if ( (tlen > 0) && (ret == 0) ) | ||
306 | { | 338 | { |
307 | /* HELIX */ | 339 | x = stndup ((const char *) &data[17 + RAFF4_HDR_SIZE], tlen); |
308 | if (size <= RAFF4_HDR_SIZE + 16 + 4) | 340 | if (x != NULL) |
309 | return 0; | 341 | { |
310 | if (0 != proc (proc_cls, | 342 | ret = proc (proc_cls, |
311 | "real", | 343 | "real", |
312 | EXTRACTOR_METATYPE_MIMETYPE, | 344 | EXTRACTOR_METATYPE_MIMETYPE, |
313 | EXTRACTOR_METAFORMAT_UTF8, | 345 | EXTRACTOR_METAFORMAT_UTF8, |
314 | "text/plain", | 346 | "text/plain", |
315 | "audio/vnd.rn-realaudio", | 347 | x, |
316 | strlen ("audio/vnd.rn-realaudio")+1)) | 348 | strlen (x) + 1); |
317 | return 1; | 349 | free (x); |
318 | hdr = (const RAFF4_header *) &data[16]; | 350 | } |
319 | if (ntohs (hdr->header_length) + 16 > size) | ||
320 | return 0; | ||
321 | tlen = data[16 + RAFF4_HDR_SIZE]; | ||
322 | if (tlen + RAFF4_HDR_SIZE + 20 > size) | ||
323 | return 0; | ||
324 | alen = data[17 + tlen + RAFF4_HDR_SIZE]; | ||
325 | if (tlen + alen + RAFF4_HDR_SIZE + 20 > size) | ||
326 | return 0; | ||
327 | clen = data[18 + tlen + alen + RAFF4_HDR_SIZE]; | ||
328 | if (tlen + alen + clen + RAFF4_HDR_SIZE + 20 > size) | ||
329 | return 0; | ||
330 | aplen = data[19 + tlen + clen + alen + RAFF4_HDR_SIZE]; | ||
331 | if (tlen + alen + clen + aplen + RAFF4_HDR_SIZE + 20 > size) | ||
332 | return 0; | ||
333 | ret = 0; | ||
334 | if ( (tlen > 0) && (ret == 0) ) | ||
335 | { | ||
336 | x = stndup ((const char *) &data[17 + RAFF4_HDR_SIZE], tlen); | ||
337 | if (x != NULL) | ||
338 | { | ||
339 | ret = proc (proc_cls, | ||
340 | "real", | ||
341 | EXTRACTOR_METATYPE_MIMETYPE, | ||
342 | EXTRACTOR_METAFORMAT_UTF8, | ||
343 | "text/plain", | ||
344 | x, | ||
345 | strlen (x)+1); | ||
346 | free (x); | ||
347 | } | ||
348 | } | ||
349 | if ( (alen > 0) && (ret == 0) ) | ||
350 | { | ||
351 | x = stndup ((const char *) &data[18 + RAFF4_HDR_SIZE + tlen], alen); | ||
352 | if (x != NULL) | ||
353 | { | ||
354 | ret = proc (proc_cls, | ||
355 | "real", | ||
356 | EXTRACTOR_METATYPE_MIMETYPE, | ||
357 | EXTRACTOR_METAFORMAT_UTF8, | ||
358 | "text/plain", | ||
359 | x, | ||
360 | strlen (x)+1); | ||
361 | free (x); | ||
362 | } | ||
363 | } | ||
364 | if ( (clen > 0) && (ret == 0) ) | ||
365 | { | ||
366 | x = stndup ((const char *) &data[19 + RAFF4_HDR_SIZE + tlen + alen], clen); | ||
367 | if (x != NULL) | ||
368 | { | ||
369 | ret = proc (proc_cls, | ||
370 | "real", | ||
371 | EXTRACTOR_METATYPE_MIMETYPE, | ||
372 | EXTRACTOR_METAFORMAT_UTF8, | ||
373 | "text/plain", | ||
374 | x, | ||
375 | strlen (x)+1); | ||
376 | free (x); | ||
377 | } | ||
378 | } | ||
379 | if ( (aplen > 0) && (ret == 0) ) | ||
380 | { | ||
381 | x = stndup ((const char *) &data[20 + RAFF4_HDR_SIZE + tlen + alen + clen], aplen); | ||
382 | if (x != NULL) | ||
383 | { | ||
384 | ret = proc (proc_cls, | ||
385 | "real", | ||
386 | EXTRACTOR_METATYPE_MIMETYPE, | ||
387 | EXTRACTOR_METAFORMAT_UTF8, | ||
388 | "text/plain", | ||
389 | x, | ||
390 | strlen (x)+1); | ||
391 | free (x); | ||
392 | } | ||
393 | } | ||
394 | return ret; | ||
395 | } | 351 | } |
352 | if ( (alen > 0) && (ret == 0) ) | ||
353 | { | ||
354 | x = stndup ((const char *) &data[18 + RAFF4_HDR_SIZE + tlen], alen); | ||
355 | if (x != NULL) | ||
356 | { | ||
357 | ret = proc (proc_cls, | ||
358 | "real", | ||
359 | EXTRACTOR_METATYPE_MIMETYPE, | ||
360 | EXTRACTOR_METAFORMAT_UTF8, | ||
361 | "text/plain", | ||
362 | x, | ||
363 | strlen (x) + 1); | ||
364 | free (x); | ||
365 | } | ||
366 | } | ||
367 | if ( (clen > 0) && (ret == 0) ) | ||
368 | { | ||
369 | x = stndup ((const char *) &data[19 + RAFF4_HDR_SIZE + tlen + alen], | ||
370 | clen); | ||
371 | if (x != NULL) | ||
372 | { | ||
373 | ret = proc (proc_cls, | ||
374 | "real", | ||
375 | EXTRACTOR_METATYPE_MIMETYPE, | ||
376 | EXTRACTOR_METAFORMAT_UTF8, | ||
377 | "text/plain", | ||
378 | x, | ||
379 | strlen (x) + 1); | ||
380 | free (x); | ||
381 | } | ||
382 | } | ||
383 | if ( (aplen > 0) && (ret == 0) ) | ||
384 | { | ||
385 | x = stndup ((const char *) &data[20 + RAFF4_HDR_SIZE + tlen + alen | ||
386 | + clen], aplen); | ||
387 | if (x != NULL) | ||
388 | { | ||
389 | ret = proc (proc_cls, | ||
390 | "real", | ||
391 | EXTRACTOR_METATYPE_MIMETYPE, | ||
392 | EXTRACTOR_METAFORMAT_UTF8, | ||
393 | "text/plain", | ||
394 | x, | ||
395 | strlen (x) + 1); | ||
396 | free (x); | ||
397 | } | ||
398 | } | ||
399 | return ret; | ||
400 | } | ||
396 | if (REAL_HEADER == ntohl (*(int *) data)) | 401 | if (REAL_HEADER == ntohl (*(int *) data)) |
402 | { | ||
403 | /* old real */ | ||
404 | end = &data[size]; | ||
405 | pos = &data[0]; | ||
406 | ret = 0; | ||
407 | while (0 == ret) | ||
397 | { | 408 | { |
398 | /* old real */ | 409 | if ((pos + 8 >= end) || (pos + 8 < pos)) |
399 | end = &data[size]; | 410 | break; |
400 | pos = &data[0]; | 411 | length = ntohl (*(((unsigned int *) pos) + 1)); |
401 | ret = 0; | 412 | if (length <= 0) |
402 | while (0 == ret) | 413 | break; |
403 | { | 414 | if ((pos + length >= end) || (pos + length < pos)) |
404 | if ((pos + 8 >= end) || (pos + 8 < pos)) | 415 | break; |
405 | break; | 416 | switch (ntohl (*((unsigned int *) pos))) |
406 | length = ntohl (*(((unsigned int *) pos) + 1)); | 417 | { |
407 | if (length <= 0) | 418 | case MDPR_HEADER: |
408 | break; | 419 | ret = processMediaProperties ((Media_Properties *) pos, |
409 | if ((pos + length >= end) || (pos + length < pos)) | 420 | proc, |
410 | break; | 421 | proc_cls); |
411 | switch (ntohl (*((unsigned int *) pos))) | 422 | pos += length; |
412 | { | 423 | break; |
413 | case MDPR_HEADER: | 424 | case CONT_HEADER: |
414 | ret = processMediaProperties ((Media_Properties *) pos, | 425 | ret = processContentDescription ((Content_Description *) pos, |
415 | proc, | 426 | proc, |
416 | proc_cls); | 427 | proc_cls); |
417 | pos += length; | 428 | pos += length; |
418 | break; | 429 | break; |
419 | case CONT_HEADER: | 430 | case REAL_HEADER: /* treat like default */ |
420 | ret = processContentDescription ((Content_Description *) pos, | 431 | default: |
421 | proc, | 432 | pos += length; |
422 | proc_cls); | 433 | break; |
423 | pos += length; | 434 | } |
424 | break; | ||
425 | case REAL_HEADER: /* treat like default */ | ||
426 | default: | ||
427 | pos += length; | ||
428 | break; | ||
429 | } | ||
430 | } | ||
431 | return ret; | ||
432 | } | 435 | } |
436 | return ret; | ||
437 | } | ||
433 | return 0; | 438 | return 0; |
434 | } | 439 | } |