Skip to content

Commit 760dd80

Browse files
peffgitster
authored andcommitted
test-delta: use strbufs to hold input files
We want to read the whole contents of two files into memory. If we switch from raw ptr/len pairs to strbufs, we can use strbuf_read_file() to shorten the code. This incidentally fixes two small bugs: 1. We stat() the files and allocate our buffers based on st.st_size. But that is an off_t which may be larger than the size_t we'd use to allocate. We should use xsize_t() to do a checked conversion. Otherwise integer truncation (on a file >4GB) could cause us to under-allocate (though in practice this does not result in a buffer overflow because the same truncation happens when read_in_full() also takes a size_t). 2. We get the size from st.st_size, and then try to read_in_full() that many bytes. But it may return fewer bytes than expected (if the file changed racily and we get an early EOF), leading us to read uninitialized bytes in the allocated buffer. We don't notice because we only check the value for error, not that we got the expected number of bytes. The strbuf code doesn't run into this, because it just reads to EOF, expanding the buffer dynamically as necessary. Neither bug is a big deal for a test helper, but fixing them is a nice bonus on top of simplifying the code. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent bc235a6 commit 760dd80

File tree

1 file changed

+14
-26
lines changed

1 file changed

+14
-26
lines changed

t/helper/test-delta.c

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,45 +11,33 @@
1111
#include "test-tool.h"
1212
#include "git-compat-util.h"
1313
#include "delta.h"
14+
#include "strbuf.h"
1415

1516
static const char usage_str[] =
1617
"test-tool delta (-d|-p) <from_file> <data_file> <out_file>";
1718

1819
int cmd__delta(int argc, const char **argv)
1920
{
2021
int fd;
21-
struct stat st;
22-
void *from_buf = NULL, *data_buf = NULL, *out_buf = NULL;
23-
unsigned long from_size, data_size, out_size;
22+
struct strbuf from = STRBUF_INIT, data = STRBUF_INIT;
23+
char *out_buf;
24+
unsigned long out_size;
2425

2526
if (argc != 5 || (strcmp(argv[1], "-d") && strcmp(argv[1], "-p")))
2627
usage(usage_str);
2728

28-
fd = xopen(argv[2], O_RDONLY);
29-
if (fstat(fd, &st) < 0)
30-
die_errno("fstat(%s)", argv[2]);
31-
from_size = st.st_size;
32-
from_buf = xmalloc(from_size);
33-
if (read_in_full(fd, from_buf, from_size) < 0)
34-
die_errno("read(%s)", argv[2]);
35-
close(fd);
36-
37-
fd = xopen(argv[3], O_RDONLY);
38-
if (fstat(fd, &st) < 0)
39-
die_errno("fstat(%s)", argv[3]);
40-
data_size = st.st_size;
41-
data_buf = xmalloc(data_size);
42-
if (read_in_full(fd, data_buf, data_size) < 0)
43-
die_errno("read(%s)", argv[3]);
44-
close(fd);
29+
if (strbuf_read_file(&from, argv[2], 0) < 0)
30+
die_errno("unable to read '%s'", argv[2]);
31+
if (strbuf_read_file(&data, argv[3], 0) < 0)
32+
die_errno("unable to read '%s'", argv[3]);
4533

4634
if (argv[1][1] == 'd')
47-
out_buf = diff_delta(from_buf, from_size,
48-
data_buf, data_size,
35+
out_buf = diff_delta(from.buf, from.len,
36+
data.buf, data.len,
4937
&out_size, 0);
5038
else
51-
out_buf = patch_delta(from_buf, from_size,
52-
data_buf, data_size,
39+
out_buf = patch_delta(from.buf, from.len,
40+
data.buf, data.len,
5341
&out_size);
5442
if (!out_buf)
5543
die("delta operation failed (returned NULL)");
@@ -58,8 +46,8 @@ int cmd__delta(int argc, const char **argv)
5846
if (write_in_full(fd, out_buf, out_size) < 0)
5947
die_errno("write(%s)", argv[4]);
6048

61-
free(from_buf);
62-
free(data_buf);
49+
strbuf_release(&from);
50+
strbuf_release(&data);
6351
free(out_buf);
6452

6553
return 0;

0 commit comments

Comments
 (0)