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