aboutsummaryrefslogtreecommitdiff
path: root/Src/nsmkv/header.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/nsmkv/header.cpp')
-rw-r--r--Src/nsmkv/header.cpp138
1 files changed, 138 insertions, 0 deletions
diff --git a/Src/nsmkv/header.cpp b/Src/nsmkv/header.cpp
new file mode 100644
index 00000000..e67297a7
--- /dev/null
+++ b/Src/nsmkv/header.cpp
@@ -0,0 +1,138 @@
+#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;
+}