mirror of
https://github.com/jakcron/nstool
synced 2024-11-15 02:06:40 +00:00
[nstool] Fix critical bug in HashTreeWrappedIFile (bumped to v1.0.5)
This commit is contained in:
parent
8bb759292d
commit
3716bf0b82
3 changed files with 38 additions and 35 deletions
|
@ -34,7 +34,7 @@ else
|
|||
endif
|
||||
|
||||
BIN_DIR = bin
|
||||
OUTPUT = $(BIN_DIR)/$(shell basename $(CURDIR))
|
||||
OUTPUT = $(BIN_DIR)/$(shell basename "$(CURDIR)")
|
||||
|
||||
all: build
|
||||
|
||||
|
|
|
@ -23,45 +23,49 @@ void HashTreeWrappedIFile::seek(size_t offset)
|
|||
|
||||
void HashTreeWrappedIFile::read(byte_t* out, size_t len)
|
||||
{
|
||||
size_t offset_in_start_block = getOffsetInBlock(mDataOffset);
|
||||
size_t offset_in_end_block = getOffsetInBlock(offset_in_start_block + len);
|
||||
|
||||
size_t start_block = getOffsetBlock(mDataOffset);
|
||||
size_t block_num = align(offset_in_start_block + len, mDataBlockSize) / mDataBlockSize;
|
||||
|
||||
size_t partial_last_block_num = block_num % mCacheBlockNum;
|
||||
bool has_partial_block_num = partial_last_block_num > 0;
|
||||
size_t read_iterations = (block_num / mCacheBlockNum) + has_partial_block_num;
|
||||
|
||||
size_t block_read_len;
|
||||
size_t block_export_offset;
|
||||
size_t block_export_size;
|
||||
size_t block_export_pos = 0;
|
||||
for (size_t i = 0; i < read_iterations; i++)
|
||||
struct sBlockPosition
|
||||
{
|
||||
// how many blocks to read from source file
|
||||
block_read_len = (i+1 == read_iterations && has_partial_block_num) ? partial_last_block_num : mCacheBlockNum;
|
||||
size_t index;
|
||||
size_t pos;
|
||||
} start_blk, end_blk;
|
||||
|
||||
// offset in this current read to copy from
|
||||
block_export_offset = (i == 0) ? offset_in_start_block : 0;
|
||||
start_blk.index = getOffsetBlock(mDataOffset);
|
||||
start_blk.pos = getOffsetInBlock(mDataOffset);
|
||||
|
||||
// size of current read to copy
|
||||
block_export_size = (block_read_len * mDataBlockSize) - block_export_offset;
|
||||
|
||||
// if last read, reduce the export size by one block less offset_in_end_block
|
||||
if (i+1 == read_iterations)
|
||||
end_blk.index = getOffsetBlock(mDataOffset + len);
|
||||
end_blk.pos = getOffsetInBlock(mDataOffset + len);
|
||||
if (end_blk.pos == 0 && len != 0)
|
||||
{
|
||||
block_export_size -= (mDataBlockSize - offset_in_end_block);
|
||||
end_blk.index -= 1;
|
||||
end_blk.pos = mDataBlockSize;
|
||||
}
|
||||
|
||||
// read the blocks
|
||||
readData(start_block + (i * mCacheBlockNum), block_read_len);
|
||||
size_t total_blk_num = (end_blk.index - start_blk.index) + 1;
|
||||
|
||||
// export the section of data that is relevant
|
||||
memcpy(out + block_export_pos, mCache.data() + block_export_offset, block_export_size);
|
||||
size_t read_blk_num = 0;
|
||||
size_t cache_export_start_pos, cache_export_end_pos, cache_export_size;
|
||||
size_t export_pos = 0;
|
||||
for (size_t i = 0; i < total_blk_num; i += read_blk_num, export_pos += cache_export_size)
|
||||
{
|
||||
read_blk_num = _MIN(mCacheBlockNum, (total_blk_num - i));
|
||||
readData(start_blk.index + i, read_blk_num);
|
||||
|
||||
// update export position
|
||||
block_export_pos += block_export_size;
|
||||
// if this is the first read, adjust offset
|
||||
if (i == 0)
|
||||
cache_export_start_pos = start_blk.pos;
|
||||
else
|
||||
cache_export_start_pos = 0;
|
||||
|
||||
// if this is the last block, adjust end offset
|
||||
if ((i + read_blk_num) == total_blk_num)
|
||||
cache_export_end_pos = ((read_blk_num - 1) * mDataBlockSize) + end_blk.pos;
|
||||
else
|
||||
cache_export_end_pos = read_blk_num * mDataBlockSize;
|
||||
|
||||
// determine cache export size
|
||||
cache_export_size = cache_export_end_pos - cache_export_start_pos;
|
||||
|
||||
memcpy(out + export_pos, mCache.data() + cache_export_start_pos, cache_export_size);
|
||||
}
|
||||
|
||||
// update offset
|
||||
|
@ -150,7 +154,6 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr)
|
|||
|
||||
void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num)
|
||||
{
|
||||
(*mData)->seek(block_offset * mDataBlockSize);
|
||||
fnd::sha::sSha256Hash hash;
|
||||
|
||||
// determine read size
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
#define BIN_NAME "nstool"
|
||||
#define VER_MAJOR 1
|
||||
#define VER_MINOR 0
|
||||
#define VER_PATCH 4
|
||||
#define VER_PATCH 5
|
||||
#define AUTHORS "jakcron"
|
Loading…
Reference in a new issue