diff options
author | Damien Zammit <damien@zamaudio.com> | 2019-06-22 17:15:10 +1000 |
---|---|---|
committer | Damien Zammit <damien@zamaudio.com> | 2019-06-22 17:15:56 +1000 |
commit | 6240b87cc8639d8402049fdccef2214286d6e0e3 (patch) | |
tree | 0eb48da2e05482932ffd20faef4f295bdc0210e6 | |
parent | ea2a1744a6aeb8d4411586de524952209c263c2f (diff) |
Remove nesting limit && fix wasted time recursively scanning regions with no children
-rw-r--r-- | ptformat.cc | 18 | ||||
-rw-r--r-- | ptformat/ptformat.h | 2 |
2 files changed, 10 insertions, 10 deletions
diff --git a/ptformat.cc b/ptformat.cc index 2fdc2db..b6b13b7 100644 --- a/ptformat.cc +++ b/ptformat.cc @@ -566,25 +566,25 @@ PTFFormat::setrates(void) { } bool -PTFFormat::parse_block_at(uint32_t pos, struct block_t *block, int level) { +PTFFormat::parse_block_at(uint32_t pos, struct block_t *block, struct block_t *parent, int level) { struct block_t b; int childjump = 0; uint32_t i; + uint32_t max = _len; - if (pos + 7 > _len) - return false; - if (level > 5) - return false; if (_ptfunxored[pos] != ZMARK) return false; + if (parent) + max = parent->block_size + parent->offset; + b.zmark = ZMARK; b.block_type = u_endian_read2(&_ptfunxored[pos+1], is_bigendian); b.block_size = u_endian_read4(&_ptfunxored[pos+3], is_bigendian); b.content_type = u_endian_read2(&_ptfunxored[pos+7], is_bigendian); b.offset = pos + 7; - if (b.block_size + b.offset > _len) + if (b.block_size + b.offset > max) return false; if (b.block_type & 0xff00) return false; @@ -596,11 +596,11 @@ PTFFormat::parse_block_at(uint32_t pos, struct block_t *block, int level) { block->offset = b.offset; memset(&block->child, 0, sizeof(block->child)); - for (i = 1; (i < block->block_size) && (pos + i + childjump < _len); i += childjump ? childjump : 1) { + for (i = 1; (i < block->block_size) && (pos + i + childjump < max); i += childjump ? childjump : 1) { int p = pos + i; struct block_t bchild; childjump = 0; - if (parse_block_at(p, &bchild, level+1)) { + if (parse_block_at(p, &bchild, block, level+1)) { block->child.push_back(bchild); childjump = bchild.block_size + 7; } @@ -661,7 +661,7 @@ PTFFormat::parseblocks(void) { while (i < _len) { struct block_t b; - if (parse_block_at(i, &b, 0)) { + if (parse_block_at(i, &b, NULL, 0)) { blocks.push_back(b); } i += b.block_size ? b.block_size + 7 : 1; diff --git a/ptformat/ptformat.h b/ptformat/ptformat.h index 4b0e8bd..43b4dc1 100644 --- a/ptformat/ptformat.h +++ b/ptformat/ptformat.h @@ -267,7 +267,7 @@ private: bool parseaudio(void); bool parsemidi(void); void dump(void); - bool parse_block_at(uint32_t pos, struct block_t *b, int level); + bool parse_block_at(uint32_t pos, struct block_t *b, struct block_t *parent, int level); void dump_block(struct block_t& b, int level); bool parse_version(); void parse_region_info(uint32_t j, block_t& blk, region_t& r); |