Handle indefinite elements
This commit is contained in:
parent
8b0fbfdcf7
commit
e0716abc81
@ -9,6 +9,8 @@
|
||||
|
||||
#include"reader.h"
|
||||
|
||||
#define is_max(u) ((u) == 0xFFFFFFFFFFFFFFFFUL)
|
||||
|
||||
void ebml_reader_init(EBMLReader *this) {
|
||||
memset(this, 0, sizeof(*this));
|
||||
this->state = EBMLRS_WAITING_FOR_ELEMENT_ID;
|
||||
@ -89,6 +91,10 @@ static int get_varint(const uint8_t *data, size_t length, uint64_t *result) {
|
||||
|
||||
if(ret >= 0) {
|
||||
*result &= ~VARINT_MASKS[ret];
|
||||
|
||||
if(*result == (1UL << (ret * 7)) - 1) {
|
||||
*result = 0xFFFFFFFFFFFFFFFFUL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -137,7 +143,7 @@ int ebml_reader_feed(EBMLReader *this, const uint8_t *data, size_t length) {
|
||||
}
|
||||
|
||||
this->idStack[this->currentDepth] = this->inside.id;
|
||||
this->stack[this->currentDepth] = elLength + status;
|
||||
this->stack[this->currentDepth] = is_max(elLength) ? elLength : elLength + status;
|
||||
|
||||
this->currentDepth++;
|
||||
|
||||
@ -156,8 +162,10 @@ int ebml_reader_feed(EBMLReader *this, const uint8_t *data, size_t length) {
|
||||
}
|
||||
|
||||
for(int i = 0; i < this->currentDepth; i++) {
|
||||
if(!is_max(this->stack[i])) {
|
||||
this->stack[i] -= eaten;
|
||||
}
|
||||
}
|
||||
|
||||
while(this->currentDepth > 0 && this->stack[this->currentDepth - 1] == 0) {
|
||||
|
||||
@ -173,3 +181,12 @@ int ebml_reader_feed(EBMLReader *this, const uint8_t *data, size_t length) {
|
||||
|
||||
return eaten;
|
||||
}
|
||||
|
||||
void ebml_reader_leave(EBMLReader *this, uint64_t id) {
|
||||
for(int i = 0; i < this->currentDepth; i++) {
|
||||
if(this->idStack[i] == id) {
|
||||
this->currentDepth = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,11 @@ typedef struct EBMLReader {
|
||||
void ebml_reader_init(EBMLReader*);
|
||||
int ebml_reader_feed(EBMLReader*, const uint8_t *data, size_t length);
|
||||
|
||||
// Because Eebie is schemaless, it must be told when we have left an
|
||||
// indefinite element, otherwise the stack may grow indefinitely and
|
||||
// even overflow. The user may call this from eventEnterElement.
|
||||
void ebml_reader_leave(EBMLReader*, uint64_t id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user