Handle indefinite elements

This commit is contained in:
Mid 2025-10-07 12:27:21 +03:00
parent 8b0fbfdcf7
commit e0716abc81
2 changed files with 24 additions and 2 deletions

View File

@ -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,7 +162,9 @@ int ebml_reader_feed(EBMLReader *this, const uint8_t *data, size_t length) {
}
for(int i = 0; i < this->currentDepth; i++) {
this->stack[i] -= eaten;
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;
}
}
}

View File

@ -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