Skip to content

Commit 3733e69

Browse files
peffgitster
authored andcommitted
use xmallocz to avoid size arithmetic
We frequently allocate strings as xmalloc(len + 1), where the extra 1 is for the NUL terminator. This can be done more simply with xmallocz, which also checks for integer overflow. There's no case where switching xmalloc(n+1) to xmallocz(n) is wrong; the result is the same length, and malloc made no guarantees about what was in the buffer anyway. But in some cases, we can stop manually placing NUL at the end of the allocated buffer. But that's only safe if it's clear that the contents will always fill the buffer. In each case where this patch does so, I manually examined the control flow, and I tried to err on the side of caution. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b32fa95 commit 3733e69

15 files changed

+17
-25
lines changed

Diff for: builtin/check-ref-format.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ static const char builtin_check_ref_format_usage[] =
2020
*/
2121
static char *collapse_slashes(const char *refname)
2222
{
23-
char *ret = xmalloc(strlen(refname) + 1);
23+
char *ret = xmallocz(strlen(refname));
2424
char ch;
2525
char prev = '/';
2626
char *cp = ret;

Diff for: builtin/merge-tree.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static struct merge_list *create_entry(unsigned stage, unsigned mode, const unsi
174174

175175
static char *traverse_path(const struct traverse_info *info, const struct name_entry *n)
176176
{
177-
char *path = xmalloc(traverse_path_len(info, n) + 1);
177+
char *path = xmallocz(traverse_path_len(info, n));
178178
return make_traverse_path(path, info, n);
179179
}
180180

Diff for: builtin/worktree.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ static int prune_worktree(const char *id, struct strbuf *reason)
5252
return 1;
5353
}
5454
len = st.st_size;
55-
path = xmalloc(len + 1);
55+
path = xmallocz(len);
5656
read_in_full(fd, path, len);
5757
close(fd);
5858
while (len && (path[len - 1] == '\n' || path[len - 1] == '\r'))

Diff for: column.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,8 @@ static void display_table(const struct string_list *list,
173173
if (colopts & COL_DENSE)
174174
shrink_columns(&data);
175175

176-
empty_cell = xmalloc(initial_width + 1);
176+
empty_cell = xmallocz(initial_width);
177177
memset(empty_cell, ' ', initial_width);
178-
empty_cell[initial_width] = '\0';
179178
for (y = 0; y < data.rows; y++) {
180179
for (x = 0; x < data.cols; x++)
181180
if (display_cell(&data, initial_width, empty_cell, x, y))

Diff for: combine-diff.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -1043,16 +1043,14 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
10431043
elem->mode = canon_mode(S_IFLNK);
10441044

10451045
result_size = len;
1046-
result = xmalloc(len + 1);
1046+
result = xmallocz(len);
10471047

10481048
done = read_in_full(fd, result, len);
10491049
if (done < 0)
10501050
die_errno("read error '%s'", elem->path);
10511051
else if (done < len)
10521052
die("early EOF '%s'", elem->path);
10531053

1054-
result[len] = 0;
1055-
10561054
/* If not a fake symlink, apply filters, e.g. autocrlf */
10571055
if (is_file) {
10581056
struct strbuf buf = STRBUF_INIT;

Diff for: config.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -1878,7 +1878,7 @@ static int git_config_parse_key_1(const char *key, char **store_key, int *basele
18781878
* Validate the key and while at it, lower case it for matching.
18791879
*/
18801880
if (store_key)
1881-
*store_key = xmalloc(strlen(key) + 1);
1881+
*store_key = xmallocz(strlen(key));
18821882

18831883
dot = 0;
18841884
for (i = 0; key[i]; i++) {
@@ -1902,8 +1902,6 @@ static int git_config_parse_key_1(const char *key, char **store_key, int *basele
19021902
if (store_key)
19031903
(*store_key)[i] = c;
19041904
}
1905-
if (store_key)
1906-
(*store_key)[i] = 0;
19071905

19081906
return 0;
19091907

Diff for: dir.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ static int add_excludes(const char *fname, const char *base, int baselen,
711711
close(fd);
712712
return 0;
713713
}
714-
buf = xmalloc(size+1);
714+
buf = xmallocz(size);
715715
if (read_in_full(fd, buf, size) != size) {
716716
free(buf);
717717
close(fd);

Diff for: entry.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
static void create_directories(const char *path, int path_len,
77
const struct checkout *state)
88
{
9-
char *buf = xmalloc(path_len + 1);
9+
char *buf = xmallocz(path_len);
1010
int len = 0;
1111

1212
while (len < path_len) {

Diff for: grep.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -1741,15 +1741,14 @@ static int grep_source_load_file(struct grep_source *gs)
17411741
i = open(filename, O_RDONLY);
17421742
if (i < 0)
17431743
goto err_ret;
1744-
data = xmalloc(size + 1);
1744+
data = xmallocz(size);
17451745
if (st.st_size != read_in_full(i, data, size)) {
17461746
error(_("'%s': short read %s"), filename, strerror(errno));
17471747
close(i);
17481748
free(data);
17491749
return -1;
17501750
}
17511751
close(i);
1752-
data[size] = 0;
17531752

17541753
gs->buf = data;
17551754
gs->size = size;

Diff for: imap-send.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -892,12 +892,11 @@ static char *cram(const char *challenge_64, const char *user, const char *pass)
892892
response = xstrfmt("%s %s", user, hex);
893893
resp_len = strlen(response) + 1;
894894

895-
response_64 = xmalloc(ENCODED_SIZE(resp_len) + 1);
895+
response_64 = xmallocz(ENCODED_SIZE(resp_len));
896896
encoded_len = EVP_EncodeBlock((unsigned char *)response_64,
897897
(unsigned char *)response, resp_len);
898898
if (encoded_len < 0)
899899
die("EVP_EncodeBlock error");
900-
response_64[encoded_len] = '\0';
901900
return (char *)response_64;
902901
}
903902

@@ -1188,7 +1187,7 @@ static void lf_to_crlf(struct strbuf *msg)
11881187
j++;
11891188
}
11901189

1191-
new = xmalloc(j + 1);
1190+
new = xmallocz(j);
11921191

11931192
/*
11941193
* Second pass: write the new string. Note that this loop is

Diff for: ll-merge.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,
205205
if (fstat(fd, &st))
206206
goto close_bad;
207207
result->size = st.st_size;
208-
result->ptr = xmalloc(result->size + 1);
208+
result->ptr = xmallocz(result->size);
209209
if (read_in_full(fd, result->ptr, result->size) != result->size) {
210210
free(result->ptr);
211211
result->ptr = NULL;

Diff for: progress.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ void stop_progress_msg(struct progress **p_progress, const char *msg)
247247
size_t len = strlen(msg) + 5;
248248
struct throughput *tp = progress->throughput;
249249

250-
bufp = (len < sizeof(buf)) ? buf : xmalloc(len + 1);
250+
bufp = (len < sizeof(buf)) ? buf : xmallocz(len);
251251
if (tp) {
252252
unsigned int rate = !tp->avg_misecs ? 0 :
253253
tp->avg_bytes / tp->avg_misecs;

Diff for: refs.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ int refname_is_safe(const char *refname)
124124
char *buf;
125125
int result;
126126

127-
buf = xmalloc(strlen(refname) + 1);
127+
buf = xmallocz(strlen(refname));
128128
/*
129129
* Does the refname try to escape refs/?
130130
* For example: refs/foo/../bar is safe but refs/foo/../../bar

Diff for: setup.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ char *prefix_path_gently(const char *prefix, int len,
8888
const char *orig = path;
8989
char *sanitized;
9090
if (is_absolute_path(orig)) {
91-
sanitized = xmalloc(strlen(path) + 1);
91+
sanitized = xmallocz(strlen(path));
9292
if (remaining_prefix)
9393
*remaining_prefix = 0;
9494
if (normalize_path_copy_len(sanitized, path, remaining_prefix)) {
@@ -499,14 +499,13 @@ const char *read_gitfile_gently(const char *path, int *return_error_code)
499499
error_code = READ_GITFILE_ERR_OPEN_FAILED;
500500
goto cleanup_return;
501501
}
502-
buf = xmalloc(st.st_size + 1);
502+
buf = xmallocz(st.st_size);
503503
len = read_in_full(fd, buf, st.st_size);
504504
close(fd);
505505
if (len != st.st_size) {
506506
error_code = READ_GITFILE_ERR_READ_FAILED;
507507
goto cleanup_return;
508508
}
509-
buf[len] = '\0';
510509
if (!starts_with(buf, "gitdir: ")) {
511510
error_code = READ_GITFILE_ERR_INVALID_FORMAT;
512511
goto cleanup_return;

Diff for: strbuf.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ char *xstrdup_tolower(const char *string)
685685
size_t len, i;
686686

687687
len = strlen(string);
688-
result = xmalloc(len + 1);
688+
result = xmallocz(len);
689689
for (i = 0; i < len; i++)
690690
result[i] = tolower(string[i]);
691691
result[i] = '\0';

0 commit comments

Comments
 (0)