1 /*
2 * Copyright (C) 2000-2018 the xine project
3 *
4 * This file is part of xine, a free video player.
5 *
6 * xine 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 * xine 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 * EBML parser
21 * a lot of ideas from the gstreamer parser
22 */
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <string.h>
28
29 #define LOG_MODULE "ebml"
30 #define LOG_VERBOSE
31 /*
32 #define LOG
33 */
34 #include <xine/xine_internal.h>
35 #include <xine/xineutils.h>
36 #include "bswap.h"
37
38 #include "ebml.h"
39
40
new_ebml_parser(xine_t * xine,input_plugin_t * input)41 ebml_parser_t *new_ebml_parser (xine_t *xine, input_plugin_t *input) {
42 ebml_parser_t *ebml;
43
44 ebml = calloc(1, sizeof(ebml_parser_t));
45 if (ebml) {
46 ebml->xine = xine;
47 ebml->input = input;
48 }
49 return ebml;
50 }
51
52
dispose_ebml_parser(ebml_parser_t * ebml)53 void dispose_ebml_parser(ebml_parser_t *ebml) {
54 if (ebml) {
55 _x_freep(&ebml->doctype);
56 free(ebml);
57 }
58 }
59
60
ebml_get_next_level(ebml_parser_t * ebml,ebml_elem_t * elem)61 uint32_t ebml_get_next_level(ebml_parser_t *ebml, ebml_elem_t *elem) {
62 ebml_elem_t *parent_elem;
63
64 if (ebml->level > 0) {
65 parent_elem = &ebml->elem_stack[ebml->level - 1];
66 while (/* avoid overflows with undefined len (=UINT64_MAX) */
67 /* (elem->start + elem->len) >= (parent_elem->start + parent_elem->len) */
68 (elem->start - parent_elem->start + elem->len) >= parent_elem->len) {
69 lprintf("parent: %" PRIdMAX ", %" PRIu64 "; elem: %" PRIdMAX ", %" PRIu64 "\n",
70 (intmax_t)parent_elem->start, parent_elem->len, (intmax_t)elem->start, elem->len);
71 ebml->level--;
72 if (ebml->level == 0) break;
73 parent_elem = &ebml->elem_stack[ebml->level - 1];
74 }
75 }
76 lprintf("id: 0x%x, len: %" PRIu64 ", next_level: %d\n", elem->id, elem->len, ebml->level);
77 return ebml->level;
78 }
79
80
ebml_read_elem_id(ebml_parser_t * ebml,uint32_t * id)81 static int ebml_read_elem_id(ebml_parser_t *ebml, uint32_t *id) {
82 uint8_t data[4];
83 uint32_t mask = 0x80;
84 uint32_t value;
85 int size = 1;
86 int i;
87
88 if (ebml->input->read(ebml->input, data, 1) != 1) {
89 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
90 "ebml: read error\n");
91 return 0;
92 }
93 value = data[0];
94
95 /* compute the size of the ID (1-4 bytes)*/
96 while (size <= 4 && !(value & mask)) {
97 size++;
98 mask >>= 1;
99 }
100 if (size > 4) {
101 off_t pos = ebml->input->get_current_pos(ebml->input);
102 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
103 "ebml: invalid EBML ID size (0x%x) at position %" PRIdMAX "\n",
104 data[0], (intmax_t)pos);
105 return 0;
106 }
107
108 /* read the rest of the id */
109 if (ebml->input->read(ebml->input, data + 1, size - 1) != (size - 1)) {
110 off_t pos = ebml->input->get_current_pos(ebml->input);
111 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
112 "ebml: read error at position %" PRIdMAX "\n", (intmax_t)pos);
113 return 0;
114 }
115 for(i = 1; i < size; i++) {
116 value = (value << 8) | data[i];
117 }
118 *id = value;
119
120 return 1;
121 }
122
123
ebml_read_elem_len(ebml_parser_t * ebml,uint64_t * len)124 static int ebml_read_elem_len(ebml_parser_t *ebml, uint64_t *len) {
125 uint8_t data[8];
126 uint32_t mask = 0x80;
127 int size = 1;
128 int ff_bytes;
129 uint64_t value;
130 int i;
131
132 if (ebml->input->read(ebml->input, data, 1) != 1) {
133 off_t pos = ebml->input->get_current_pos(ebml->input);
134 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
135 "ebml: read error at position %" PRIdMAX "\n", (intmax_t)pos);
136 return 0;
137 }
138 value = data[0];
139
140 /* compute the size of the "data len" (1-8 bytes) */
141 while (size <= 8 && !(value & mask)) {
142 size++;
143 mask >>= 1;
144 }
145 if (size > 8) {
146 off_t pos = ebml->input->get_current_pos(ebml->input);
147 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
148 "ebml: Invalid EBML length size (0x%x) at position %" PRIdMAX "\n",
149 data[0], (intmax_t)pos);
150 return 0;
151 }
152
153 /* remove size bits */
154 value &= mask - 1;
155
156 /* check if the first byte is full */
157 if (value == (mask - 1))
158 ff_bytes = 1;
159 else
160 ff_bytes = 0;
161
162 /* read the rest of the len */
163 if (ebml->input->read(ebml->input, data + 1, size - 1) != (size - 1)) {
164 off_t pos = ebml->input->get_current_pos(ebml->input);
165 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
166 "ebml: read error at position %" PRIdMAX "\n", (intmax_t)pos);
167 return 0;
168 }
169 for (i = 1; i < size; i++) {
170 if (data[i] == 0xff)
171 ff_bytes++;
172 value = (value << 8) | data[i];
173 }
174
175 if (ff_bytes == size)
176 *len = -1;
177 else
178 *len = value;
179
180 return 1;
181 }
182
183
ebml_read_elem_data(ebml_parser_t * ebml,void * buf,int64_t len)184 static int ebml_read_elem_data(ebml_parser_t *ebml, void *buf, int64_t len) {
185
186 if (ebml->input->read(ebml->input, buf, len) != len) {
187 off_t pos = ebml->input->get_current_pos(ebml->input);
188 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
189 "ebml: read error at position %" PRIdMAX "\n", (intmax_t)pos);
190 return 0;
191 }
192
193 return 1;
194 }
195
196
ebml_skip(ebml_parser_t * ebml,ebml_elem_t * elem)197 int ebml_skip(ebml_parser_t *ebml, ebml_elem_t *elem) {
198 if (ebml->input->seek(ebml->input, elem->len, SEEK_CUR) < 0) {
199 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
200 "ebml: seek error (failed skipping %" PRId64 " bytes)\n", (int64_t)elem->len);
201 return 0;
202 }
203
204 return 1;
205 }
206
207
ebml_read_elem_head(ebml_parser_t * ebml,ebml_elem_t * elem)208 int ebml_read_elem_head(ebml_parser_t *ebml, ebml_elem_t *elem) {
209
210 int ret_id = ebml_read_elem_id(ebml, &elem->id);
211
212 int ret_len = ebml_read_elem_len(ebml, &elem->len);
213
214 elem->start = ebml->input->get_current_pos(ebml->input);
215
216 return (ret_id && ret_len);
217 }
218
219
ebml_read_uint(ebml_parser_t * ebml,ebml_elem_t * elem,uint64_t * num)220 int ebml_read_uint(ebml_parser_t *ebml, ebml_elem_t *elem, uint64_t *num) {
221 uint8_t data[8];
222 uint64_t size = elem->len;
223
224 if ((elem->len < 1) || (elem->len > 8)) {
225 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
226 "ebml: Invalid integer element size %" PRIu64 "\n", size);
227 return 0;
228 }
229
230 if (!ebml_read_elem_data (ebml, data, size))
231 return 0;
232
233 *num = 0;
234 while (size > 0) {
235 *num = (*num << 8) | data[elem->len - size];
236 size--;
237 }
238
239 return 1;
240 }
241
242 #if 0
243 int ebml_read_sint (ebml_parser_t *ebml, ebml_elem_t *elem, int64_t *num) {
244 uint8_t data[8];
245 uint64_t size = elem->len;
246
247 if ((elem->len < 1) || (elem->len > 8)) {
248 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
249 "ebml: Invalid integer element size %" PRIu64 "\n", size);
250 return 0;
251 }
252
253 if (!ebml_read_elem_data(ebml, data, size))
254 return 0;
255
256 /* propagate negative bit */
257 if (data[0] & 80)
258 *num = -1;
259 else
260 *num = 0;
261
262 while (size > 0) {
263 *num = (*num << 8) | data[elem->len - size];
264 size--;
265 }
266
267 return 1;
268 }
269 #endif
270
271
ebml_read_float(ebml_parser_t * ebml,ebml_elem_t * elem,double * num)272 int ebml_read_float (ebml_parser_t *ebml, ebml_elem_t *elem, double *num) {
273 uint8_t data[10];
274 uint64_t size = elem->len;
275
276 if ((size != 4) && (size != 8) && (size != 10)) {
277 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
278 "ebml: Invalid float element size %" PRIu64 "\n", size);
279 return 0;
280 }
281
282 if (!ebml_read_elem_data(ebml, data, size))
283 return 0;
284
285 if (size == 10) {
286 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
287 "ebml: FIXME! 10-byte floats unimplemented\n");
288 return 0;
289 }
290
291 if (size == 4) {
292 union {
293 float f;
294 uint32_t u32;
295 } tmp;
296 tmp.u32 = _X_BE_32(data);
297 *num = tmp.f;
298 } else {
299 union {
300 double d;
301 uint64_t u64;
302 } tmp;
303 tmp.u64 = _X_BE_64(data);
304 *num = tmp.d;
305 }
306 return 1;
307 }
308
ebml_read_ascii(ebml_parser_t * ebml,ebml_elem_t * elem,char * str)309 int ebml_read_ascii(ebml_parser_t *ebml, ebml_elem_t *elem, char *str) {
310 uint64_t size = elem->len;
311
312 if (!ebml_read_elem_data(ebml, str, size))
313 return 0;
314
315 return 1;
316 }
317
318 #if 0
319 int ebml_read_utf8 (ebml_parser_t *ebml, ebml_elem_t *elem, char *str) {
320 return ebml_read_ascii (ebml, elem, str);
321 }
322 #endif
323
ebml_alloc_read_ascii(ebml_parser_t * ebml,ebml_elem_t * elem)324 char *ebml_alloc_read_ascii (ebml_parser_t *ebml, ebml_elem_t *elem)
325 {
326 char *text;
327 if (elem->len >= 4096)
328 return NULL;
329 text = malloc(elem->len + 1);
330 if (text)
331 {
332 text[elem->len] = '\0';
333 if (ebml_read_ascii (ebml, elem, text))
334 return text;
335 free (text);
336 }
337 return NULL;
338 }
339
340 #if 0
341 int ebml_read_date (ebml_parser_t *ebml, ebml_elem_t *elem, int64_t *date) {
342 return ebml_read_sint (ebml, elem, date);
343 }
344 #endif
345
ebml_read_master(ebml_parser_t * ebml,ebml_elem_t * elem)346 int ebml_read_master (ebml_parser_t *ebml, ebml_elem_t *elem) {
347 ebml_elem_t *top_elem;
348
349 if (ebml->level < 0) {
350 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
351 "ebml: invalid current level\n");
352 return 0;
353 }
354
355 top_elem = &ebml->elem_stack[ebml->level];
356 top_elem->start = elem->start;
357 top_elem->len = elem->len;
358 top_elem->id = elem->id;
359
360 ebml->level++;
361 lprintf("id: 0x%x, len: %" PRIu64 ", level: %d\n", elem->id, elem->len, ebml->level);
362 if (ebml->level >= EBML_STACK_SIZE) {
363 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
364 "ebml: max level exceeded\n");
365 return 0;
366 }
367 return 1;
368 }
369
ebml_read_binary(ebml_parser_t * ebml,ebml_elem_t * elem,void * binary)370 int ebml_read_binary(ebml_parser_t *ebml, ebml_elem_t *elem, void *binary) {
371 return ebml_read_elem_data(ebml, binary, elem->len);
372 }
373
ebml_check_header(ebml_parser_t * ebml)374 int ebml_check_header(ebml_parser_t *ebml) {
375 uint32_t next_level;
376 ebml_elem_t master;
377
378 if (!ebml_read_elem_head(ebml, &master)) {
379 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
380 "ebml: invalid master element\n");
381 return 0;
382 }
383
384 if (master.id != EBML_ID_EBML) {
385 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
386 "ebml: invalid master element 0x%x\n", master.id);
387 return 0;
388 }
389
390 if (!ebml_read_master (ebml, &master))
391 return 0;
392
393 next_level = 1;
394 while (next_level == 1) {
395 ebml_elem_t elem;
396
397 if (!ebml_read_elem_head(ebml, &elem))
398 return 0;
399
400 switch (elem.id) {
401 case EBML_ID_EBMLVERSION: {
402 uint64_t num;
403
404 if (!ebml_read_uint (ebml, &elem, &num))
405 return 0;
406 lprintf("ebml_version: %" PRIu64 "\n", num);
407 ebml->version = num;
408 break;
409 }
410
411 case EBML_ID_EBMLREADVERSION: {
412 uint64_t num;
413
414 if (!ebml_read_uint (ebml, &elem, &num))
415 return 0;
416 lprintf("ebml_read_version: %" PRIu64 "\n", num);
417 if (num != EBML_VERSION)
418 return 0;
419 ebml->read_version = num;
420 break;
421 }
422
423 case EBML_ID_EBMLMAXIDLENGTH: {
424 uint64_t num;
425
426 if (!ebml_read_uint (ebml, &elem, &num))
427 return 0;
428 lprintf("ebml_max_id_length: %" PRIu64 "\n", num);
429 ebml->max_id_len = num;
430 break;
431 }
432
433 case EBML_ID_EBMLMAXSIZELENGTH: {
434 uint64_t num;
435
436 if (!ebml_read_uint (ebml, &elem, &num))
437 return 0;
438 lprintf("ebml_max_size_length: %" PRIu64 "\n", num);
439 ebml->max_size_len = num;
440 break;
441 }
442
443 case EBML_ID_DOCTYPE: {
444 char *text = ebml_alloc_read_ascii (ebml, &elem);
445 if (!text)
446 return 0;
447
448 lprintf("doctype: %s\n", text);
449 if (ebml->doctype)
450 free (ebml->doctype);
451 ebml->doctype = text;
452 break;
453 }
454
455 case EBML_ID_DOCTYPEVERSION: {
456 uint64_t num;
457
458 if (!ebml_read_uint (ebml, &elem, &num))
459 return 0;
460 lprintf("doctype_version: %" PRIu64 "\n", num);
461 ebml->doctype_version = num;
462 break;
463 }
464
465 case EBML_ID_DOCTYPEREADVERSION: {
466 uint64_t num;
467
468 if (!ebml_read_uint (ebml, &elem, &num))
469 return 0;
470 lprintf("doctype_read_version: %" PRIu64 "\n", num);
471 ebml->doctype_read_version = num;
472 break;
473 }
474
475 default:
476 xprintf(ebml->xine, XINE_VERBOSITY_LOG,
477 "ebml: Unknown data type 0x%x in EBML header (ignored)\n", elem.id);
478 if (!ebml_skip(ebml, &elem))
479 return 0;
480 }
481 next_level = ebml_get_next_level(ebml, &elem);
482 }
483
484 return 1;
485 }
486