sbase

suckless unix tools
git clone git://git.2f30.org/sbase.git
Log | Files | Refs | README | LICENSE

commit 2116ce06806406b1aac5be1a021be1b14c93329e
parent 58ed21f49d777924be808f8f53d70415060fa14a
Author: sin <sin@2f30.org>
Date:   Mon Apr 20 16:29:21 +0100

Fix tar(1) handling of <space> terminated fields

Numeric fields can be <space> terminated.  Ensure those are
patched with NULs so we can perform string operations.

There is more work to be done in this area, namely some fields like
name, linkname and prefix are not always null-terminated.

Diffstat:
tar.c | 28++++++++++++++++++++++++++++
1 file changed, 28 insertions(+), 0 deletions(-)
diff --git a/tar.c b/tar.c @@ -280,6 +280,33 @@ c(const char *path, struct stat *st, void *data, struct recursor *r) } static void +sanitize(struct header *h) +{ + size_t i, j; + struct { + char *f; + size_t l; + } fields[] = { + { h->mode, sizeof(h->mode) }, + { h->uid, sizeof(h->uid) }, + { h->gid, sizeof(h->gid) }, + { h->size, sizeof(h->size) }, + { h->mtime, sizeof(h->mtime) }, + { h->chksum, sizeof(h->chksum) }, + { h->major, sizeof(h->major) }, + { h->minor, sizeof(h->minor) } + }; + + /* Numeric fields can be terminated with spaces instead of + * NULs as per the ustar specification. Patch all of them to + * use NULs so we can perform string operations on them. */ + for (i = 0; i < LEN(fields); i++) + for (j = 0; j < fields[i].l; j++) + if (fields[i].f[j] == ' ') + fields[i].f[j] = '\0'; +} + +static void xt(int (*fn)(char *, ssize_t, char[BLKSIZ])) { struct header *h; @@ -289,6 +316,7 @@ xt(int (*fn)(char *, ssize_t, char[BLKSIZ])) h = (void *)b; while (fread(b, BLKSIZ, 1, tarfile) == 1 && *(h->name)) { + sanitize(h); fname[0] = '\0'; if (*(h->prefix)) { estrlcat(fname, h->prefix, sizeof(fname));