From 59d43aadba53b164dc529cfef069c5aeb9a65807 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Fri, 31 Jan 2014 00:21:04 -0500 Subject: [PATCH] liblbx: Correct EOF handling in lbx_file_read. We should never see an EOF from the underlying I/O when reading archive members, because we setup the read request to only return bytes that are supposed to be there. So if EOF happens, flag this as an error and do *not* set the eof flag in the state structure. Also fixup lbxtool to properly handle this. --- src/lbx.c | 7 ++++++- src/lbxtool.c | 20 ++++++++++---------- tests/broken-archives.tap | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/lbx.c b/src/lbx.c index 1198ebb..f96344d 100644 --- a/src/lbx.c +++ b/src/lbx.c @@ -262,8 +262,13 @@ size_t lbx_file_read(struct lbx_file_state *f, void *buf, size_t n) rc = fops->read(buf, want, f->lbx->f); f->offset += rc; - if (want < n || (rc < want && fops->eof(f->lbx->f))) + if (rc < want) { + if (fops->eof(f->lbx->f)) + lbx_error_raise(LBX_EEOF); + } else if (rc < n) { f->eof = 1; + } + return rc; } diff --git a/src/lbxtool.c b/src/lbxtool.c index 767c309..3c4e436 100644 --- a/src/lbxtool.c +++ b/src/lbxtool.c @@ -110,19 +110,19 @@ int extract_file(LBXfile *f, const struct lbx_statbuf *stat) unsigned char buf[1024]; rc = lbx_file_read(f, buf, sizeof buf); - if (rc == 0) { - if (lbx_file_eof(f)) - ret = 0; - break; - } - - if (fwrite(buf, rc, 1, of) != 1) { - tool_err(0, "%s: fwrite", stat->name); - break; + if (rc > 0) { + /* Write out any data we got. */ + if (fwrite(buf, rc, 1, of) != 1) { + tool_err(0, "%s: fwrite", stat->name); + break; + } } + /* Now test for read errors */ if (rc < sizeof buf) { - if (lbx_file_eof(f)) + if (!lbx_file_eof(f)) + tool_err(-1, "error reading archive: %s", lbx_errmsg()); + else ret = 0; break; } diff --git a/tests/broken-archives.tap b/tests/broken-archives.tap index 3997ca3..2eacc7f 100644 --- a/tests/broken-archives.tap +++ b/tests/broken-archives.tap @@ -24,4 +24,4 @@ dx_create_testdir failed=false $LBXTOOL -xf "$testdata/arch-trunc.lbx" || failed=true -command_ok_ "EOF handled in archive" -D TODO $failed +command_ok_ "EOF handled in archive" $failed -- 2.43.0