header.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "header.h"
  2. #include "read.h"
  3. #include "global_elements.h"
  4. #ifdef WA_VALIDATE
  5. extern uint64_t max_id_length;
  6. extern uint64_t max_size_length;
  7. #endif
  8. // returns bytes read. 0 means EOF
  9. uint64_t nsmkv::ReadHeader(nsmkv::MKVReader *reader, uint64_t size, nsmkv::Header &header)
  10. {
  11. uint64_t total_bytes_read=0;
  12. while (size)
  13. {
  14. ebml_node node;
  15. uint64_t bytes_read = read_ebml_node(reader, &node);
  16. if (bytes_read == 0)
  17. return 0;
  18. // benski> checking bytes_read and node.size separately prevents possible integer overflow attack
  19. if (bytes_read > size)
  20. return 0;
  21. total_bytes_read+=bytes_read;
  22. size-=bytes_read;
  23. if (node.size > size)
  24. return 0;
  25. total_bytes_read+=node.size;
  26. size-=node.size;
  27. switch(node.id)
  28. {
  29. case mkv_header_doctype:
  30. {
  31. char *utf8=0;
  32. if (read_utf8(reader, node.size, &utf8) == 0)
  33. return 0;
  34. header.OwnDocType(utf8);
  35. #ifdef WA_VALIDATE
  36. header.doctype_found = true;
  37. printf(" DocType: %s\n", header.doctype);
  38. #endif
  39. }
  40. break;
  41. case mkv_header_doctype_version:
  42. {
  43. uint64_t val;
  44. if (read_unsigned(reader, node.size, &val) == 0)
  45. return 0;
  46. header.doctype_version = val;
  47. #ifdef WA_VALIDATE
  48. header.doctype_version_found = true;
  49. printf(" DocType Version: %I64u\n", header.doctype_version);
  50. #endif
  51. }
  52. break;
  53. case mkv_header_doctype_read_version:
  54. {
  55. uint64_t val;
  56. if (read_unsigned(reader, node.size, &val) == 0)
  57. return 0;
  58. header.doctype_read_version = val;
  59. #ifdef WA_VALIDATE
  60. header.doctype_read_version_found = true;
  61. printf(" DocType Read Version: %I64u\n", header.doctype_read_version);
  62. #endif
  63. }
  64. break;
  65. case mkv_header_ebml_version:
  66. {
  67. uint64_t val;
  68. if (read_unsigned(reader, node.size, &val) == 0)
  69. return 0;
  70. header.ebml_version = val;
  71. #ifdef WA_VALIDATE
  72. header.ebml_version_found = true;
  73. printf(" EBML Version: %I64u\n", header.ebml_version);
  74. #endif
  75. }
  76. break;
  77. case mkv_header_ebml_read_version:
  78. {
  79. uint64_t val;
  80. if (read_unsigned(reader, node.size, &val) == 0)
  81. return 0;
  82. header.ebml_read_version = val;
  83. #ifdef WA_VALIDATE
  84. header.ebml_read_version_found = true;
  85. printf(" EBML Read Version: %I64u\n", header.ebml_read_version);
  86. #endif
  87. }
  88. break;
  89. case mkv_header_ebml_max_id_length:
  90. {
  91. uint64_t val;
  92. if (read_unsigned(reader, node.size, &val) == 0)
  93. return 0;
  94. header.ebml_max_id_length = val;
  95. #ifdef WA_VALIDATE
  96. max_id_length = val;
  97. header.ebml_max_id_length_found = true;
  98. printf(" EBML Max ID Length: %I64u\n", header.ebml_max_id_length);
  99. #endif
  100. }
  101. break;
  102. case mkv_header_ebml_max_size_length:
  103. {
  104. uint64_t val;
  105. if (read_unsigned(reader, node.size, &val) == 0)
  106. return 0;
  107. header.ebml_max_size_length = val;
  108. #ifdef WA_VALIDATE
  109. max_size_length = val;
  110. header.ebml_max_size_length_found = true;
  111. printf(" EBML Max Size Length: %I64u\n", header.ebml_max_size_length);
  112. #endif
  113. }
  114. break;
  115. default:
  116. {
  117. if (ReadGlobal(reader, node.id, node.size) == 0)
  118. return 0;
  119. }
  120. }
  121. }
  122. return total_bytes_read;
  123. }