bsdiff-portable

A more portable version of Colin Percival's bsdiff
git clone git://git.sgregoratto.me/bsdiff-portable
Log | Files | Refs | LICENSE

commit 3057fab5a8fde64f0058ef42c072925ff014f13d
parent e3951bb17974ff92e4a4c9841294e689e2f5c3c0
Author: Stephen Gregoratto <dev@sgregoratto.me>
Date:   Wed, 23 Sep 2020 20:23:11 +1000

use custom readfile function

Replaces the `if` soup that was copied a couple times.
Also replace malloc with reallocarray to check for overflow.

Diffstat:
Mbsdiff.c | 36+++++++++++-------------------------
Mbsdiff.h | 1+
Mbspatch.c | 11+++--------
Mutil.c | 34++++++++++++++++++++++++++++++++++
4 files changed, 49 insertions(+), 33 deletions(-)

diff --git a/bsdiff.c b/bsdiff.c @@ -39,14 +39,12 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bsdiff/bsdiff.c,v 1.1 2005/08/06 01:59:05 #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> #include "bsdiff.h" int main(int argc, char **argv) { - int fd; uint8_t *old, *new; off_t oldsize, newsize; off_t *I, *V; @@ -67,35 +65,23 @@ main(int argc, char **argv) if (argc != 4) usage(); - /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure - that we never try to malloc(0) and get a NULL pointer */ - if (((fd = open(argv[1], O_RDONLY, 0)) < 0) || - ((oldsize = lseek(fd, 0, SEEK_END)) == -1) || - ((old = malloc(oldsize + 1)) == NULL) || - (lseek(fd, 0, SEEK_SET) != 0) || - (read(fd, old, oldsize) != oldsize) || (close(fd) == -1)) - err(1, "%s", argv[1]); + old = readfile(argv[1], &oldsize); - if (((I = malloc((oldsize + 1) * sizeof(off_t))) == NULL) || - ((V = malloc((oldsize + 1) * sizeof(off_t))) == NULL)) - err(1, NULL); + if ((I = reallocarray(NULL, oldsize + 1, sizeof(off_t))) == NULL) + err(1, "reallocarray"); + if ((V = reallocarray(NULL, oldsize + 1, sizeof(off_t))) == NULL) + err(1, "reallocarray"); qsufsort(I, V, old, oldsize); free(V); - /* Allocate newsize+1 bytes instead of newsize bytes to ensure - that we never try to malloc(0) and get a NULL pointer */ - if (((fd = open(argv[2], O_RDONLY, 0)) < 0) || - ((newsize = lseek(fd, 0, SEEK_END)) == -1) || - ((new = malloc(newsize + 1)) == NULL) || - (lseek(fd, 0, SEEK_SET) != 0) || - (read(fd, new, newsize) != newsize) || (close(fd) == -1)) - err(1, "%s", argv[2]); - - if (((db = malloc(newsize + 1)) == NULL) || - ((eb = malloc(newsize + 1)) == NULL)) - err(1, NULL); + new = readfile(argv[2], &newsize); + + if ((db = reallocarray(NULL, oldsize + 1, sizeof(off_t))) == NULL) + err(1, "reallocarray"); + if ((eb = reallocarray(NULL, oldsize + 1, sizeof(off_t))) == NULL) + err(1, "reallocarray"); dblen = eblen = 0; /* Create the patch file */ diff --git a/bsdiff.h b/bsdiff.h @@ -44,4 +44,5 @@ void offtout(off_t, uint8_t *); off_t offtin(uint8_t *buf); uint8_t * readfile(char *, off_t *); DEAD void usage(void); +uint8_t * readfile(char *, off_t *); #endif /* BSDIFF_H */ diff --git a/bspatch.c b/bspatch.c @@ -120,14 +120,9 @@ main(int argc, char **argv) if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL) errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err); - if (((fd = open(argv[1], O_RDONLY, 0)) < 0) || - ((oldsize = lseek(fd, 0, SEEK_END)) == -1) || - ((old = malloc(oldsize + 1)) == NULL) || - (lseek(fd, 0, SEEK_SET) != 0) || - (read(fd, old, oldsize) != oldsize) || (close(fd) == -1)) - err(1, "%s", argv[1]); - if ((new = malloc(newsize + 1)) == NULL) - err(1, NULL); + old = readfile(argv[1], &oldsize); + if ((new = reallocarray(NULL, newsize + 1, 1)) == NULL) + err(1, "reallocarray"); oldpos = newpos = 0; while (newpos < newsize) { diff --git a/util.c b/util.c @@ -1,5 +1,6 @@ /*- * Copyright 2003-2005 Colin Percival + * Copyright 2020 Stephen Gregoratto * All rights reserved * * Redistribution and use in source and binary forms, with or without @@ -25,10 +26,16 @@ */ #include "config.h" +#include <sys/stat.h> +#if HAVE_ERR +#include <err.h> +#endif +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #include "bsdiff.h" @@ -243,3 +250,30 @@ usage(void) exit(1); } + +uint8_t * +readfile(char *path, off_t *size) +{ + uint8_t *buf = NULL; + int fd; + struct stat st; + + if ((fd = open(path, O_RDONLY, 0)) == -1) + err(1, "%s: open", path); + if (fstat(fd, &st) == -1) + err(1, "%s: fstat", path); + /* + * Allocate size + 1 bytes to ensure that we never + * try to malloc(0) and get a NULL pointer. + */ + *size = st.st_size + 1; + if ((buf = reallocarray(NULL, *size, sizeof(off_t))) == NULL) + err(1, "%s: reallocarray", path); + + if (read(fd, buf, *size) != *size) + err(1, "%s: read", path); + if (close(fd) == -1) + err(1, "%s: close", path); + + return buf; +}