From 4eadb8a704a3fe895224d94d4de3fed7cd9cc191 Mon Sep 17 00:00:00 2001 From: erankor Date: Mon, 11 Jun 2018 13:12:27 +0300 Subject: [PATCH] mkv - truncate the element size instead of failing some elements (e.g. cluster) may not be read in full when processing a segment. --- vod/mkv/ebml.c | 30 +++++++++++++++++++----------- vod/mkv/ebml.h | 5 ++++- vod/mkv/mkv_format.c | 8 ++++---- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/vod/mkv/ebml.c b/vod/mkv/ebml.c index e1970249..c653f222 100644 --- a/vod/mkv/ebml.c +++ b/vod/mkv/ebml.c @@ -97,9 +97,10 @@ ebml_read_num(ebml_context_t* context, uint64_t* result, size_t max_size, int re } static vod_status_t -ebml_read_size(ebml_context_t* context, uint64_t* result) +ebml_read_size(ebml_context_t* context, bool_t truncate, uint64_t* result) { vod_status_t rc; + uint64_t size_left; rc = ebml_read_num(context, result, 8, 1); if (rc < 0) @@ -109,16 +110,22 @@ ebml_read_size(ebml_context_t* context, uint64_t* result) return rc; } + size_left = context->end_pos - context->cur_pos; if (is_unknown_size(*result, rc)) { - *result = context->end_pos - context->cur_pos; + *result = size_left; } - else if (*result > (uint64_t)(context->end_pos - context->cur_pos)) + else if (*result > size_left) { - vod_log_error(VOD_LOG_ERR, context->request_context->log, 0, - "ebml_read_size: size %uL greater than the remaining stream bytes %uL", - *result, (uint64_t)(context->end_pos - context->cur_pos)); - return VOD_BAD_DATA; + if (!truncate) + { + vod_log_error(VOD_LOG_ERR, context->request_context->log, 0, + "ebml_read_size: size %uL greater than the remaining stream bytes %uL", + *result, size_left); + return VOD_BAD_DATA; + } + + *result = size_left; } return VOD_OK; @@ -192,11 +199,12 @@ ebml_parse_element(ebml_context_t* context, ebml_spec_t* spec, void* dest) ebml_context_t next_context; uint64_t max_size; uint64_t size; + uint32_t type = spec->type & EBML_TYPE_MASK; void* cur_dest; vod_status_t rc; // size - rc = ebml_read_size(context, &size); + rc = ebml_read_size(context, spec->type & EBML_TRUNCATE, &size); if (rc != VOD_OK) { vod_log_debug1(VOD_LOG_DEBUG_LEVEL, context->request_context->log, 0, @@ -204,13 +212,13 @@ ebml_parse_element(ebml_context_t* context, ebml_spec_t* spec, void* dest) return rc; } - if (spec->type == EBML_NONE) + if (type == EBML_NONE) { context->cur_pos += size; return VOD_OK; } - max_size = ebml_max_sizes[spec->type]; + max_size = ebml_max_sizes[type]; if (max_size && size > max_size) { vod_log_error(VOD_LOG_ERR, context->request_context->log, 0, @@ -220,7 +228,7 @@ ebml_parse_element(ebml_context_t* context, ebml_spec_t* spec, void* dest) cur_dest = (u_char*)dest + spec->offset; - switch (spec->type) + switch (type) { case EBML_UINT: rc = ebml_read_uint(context, size, cur_dest); diff --git a/vod/mkv/ebml.h b/vod/mkv/ebml.h index 907d9ad4..8f0f2020 100644 --- a/vod/mkv/ebml.h +++ b/vod/mkv/ebml.h @@ -16,6 +16,9 @@ typedef enum { EBML_BINARY, EBML_MASTER, EBML_CUSTOM, + + EBML_TYPE_MASK = 0x00ffffff, + EBML_TRUNCATE = 0x01000000, } ebml_type_t; typedef struct { @@ -26,7 +29,7 @@ typedef struct { typedef struct { uint32_t id; - ebml_type_t type; + uint32_t type; off_t offset; void* child; } ebml_spec_t; diff --git a/vod/mkv/mkv_format.c b/vod/mkv/mkv_format.c index 032769b4..702eebb9 100644 --- a/vod/mkv/mkv_format.c +++ b/vod/mkv/mkv_format.c @@ -144,23 +144,23 @@ static ebml_spec_t mkv_spec_index[] = { // cluster static ebml_spec_t mkv_spec_cluster_fields[] = { { MKV_ID_CLUSTERTIMECODE, EBML_UINT, offsetof(mkv_cluster_t, timecode), NULL }, - { MKV_ID_SIMPLEBLOCK, EBML_CUSTOM, 0, mkv_parse_frame }, + { MKV_ID_SIMPLEBLOCK, EBML_CUSTOM | EBML_TRUNCATE, 0, mkv_parse_frame }, { 0, EBML_NONE, 0, NULL } }; static ebml_spec_t mkv_spec_cluster[] = { - { MKV_ID_CLUSTER, EBML_MASTER, 0, mkv_spec_cluster_fields }, + { MKV_ID_CLUSTER, EBML_MASTER | EBML_TRUNCATE, 0, mkv_spec_cluster_fields }, { 0, EBML_NONE, 0, NULL } }; static ebml_spec_t mkv_spec_bitrate_estimate_cluster_fields[] = { { MKV_ID_CLUSTERTIMECODE, EBML_UINT, offsetof(mkv_cluster_t, timecode), NULL }, - { MKV_ID_SIMPLEBLOCK, EBML_CUSTOM, 0, mkv_parse_frame_estimate_bitrate }, + { MKV_ID_SIMPLEBLOCK, EBML_CUSTOM | EBML_TRUNCATE, 0, mkv_parse_frame_estimate_bitrate }, { 0, EBML_NONE, 0, NULL } }; static ebml_spec_t mkv_spec_bitrate_estimate_cluster[] = { - { MKV_ID_CLUSTER, EBML_MASTER, 0, mkv_spec_bitrate_estimate_cluster_fields }, + { MKV_ID_CLUSTER, EBML_MASTER | EBML_TRUNCATE, 0, mkv_spec_bitrate_estimate_cluster_fields }, { 0, EBML_NONE, 0, NULL } };