#include "header.h" #include "read.h" #include "global_elements.h" #ifdef WA_VALIDATE extern uint64_t max_id_length; extern uint64_t max_size_length; #endif // returns bytes read. 0 means EOF uint64_t nsmkv::ReadHeader(nsmkv::MKVReader *reader, uint64_t size, nsmkv::Header &header) { uint64_t total_bytes_read=0; while (size) { ebml_node node; uint64_t bytes_read = read_ebml_node(reader, &node); if (bytes_read == 0) return 0; // benski> checking bytes_read and node.size separately prevents possible integer overflow attack if (bytes_read > size) return 0; total_bytes_read+=bytes_read; size-=bytes_read; if (node.size > size) return 0; total_bytes_read+=node.size; size-=node.size; switch(node.id) { case mkv_header_doctype: { char *utf8=0; if (read_utf8(reader, node.size, &utf8) == 0) return 0; header.OwnDocType(utf8); #ifdef WA_VALIDATE header.doctype_found = true; printf(" DocType: %s\n", header.doctype); #endif } break; case mkv_header_doctype_version: { uint64_t val; if (read_unsigned(reader, node.size, &val) == 0) return 0; header.doctype_version = val; #ifdef WA_VALIDATE header.doctype_version_found = true; printf(" DocType Version: %I64u\n", header.doctype_version); #endif } break; case mkv_header_doctype_read_version: { uint64_t val; if (read_unsigned(reader, node.size, &val) == 0) return 0; header.doctype_read_version = val; #ifdef WA_VALIDATE header.doctype_read_version_found = true; printf(" DocType Read Version: %I64u\n", header.doctype_read_version); #endif } break; case mkv_header_ebml_version: { uint64_t val; if (read_unsigned(reader, node.size, &val) == 0) return 0; header.ebml_version = val; #ifdef WA_VALIDATE header.ebml_version_found = true; printf(" EBML Version: %I64u\n", header.ebml_version); #endif } break; case mkv_header_ebml_read_version: { uint64_t val; if (read_unsigned(reader, node.size, &val) == 0) return 0; header.ebml_read_version = val; #ifdef WA_VALIDATE header.ebml_read_version_found = true; printf(" EBML Read Version: %I64u\n", header.ebml_read_version); #endif } break; case mkv_header_ebml_max_id_length: { uint64_t val; if (read_unsigned(reader, node.size, &val) == 0) return 0; header.ebml_max_id_length = val; #ifdef WA_VALIDATE max_id_length = val; header.ebml_max_id_length_found = true; printf(" EBML Max ID Length: %I64u\n", header.ebml_max_id_length); #endif } break; case mkv_header_ebml_max_size_length: { uint64_t val; if (read_unsigned(reader, node.size, &val) == 0) return 0; header.ebml_max_size_length = val; #ifdef WA_VALIDATE max_size_length = val; header.ebml_max_size_length_found = true; printf(" EBML Max Size Length: %I64u\n", header.ebml_max_size_length); #endif } break; default: { if (ReadGlobal(reader, node.id, node.size) == 0) return 0; } } } return total_bytes_read; }