From 92e2c77a5b5eeabc3252ea90953ab6bd1a8944d1 Mon Sep 17 00:00:00 2001
From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Date: Wed, 8 Feb 2023 14:08:34 +0100
Subject: libtar: remove need for skip_padding function

In the istream implementation, automatically skip the padding when we
reach end-of-file. Also skip file AND padding when we destroy the
object. Replace the remaining instances with a simple istream_skip
instead and remove the wrapper from libtar.

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
---
 lib/tar/src/istream.c            | 22 ++++++++++++++++++++--
 lib/tar/src/read_header.c        |  7 -------
 lib/tar/src/record_to_memory.c   |  6 ++++--
 lib/tar/test/tar_istream2.c      |  4 ----
 lib/tar/test/tar_target_filled.c |  4 ++--
 5 files changed, 26 insertions(+), 17 deletions(-)

(limited to 'lib/tar')

diff --git a/lib/tar/src/istream.c b/lib/tar/src/istream.c
index 30b8a34..80519b1 100644
--- a/lib/tar/src/istream.c
+++ b/lib/tar/src/istream.c
@@ -28,6 +28,7 @@ typedef struct {
 	sqfs_u64 file_size;
 	sqfs_u64 offset;
 
+	size_t padding;
 	size_t last_chunk;
 	bool last_sparse;
 
@@ -83,6 +84,9 @@ static int precache(istream_t *strm)
 		strm->buffer = tar->buffer;
 		if (tar->record_size > 0)
 			goto fail_rec_sz;
+		if (istream_skip(tar->parent, tar->padding))
+			goto fail;
+		tar->padding = 0;
 		return 0;
 	}
 
@@ -105,7 +109,7 @@ static int precache(istream_t *strm)
 		if ((diff > avail) &&
 		    ((tar->parent->buffer_offset > 0) || avail == 0)) {
 			if (istream_precache(tar->parent))
-				return -1;
+				goto fail;
 
 			if (tar->parent->buffer_used == 0 && tar->parent->eof)
 				goto fail_eof;
@@ -127,10 +131,14 @@ fail_rec_sz:
 	fprintf(stderr,
 		"%s: missmatch in tar record size vs file size for `%s`.\n",
 		istream_get_filename(tar->parent), istream_get_filename(strm));
-	return -1;
+	goto fail;
 fail_eof:
 	fprintf(stderr, "%s: unexpected end-of-file while reading `%s`\n",
 		istream_get_filename(tar->parent), istream_get_filename(strm));
+	goto fail;
+fail:
+	tar->record_size = 0;
+	tar->padding = 0;
 	return -1;
 }
 
@@ -143,6 +151,12 @@ static void tar_istream_destroy(sqfs_object_t *obj)
 {
 	tar_istream_t *strm = (tar_istream_t *)obj;
 
+	if (strm->record_size > 0)
+		istream_skip(strm->parent, strm->record_size);
+
+	if (strm->padding > 0)
+		istream_skip(strm->parent, strm->padding);
+
 	sqfs_drop(strm->parent);
 	free(strm->sparse);
 	free(strm->filename);
@@ -197,6 +211,10 @@ istream_t *tar_record_istream_create(istream_t *parent,
 			goto fail_sparse;
 	}
 
+	strm->padding = hdr->record_size % 512;
+	if (strm->padding > 0)
+		strm->padding = 512 - strm->padding;
+
 	strm->record_size = hdr->record_size;
 	strm->file_size = hdr->actual_size;
 	strm->parent = sqfs_grab(parent);
diff --git a/lib/tar/src/read_header.c b/lib/tar/src/read_header.c
index 1e74841..8d3145b 100644
--- a/lib/tar/src/read_header.c
+++ b/lib/tar/src/read_header.c
@@ -292,13 +292,6 @@ fail:
 	return -1;
 }
 
-int skip_padding(istream_t *fp, sqfs_u64 size)
-{
-	size_t tail = size % 512;
-
-	return tail ? istream_skip(fp, 512 - tail) : 0;
-}
-
 int skip_entry(istream_t *fp, sqfs_u64 size)
 {
 	size_t tail = size % 512;
diff --git a/lib/tar/src/record_to_memory.c b/lib/tar/src/record_to_memory.c
index ba422de..43fd44c 100644
--- a/lib/tar/src/record_to_memory.c
+++ b/lib/tar/src/record_to_memory.c
@@ -27,8 +27,10 @@ char *record_to_memory(istream_t *fp, size_t size)
 		goto fail;
 	}
 
-	if (skip_padding(fp, size))
-		goto fail;
+	if (size % 512) {
+		if (istream_skip(fp, 512 - (size % 512)))
+			goto fail;
+	}
 
 	buffer[size] = '\0';
 	return buffer;
diff --git a/lib/tar/test/tar_istream2.c b/lib/tar/test/tar_istream2.c
index a3f27d5..e5cdca8 100644
--- a/lib/tar/test/tar_istream2.c
+++ b/lib/tar/test/tar_istream2.c
@@ -77,8 +77,6 @@ int main(int argc, char **argv)
 	ti = sqfs_drop(ti);
 	TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1);
 
-	TEST_ASSERT(skip_padding(fp, 5) == 0);
-
 	TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1);
 	TEST_ASSERT(read_header(fp, &hdr) == 0);
 	TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1);
@@ -102,8 +100,6 @@ int main(int argc, char **argv)
 	ti = sqfs_drop(ti);
 	TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1);
 
-	TEST_ASSERT(skip_padding(fp, 5) == 0);
-
 	/* "deep" directory hierarchy containg a hard link */
 	TEST_EQUAL_UI(((sqfs_object_t *)fp)->refcount, 1);
 	TEST_ASSERT(read_header(fp, &hdr) == 0);
diff --git a/lib/tar/test/tar_target_filled.c b/lib/tar/test/tar_target_filled.c
index abc6a47..e2e1798 100644
--- a/lib/tar/test/tar_target_filled.c
+++ b/lib/tar/test/tar_target_filled.c
@@ -53,7 +53,7 @@ int main(int argc, char **argv)
 	TEST_ASSERT(istream_read(fp, buffer, 5) == 5);
 	buffer[5] = '\0';
 	TEST_STR_EQUAL(buffer, "test\n");
-	TEST_ASSERT(skip_padding(fp, 5) == 0);
+	TEST_ASSERT(istream_skip(fp, 512 - 5) == 0);
 	clear_header(&hdr);
 
 	TEST_ASSERT(read_header(fp, &hdr) == 0);
@@ -65,7 +65,7 @@ int main(int argc, char **argv)
 	TEST_ASSERT(istream_read(fp, buffer, 5) == 5);
 	buffer[5] = '\0';
 	TEST_STR_EQUAL(buffer, "test\n");
-	TEST_ASSERT(skip_padding(fp, 5) == 0);
+	TEST_ASSERT(istream_skip(fp, 512 - 5) == 0);
 	clear_header(&hdr);
 
 	/* "deep" directory hierarchy containg a hard link */
-- 
cgit v1.2.3