From 18275733975c23b93419fbce7ca3105e6638786d Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Mon, 10 Aug 2020 11:08:12 +0200 Subject: Fix block processor single block with don't fragment flag bug This commit fixes a bug where the block processor state machine would not add the "last block" flag if there is only one not entirely filled block and the "don't fragment" flag is set. If the flag isn't set, the inode start block position is not updated and points to the beginning of the image instead. Signed-off-by: David Oberhollenzer --- lib/sqfs/block_processor/frontend.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/sqfs/block_processor/frontend.c b/lib/sqfs/block_processor/frontend.c index daf12e7..f6aeffa 100644 --- a/lib/sqfs/block_processor/frontend.c +++ b/lib/sqfs/block_processor/frontend.c @@ -43,14 +43,6 @@ static int flush_block(sqfs_block_processor_t *proc) proc->blk_current = NULL; - if (block->size < proc->max_block_size && - !(block->flags & SQFS_BLK_DONT_FRAGMENT)) { - block->flags |= SQFS_BLK_IS_FRAGMENT; - } else { - proc->blk_flags &= ~SQFS_BLK_FIRST_BLOCK; - } - - block->index = proc->blk_index++; return proc->append_to_work_queue(proc, block); } @@ -107,6 +99,8 @@ int sqfs_block_processor_append(sqfs_block_processor_t *proc, const void *data, proc->blk_current->flags = proc->blk_flags; proc->blk_current->inode = proc->inode; proc->blk_current->user = proc->user; + proc->blk_current->index = proc->blk_index++; + proc->blk_flags &= ~SQFS_BLK_FIRST_BLOCK; } diff = proc->max_block_size - proc->blk_current->size; @@ -146,18 +140,26 @@ int sqfs_block_processor_end_file(sqfs_block_processor_t *proc) if (!proc->begin_called) return SQFS_ERROR_SEQUENCE; - if (!(proc->blk_flags & SQFS_BLK_FIRST_BLOCK)) { - if (proc->blk_current != NULL && - (proc->blk_flags & SQFS_BLK_DONT_FRAGMENT)) { - proc->blk_current->flags |= SQFS_BLK_LAST_BLOCK; - } else { + if (proc->blk_current == NULL) { + if (!(proc->blk_flags & SQFS_BLK_FIRST_BLOCK)) { err = add_sentinel_block(proc); if (err) return err; } - } + } else { + if (proc->blk_flags & SQFS_BLK_DONT_FRAGMENT) { + proc->blk_current->flags |= SQFS_BLK_LAST_BLOCK; + } else { + if (!(proc->blk_current->flags & + SQFS_BLK_FIRST_BLOCK)) { + err = add_sentinel_block(proc); + if (err) + return err; + } + + proc->blk_current->flags |= SQFS_BLK_IS_FRAGMENT; + } - if (proc->blk_current != NULL) { err = flush_block(proc); if (err) return err; -- cgit v1.2.3