1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-13 14:36:08 +02:00

Merge branch 'jk/tighten-alloc'

Update various codepaths to avoid manually-counted malloc().

* jk/tighten-alloc: (22 commits)
  ewah: convert to REALLOC_ARRAY, etc
  convert ewah/bitmap code to use xmalloc
  diff_populate_gitlink: use a strbuf
  transport_anonymize_url: use xstrfmt
  git-compat-util: drop mempcpy compat code
  sequencer: simplify memory allocation of get_message
  test-path-utils: fix normalize_path_copy output buffer size
  fetch-pack: simplify add_sought_entry
  fast-import: simplify allocation in start_packfile
  write_untracked_extension: use FLEX_ALLOC helper
  prepare_{git,shell}_cmd: use argv_array
  use st_add and st_mult for allocation size computation
  convert trivial cases to FLEX_ARRAY macros
  use xmallocz to avoid size arithmetic
  convert trivial cases to ALLOC_ARRAY
  convert manual allocations to argv_array
  argv-array: add detach function
  add helpers for allocating flex-array structs
  harden REALLOC_ARRAY and xcalloc against size_t overflow
  tree-diff: catch integer overflow in combine_diff_path allocation
  ...
This commit is contained in:
Junio C Hamano 2016-02-26 13:37:16 -08:00
commit 11529ecec9
91 changed files with 440 additions and 481 deletions

View File

@ -56,3 +56,10 @@ Functions
`argv_array_clear`::
Free all memory associated with the array and return it to the
initial, empty state.
`argv_array_detach`::
Disconnect the `argv` member from the `argv_array` struct and
return it. The caller is responsible for freeing the memory used
by the array, and by the strings it references. After detaching,
the `argv_array` is in a reinitialized state and can be pushed
into again.

View File

@ -23,7 +23,7 @@ int split_cmdline(char *cmdline, const char ***argv)
int src, dst, count = 0, size = 16;
char quoted = 0;
*argv = xmalloc(sizeof(**argv) * size);
ALLOC_ARRAY(*argv, size);
/* split alias_string */
(*argv)[count++] = cmdline;

View File

@ -171,8 +171,8 @@ static void queue_directory(const unsigned char *sha1,
unsigned mode, int stage, struct archiver_context *c)
{
struct directory *d;
size_t len = base->len + 1 + strlen(filename) + 1;
d = xmalloc(sizeof(*d) + len);
size_t len = st_add4(base->len, 1, strlen(filename), 1);
d = xmalloc(st_add(sizeof(*d), len));
d->up = c->bottom;
d->baselen = base->len;
d->mode = mode;

View File

@ -74,3 +74,14 @@ void argv_array_clear(struct argv_array *array)
}
argv_array_init(array);
}
const char **argv_array_detach(struct argv_array *array)
{
if (array->argv == empty_argv)
return xcalloc(1, sizeof(const char *));
else {
const char **ret = array->argv;
argv_array_init(array);
return ret;
}
}

View File

@ -20,5 +20,6 @@ void argv_array_pushl(struct argv_array *, ...);
void argv_array_pushv(struct argv_array *, const char **);
void argv_array_pop(struct argv_array *);
void argv_array_clear(struct argv_array *);
const char **argv_array_detach(struct argv_array *);
#endif /* ARGV_ARRAY_H */

6
attr.c
View File

@ -93,9 +93,7 @@ static struct git_attr *git_attr_internal(const char *name, int len)
if (invalid_attr_name(name, len))
return NULL;
a = xmalloc(sizeof(*a) + len + 1);
memcpy(a->name, name, len);
a->name[len] = 0;
FLEX_ALLOC_MEM(a, name, name, len);
a->h = hval;
a->next = git_attr_hash[pos];
a->attr_nr = attr_nr++;
@ -799,7 +797,7 @@ int git_all_attrs(const char *path, int *num, struct git_attr_check **check)
++count;
}
*num = count;
*check = xmalloc(sizeof(**check) * count);
ALLOC_ARRAY(*check, count);
j = 0;
for (i = 0; i < attr_nr; i++) {
const char *value = check_all_attr[i].value;

View File

@ -708,10 +708,10 @@ static struct commit *get_commit_reference(const unsigned char *sha1)
static struct commit **get_bad_and_good_commits(int *rev_nr)
{
int len = 1 + good_revs.nr;
struct commit **rev = xmalloc(len * sizeof(*rev));
struct commit **rev;
int i, n = 0;
ALLOC_ARRAY(rev, 1 + good_revs.nr);
rev[n++] = get_commit_reference(current_bad_oid->hash);
for (i = 0; i < good_revs.nr; i++)
rev[n++] = get_commit_reference(good_revs.sha1[i]);

View File

@ -2632,7 +2632,7 @@ static void update_image(struct image *img,
insert_count = postimage->len;
/* Adjust the contents */
result = xmalloc(img->len + insert_count - remove_count + 1);
result = xmalloc(st_add3(st_sub(img->len, remove_count), insert_count, 1));
memcpy(result, img->buf, applied_at);
memcpy(result + applied_at, postimage->buf, postimage->len);
memcpy(result + applied_at + postimage->len,

View File

@ -466,13 +466,11 @@ static void queue_blames(struct scoreboard *sb, struct origin *porigin,
static struct origin *make_origin(struct commit *commit, const char *path)
{
struct origin *o;
size_t pathlen = strlen(path) + 1;
o = xcalloc(1, sizeof(*o) + pathlen);
FLEX_ALLOC_STR(o, path, path);
o->commit = commit;
o->refcnt = 1;
o->next = commit->util;
commit->util = o;
memcpy(o->path, path, pathlen); /* includes NUL */
return o;
}
@ -2059,7 +2057,8 @@ static int prepare_lines(struct scoreboard *sb)
for (p = buf; p < end; p = get_next_line(p, end))
num++;
sb->lineno = lineno = xmalloc(sizeof(*sb->lineno) * (num + 1));
ALLOC_ARRAY(sb->lineno, num + 1);
lineno = sb->lineno;
for (p = buf; p < end; p = get_next_line(p, end))
*lineno++ = p - buf;

View File

@ -20,7 +20,7 @@ static const char builtin_check_ref_format_usage[] =
*/
static char *collapse_slashes(const char *refname)
{
char *ret = xmalloc(strlen(refname) + 1);
char *ret = xmallocz(strlen(refname));
char ch;
char prev = '/';
char *cp = ret;

View File

@ -543,7 +543,7 @@ static int *list_and_choose(struct menu_opts *opts, struct menu_stuff *stuff)
int eof = 0;
int i;
chosen = xmalloc(sizeof(int) * stuff->nr);
ALLOC_ARRAY(chosen, stuff->nr);
/* set chosen as uninitialized */
for (i = 0; i < stuff->nr; i++)
chosen[i] = -1;
@ -615,7 +615,7 @@ static int *list_and_choose(struct menu_opts *opts, struct menu_stuff *stuff)
nr += chosen[i];
}
result = xcalloc(nr + 1, sizeof(int));
result = xcalloc(st_add(nr, 1), sizeof(int));
for (i = 0; i < stuff->nr && j < nr; i++) {
if (chosen[i])
result[j++] = i;

View File

@ -1021,7 +1021,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
const char **refspecs_str;
int i;
refspecs_str = xmalloc(sizeof(*refspecs_str) * refspecs_list.nr);
ALLOC_ARRAY(refspecs_str, refspecs_list.nr);
for (i = 0; i < refspecs_list.nr; i++)
refspecs_str[i] = refspecs_list.items[i].string;

View File

@ -10,33 +10,24 @@ static const char fetch_pack_usage[] =
"[--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] "
"[--no-progress] [--diag-url] [-v] [<host>:]<directory> [<refs>...]";
static void add_sought_entry_mem(struct ref ***sought, int *nr, int *alloc,
const char *name, int namelen)
static void add_sought_entry(struct ref ***sought, int *nr, int *alloc,
const char *name)
{
struct ref *ref = xcalloc(1, sizeof(*ref) + namelen + 1);
struct ref *ref;
struct object_id oid;
const int chunksz = GIT_SHA1_HEXSZ + 1;
if (namelen > chunksz && name[chunksz - 1] == ' ' &&
!get_oid_hex(name, &oid)) {
oidcpy(&ref->old_oid, &oid);
name += chunksz;
namelen -= chunksz;
}
if (!get_oid_hex(name, &oid) && name[GIT_SHA1_HEXSZ] == ' ')
name += GIT_SHA1_HEXSZ + 1;
else
oidclr(&oid);
memcpy(ref->name, name, namelen);
ref->name[namelen] = '\0';
ref = alloc_ref(name);
oidcpy(&ref->old_oid, &oid);
(*nr)++;
ALLOC_GROW(*sought, *nr, *alloc);
(*sought)[*nr - 1] = ref;
}
static void add_sought_entry(struct ref ***sought, int *nr, int *alloc,
const char *string)
{
add_sought_entry_mem(sought, nr, alloc, string, strlen(string));
}
int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
{
int i, ret;

View File

@ -1115,7 +1115,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
if (argc > 0) {
int j = 0;
int i;
refs = xcalloc(argc + 1, sizeof(const char *));
refs = xcalloc(st_add(argc, 1), sizeof(const char *));
for (i = 0; i < argc; i++) {
if (!strcmp(argv[i], "tag")) {
i++;

View File

@ -365,17 +365,17 @@ static void append_path(struct grep_opt *opt, const void *data, size_t len)
static void run_pager(struct grep_opt *opt, const char *prefix)
{
struct string_list *path_list = opt->output_priv;
const char **argv = xmalloc(sizeof(const char *) * (path_list->nr + 1));
struct child_process child = CHILD_PROCESS_INIT;
int i, status;
for (i = 0; i < path_list->nr; i++)
argv[i] = path_list->items[i].string;
argv[path_list->nr] = NULL;
argv_array_push(&child.args, path_list->items[i].string);
child.dir = prefix;
child.use_shell = 1;
status = run_command_v_opt_cd_env(argv, RUN_USING_SHELL, prefix, NULL);
status = run_command(&child);
if (status)
exit(status);
free(argv);
}
static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int cached)

View File

@ -171,12 +171,10 @@ static void exec_man_cmd(const char *cmd, const char *page)
static void add_man_viewer(const char *name)
{
struct man_viewer_list **p = &man_viewer_list;
size_t len = strlen(name);
while (*p)
p = &((*p)->next);
*p = xcalloc(1, (sizeof(**p) + len + 1));
memcpy((*p)->name, name, len); /* NUL-terminated by xcalloc */
FLEX_ALLOC_STR(*p, name, name);
}
static int supported_man_viewer(const char *name, size_t len)
@ -190,9 +188,8 @@ static void do_add_man_viewer_info(const char *name,
size_t len,
const char *value)
{
struct man_viewer_info_list *new = xcalloc(1, sizeof(*new) + len + 1);
memcpy(new->name, name, len); /* NUL-terminated by xcalloc */
struct man_viewer_info_list *new;
FLEX_ALLOC_MEM(new, name, name, len);
new->info = xstrdup(value);
new->next = man_viewer_info_list;
man_viewer_info_list = new;

View File

@ -1346,7 +1346,7 @@ static void fix_unresolved_deltas(struct sha1file *f)
* before deltas depending on them, a good heuristic is to start
* resolving deltas in the same order as their position in the pack.
*/
sorted_by_pos = xmalloc(nr_ref_deltas * sizeof(*sorted_by_pos));
ALLOC_ARRAY(sorted_by_pos, nr_ref_deltas);
for (i = 0; i < nr_ref_deltas; i++)
sorted_by_pos[i] = &ref_deltas[i];
qsort(sorted_by_pos, nr_ref_deltas, sizeof(*sorted_by_pos), delta_pos_compare);
@ -1744,9 +1744,9 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
curr_pack = open_pack_file(pack_name);
parse_pack_header();
objects = xcalloc(nr_objects + 1, sizeof(struct object_entry));
objects = xcalloc(st_add(nr_objects, 1), sizeof(struct object_entry));
if (show_stat)
obj_stat = xcalloc(nr_objects + 1, sizeof(struct object_stat));
obj_stat = xcalloc(st_add(nr_objects, 1), sizeof(struct object_stat));
ofs_deltas = xcalloc(nr_objects, sizeof(struct ofs_delta_entry));
parse_pack_objects(pack_sha1);
resolve_deltas();
@ -1759,7 +1759,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
if (show_stat)
show_pack_info(stat_only);
idx_objects = xmalloc((nr_objects) * sizeof(struct pack_idx_entry *));
ALLOC_ARRAY(idx_objects, nr_objects);
for (i = 0; i < nr_objects; i++)
idx_objects[i] = &objects[i].idx;
curr_index = write_idx_file(index_name, idx_objects, nr_objects, &opts, pack_sha1);

View File

@ -252,7 +252,7 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)
if (argc < 2)
usage_with_options(merge_base_usage, options);
rev = xmalloc(argc * sizeof(*rev));
ALLOC_ARRAY(rev, argc);
while (argc-- > 0)
rev[rev_nr++] = get_commit_reference(*argv++);
return show_merge_base(rev, rev_nr, show_all);

View File

@ -174,7 +174,7 @@ static struct merge_list *create_entry(unsigned stage, unsigned mode, const unsi
static char *traverse_path(const struct traverse_info *info, const struct name_entry *n)
{
char *path = xmalloc(traverse_path_len(info, n) + 1);
char *path = xmallocz(traverse_path_len(info, n));
return make_traverse_path(path, info, n);
}

View File

@ -939,7 +939,7 @@ static int setup_with_upstream(const char ***argv)
if (!branch->merge_nr)
die(_("No default upstream defined for the current branch."));
args = xcalloc(branch->merge_nr + 1, sizeof(char *));
args = xcalloc(st_add(branch->merge_nr, 1), sizeof(char *));
for (i = 0; i < branch->merge_nr; i++) {
if (!branch->merge[i]->dst)
die(_("No remote-tracking branch for %s from %s"),

View File

@ -19,16 +19,17 @@ static int alloc, used;
static void append_to_tree(unsigned mode, unsigned char *sha1, char *path)
{
struct treeent *ent;
int len = strlen(path);
size_t len = strlen(path);
if (strchr(path, '/'))
die("path %s contains slash", path);
ALLOC_GROW(entries, used + 1, alloc);
ent = entries[used++] = xmalloc(sizeof(**entries) + len + 1);
FLEX_ALLOC_MEM(ent, name, path, len);
ent->mode = mode;
ent->len = len;
hashcpy(ent->sha1, sha1);
memcpy(ent->name, path, len+1);
ALLOC_GROW(entries, used + 1, alloc);
entries[used++] = ent;
}
static int ent_compare(const void *a_, const void *b_)

View File

@ -24,7 +24,8 @@ static const char **internal_copy_pathspec(const char *prefix,
int count, unsigned flags)
{
int i;
const char **result = xmalloc((count + 1) * sizeof(const char *));
const char **result;
ALLOC_ARRAY(result, count + 1);
memcpy(result, pathspec, count * sizeof(const char *));
result[count] = NULL;
for (i = 0; i < count; i++) {
@ -47,9 +48,9 @@ static const char **internal_copy_pathspec(const char *prefix,
static const char *add_slash(const char *path)
{
int len = strlen(path);
size_t len = strlen(path);
if (path[len - 1] != '/') {
char *with_slash = xmalloc(len + 2);
char *with_slash = xmalloc(st_add(len, 2));
memcpy(with_slash, path, len);
with_slash[len++] = '/';
with_slash[len] = 0;

View File

@ -624,7 +624,7 @@ static struct object_entry **compute_write_order(void)
{
unsigned int i, wo_end, last_untagged;
struct object_entry **wo = xmalloc(to_pack.nr_objects * sizeof(*wo));
struct object_entry **wo;
struct object_entry *objects = to_pack.objects;
for (i = 0; i < to_pack.nr_objects; i++) {
@ -657,6 +657,7 @@ static struct object_entry **compute_write_order(void)
* Give the objects in the original recency order until
* we see a tagged tip.
*/
ALLOC_ARRAY(wo, to_pack.nr_objects);
for (i = wo_end = 0; i < to_pack.nr_objects; i++) {
if (objects[i].tagged)
break;
@ -769,7 +770,7 @@ static void write_pack_file(void)
if (progress > pack_to_stdout)
progress_state = start_progress(_("Writing objects"), nr_result);
written_list = xmalloc(to_pack.nr_objects * sizeof(*written_list));
ALLOC_ARRAY(written_list, to_pack.nr_objects);
write_order = compute_write_order();
do {
@ -2129,7 +2130,7 @@ static void prepare_pack(int window, int depth)
if (!to_pack.nr_objects || !window || !depth)
return;
delta_list = xmalloc(to_pack.nr_objects * sizeof(*delta_list));
ALLOC_ARRAY(delta_list, to_pack.nr_objects);
nr_deltas = n = 0;
for (i = 0; i < to_pack.nr_objects; i++) {

View File

@ -53,7 +53,7 @@ static inline struct llist_item *llist_item_get(void)
free_nodes = free_nodes->next;
} else {
int i = 1;
new = xmalloc(sizeof(struct llist_item) * BLKSIZE);
ALLOC_ARRAY(new, BLKSIZE);
for (; i < BLKSIZE; i++)
llist_item_put(&new[i]);
}

View File

@ -1031,7 +1031,6 @@ static void run_update_post_hook(struct command *commands)
{
struct command *cmd;
int argc;
const char **argv;
struct child_process proc = CHILD_PROCESS_INIT;
const char *hook;
@ -1044,21 +1043,16 @@ static void run_update_post_hook(struct command *commands)
if (!argc || !hook)
return;
argv = xmalloc(sizeof(*argv) * (2 + argc));
argv[0] = hook;
for (argc = 1, cmd = commands; cmd; cmd = cmd->next) {
argv_array_push(&proc.args, hook);
for (cmd = commands; cmd; cmd = cmd->next) {
if (cmd->error_string || cmd->did_not_exist)
continue;
argv[argc] = xstrdup(cmd->ref_name);
argc++;
argv_array_push(&proc.args, cmd->ref_name);
}
argv[argc] = NULL;
proc.no_stdin = 1;
proc.stdout_to_stderr = 1;
proc.err = use_sideband ? -1 : 0;
proc.argv = argv;
if (!start_command(&proc)) {
if (use_sideband)
@ -1378,7 +1372,7 @@ static struct command **queue_command(struct command **tail,
refname = line + 82;
reflen = linelen - 82;
cmd = xcalloc(1, sizeof(struct command) + reflen + 1);
cmd = xcalloc(1, st_add3(sizeof(struct command), reflen, 1));
hashcpy(cmd->old_sha1, old_sha1);
hashcpy(cmd->new_sha1, new_sha1);
memcpy(cmd->ref_name, refname, reflen);
@ -1597,8 +1591,7 @@ static void prepare_shallow_update(struct command *commands,
{
int i, j, k, bitmap_size = (si->ref->nr + 31) / 32;
si->used_shallow = xmalloc(sizeof(*si->used_shallow) *
si->shallow->nr);
ALLOC_ARRAY(si->used_shallow, si->shallow->nr);
assign_shallow_commits_to_refs(si, si->used_shallow, NULL);
si->need_reachability_test =
@ -1664,7 +1657,7 @@ static void update_shallow_info(struct command *commands,
return;
}
ref_status = xmalloc(sizeof(*ref_status) * ref->nr);
ALLOC_ARRAY(ref_status, ref->nr);
assign_shallow_commits_to_refs(si, NULL, ref_status);
for (cmd = commands; cmd; cmd = cmd->next) {
if (is_null_sha1(cmd->new_sha1))

View File

@ -382,11 +382,9 @@ static int collect_reflog(const char *ref, const struct object_id *oid, int unus
{
struct collected_reflog *e;
struct collect_reflog_cb *cb = cb_data;
size_t namelen = strlen(ref);
e = xmalloc(sizeof(*e) + namelen + 1);
FLEX_ALLOC_STR(e, reflog, ref);
hashcpy(e->sha1, oid->hash);
memcpy(e->reflog, ref, namelen + 1);
ALLOC_GROW(cb->e, cb->nr + 1, cb->alloc);
cb->e[cb->nr++] = e;
return 0;
@ -396,7 +394,6 @@ static struct reflog_expire_cfg {
struct reflog_expire_cfg *next;
unsigned long expire_total;
unsigned long expire_unreachable;
size_t len;
char pattern[FLEX_ARRAY];
} *reflog_expire_cfg, **reflog_expire_cfg_tail;
@ -408,13 +405,11 @@ static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len)
reflog_expire_cfg_tail = &reflog_expire_cfg;
for (ent = reflog_expire_cfg; ent; ent = ent->next)
if (ent->len == len &&
!memcmp(ent->pattern, pattern, len))
if (!strncmp(ent->pattern, pattern, len) &&
ent->pattern[len] == '\0')
return ent;
ent = xcalloc(1, (sizeof(*ent) + len));
memcpy(ent->pattern, pattern, len);
ent->len = len;
FLEX_ALLOC_MEM(ent, pattern, pattern, len);
*reflog_expire_cfg_tail = ent;
reflog_expire_cfg_tail = &(ent->next);
return ent;

View File

@ -114,30 +114,14 @@ static char *strip_escapes(const char *str, const char *service,
}
}
/* Should be enough... */
#define MAXARGUMENTS 256
static const char **parse_argv(const char *arg, const char *service)
static void parse_argv(struct argv_array *out, const char *arg, const char *service)
{
int arguments = 0;
int i;
const char **ret;
char *temparray[MAXARGUMENTS + 1];
while (*arg) {
char *expanded;
if (arguments == MAXARGUMENTS)
die("remote-ext command has too many arguments");
expanded = strip_escapes(arg, service, &arg);
char *expanded = strip_escapes(arg, service, &arg);
if (expanded)
temparray[arguments++] = expanded;
argv_array_push(out, expanded);
free(expanded);
}
ret = xmalloc((arguments + 1) * sizeof(char *));
for (i = 0; i < arguments; i++)
ret[i] = temparray[i];
ret[arguments] = NULL;
return ret;
}
static void send_git_request(int stdin_fd, const char *serv, const char *repo,
@ -158,7 +142,7 @@ static int run_child(const char *arg, const char *service)
child.in = -1;
child.out = -1;
child.err = 0;
child.argv = parse_argv(arg, service);
parse_argv(&child.args, arg, service);
if (start_command(&child) < 0)
die("Can't run specified command");

View File

@ -52,7 +52,7 @@ static int prune_worktree(const char *id, struct strbuf *reason)
return 1;
}
len = st.st_size;
path = xmalloc(len + 1);
path = xmallocz(len);
read_in_full(fd, path, len);
close(fd);
while (len && (path[len - 1] == '\n' || path[len - 1] == '\r'))

View File

@ -79,11 +79,9 @@ static struct cache_tree_sub *find_subtree(struct cache_tree *it,
ALLOC_GROW(it->down, it->subtree_nr + 1, it->subtree_alloc);
it->subtree_nr++;
down = xmalloc(sizeof(*down) + pathlen + 1);
FLEX_ALLOC_MEM(down, name, path, pathlen);
down->cache_tree = NULL;
down->namelen = pathlen;
memcpy(down->name, path, pathlen);
down->name[pathlen] = 0;
if (pos < it->subtree_nr)
memmove(it->down + pos + 1,

View File

@ -164,7 +164,7 @@ static void display_table(const struct string_list *list,
data.colopts = colopts;
data.opts = *opts;
data.len = xmalloc(sizeof(*data.len) * list->nr);
ALLOC_ARRAY(data.len, list->nr);
for (i = 0; i < list->nr; i++)
data.len[i] = item_length(colopts, list->items[i].string);
@ -173,9 +173,8 @@ static void display_table(const struct string_list *list,
if (colopts & COL_DENSE)
shrink_columns(&data);
empty_cell = xmalloc(initial_width + 1);
empty_cell = xmallocz(initial_width);
memset(empty_cell, ' ', initial_width);
empty_cell[initial_width] = '\0';
for (y = 0; y < data.rows; y++) {
for (x = 0; x < data.cols; x++)
if (display_cell(&data, initial_width, empty_cell, x, y))

View File

@ -189,11 +189,11 @@ static struct lline *coalesce_lines(struct lline *base, int *lenbase,
* - Else if we have NEW, insert newend lline into base and
* consume newend
*/
lcs = xcalloc(origbaselen + 1, sizeof(int*));
directions = xcalloc(origbaselen + 1, sizeof(enum coalesce_direction*));
lcs = xcalloc(st_add(origbaselen, 1), sizeof(int*));
directions = xcalloc(st_add(origbaselen, 1), sizeof(enum coalesce_direction*));
for (i = 0; i < origbaselen + 1; i++) {
lcs[i] = xcalloc(lennew + 1, sizeof(int));
directions[i] = xcalloc(lennew + 1, sizeof(enum coalesce_direction));
lcs[i] = xcalloc(st_add(lennew, 1), sizeof(int));
directions[i] = xcalloc(st_add(lennew, 1), sizeof(enum coalesce_direction));
directions[i][0] = BASE;
}
for (j = 1; j < lennew + 1; j++)
@ -319,7 +319,7 @@ static void append_lost(struct sline *sline, int n, const char *line, int len)
if (line[len-1] == '\n')
len--;
lline = xmalloc(sizeof(*lline) + len + 1);
FLEX_ALLOC_MEM(lline, line, line, len);
lline->len = len;
lline->next = NULL;
lline->prev = sline->plost.lost_tail;
@ -330,8 +330,6 @@ static void append_lost(struct sline *sline, int n, const char *line, int len)
sline->plost.lost_tail = lline;
sline->plost.len++;
lline->parent_map = this_mask;
memcpy(lline->line, line, len);
lline->line[len] = 0;
}
struct combine_diff_state {
@ -1043,7 +1041,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
elem->mode = canon_mode(S_IFLNK);
result_size = len;
result = xmalloc(len + 1);
result = xmallocz(len);
done = read_in_full(fd, result, len);
if (done < 0)
@ -1051,8 +1049,6 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
else if (done < len)
die("early EOF '%s'", elem->path);
result[len] = 0;
/* If not a fake symlink, apply filters, e.g. autocrlf */
if (is_file) {
struct strbuf buf = STRBUF_INIT;
@ -1115,7 +1111,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
if (result_size && result[result_size-1] != '\n')
cnt++; /* incomplete line */
sline = xcalloc(cnt+2, sizeof(*sline));
sline = xcalloc(st_add(cnt, 2), sizeof(*sline));
sline[0].bol = result;
for (lno = 0, cp = result; cp < result + result_size; cp++) {
if (*cp == '\n') {
@ -1134,7 +1130,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
/* Even p_lno[cnt+1] is valid -- that is for the end line number
* for deletion hunk at the end.
*/
sline[0].p_lno = xcalloc((cnt+2) * num_parent, sizeof(unsigned long));
sline[0].p_lno = xcalloc(st_mult(st_add(cnt, 2), num_parent), sizeof(unsigned long));
for (lno = 0; lno <= cnt; lno++)
sline[lno+1].p_lno = sline[lno].p_lno + num_parent;
@ -1266,7 +1262,7 @@ static struct diff_filepair *combined_pair(struct combine_diff_path *p,
struct diff_filespec *pool;
pair = xmalloc(sizeof(*pair));
pool = xcalloc(num_parent + 1, sizeof(struct diff_filespec));
pool = xcalloc(st_add(num_parent, 1), sizeof(struct diff_filespec));
pair->one = pool + 1;
pair->two = pool;
@ -1372,7 +1368,7 @@ static struct combine_diff_path *find_paths_multitree(
struct combine_diff_path paths_head;
struct strbuf base;
parents_sha1 = xmalloc(nparent * sizeof(parents_sha1[0]));
ALLOC_ARRAY(parents_sha1, nparent);
for (i = 0; i < nparent; i++)
parents_sha1[i] = parents->sha1[i];
@ -1483,7 +1479,7 @@ void diff_tree_combined(const unsigned char *sha1,
if (opt->orderfile && num_paths) {
struct obj_order *o;
o = xmalloc(sizeof(*o) * num_paths);
ALLOC_ARRAY(o, num_paths);
for (i = 0, p = paths; p; p = p->next, i++)
o[i].obj = p;
order_objects(opt->orderfile, path_path, o, num_paths);

View File

@ -147,7 +147,7 @@ struct commit_graft *read_graft_line(char *buf, int len)
if ((len + 1) % entry_size)
goto bad_graft_data;
i = (len + 1) / entry_size - 1;
graft = xmalloc(sizeof(*graft) + GIT_SHA1_RAWSZ * i);
graft = xmalloc(st_add(sizeof(*graft), st_mult(GIT_SHA1_RAWSZ, i)));
graft->nr_parent = i;
if (get_oid_hex(buf, &graft->oid))
goto bad_graft_data;
@ -903,7 +903,7 @@ static int remove_redundant(struct commit **array, int cnt)
work = xcalloc(cnt, sizeof(*work));
redundant = xcalloc(cnt, 1);
filled_index = xmalloc(sizeof(*filled_index) * (cnt - 1));
ALLOC_ARRAY(filled_index, cnt - 1);
for (i = 0; i < cnt; i++)
parse_commit(array[i]);

View File

@ -810,7 +810,7 @@ static const char *quote_arg(const char *arg)
return arg;
/* insert \ where necessary */
d = q = xmalloc(len+n+3);
d = q = xmalloc(st_add3(len, n, 3));
*d++ = '"';
while (*arg) {
if (*arg == '"')
@ -893,7 +893,7 @@ static char **get_path_split(void)
if (!n)
return NULL;
path = xmalloc((n+1)*sizeof(char *));
ALLOC_ARRAY(path, n + 1);
p = envpath;
i = 0;
do {
@ -978,7 +978,7 @@ static wchar_t *make_environment_block(char **deltaenv)
i++;
/* copy the environment, leaving space for changes */
tmpenv = xmalloc((size + i) * sizeof(char*));
ALLOC_ARRAY(tmpenv, size + i);
memcpy(tmpenv, environ, size * sizeof(char*));
/* merge supplied environment changes into the temporary environment */
@ -1069,7 +1069,7 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
free(quoted);
}
wargs = xmalloc((2 * args.len + 1) * sizeof(wchar_t));
wargs = xmalloc_array(st_add(st_mult(2, args.len), 1), sizeof(wchar_t));
xutftowcs(wargs, args.buf, 2 * args.len + 1);
strbuf_release(&args);
@ -1168,7 +1168,7 @@ static int try_shell_exec(const char *cmd, char *const *argv)
int argc = 0;
const char **argv2;
while (argv[argc]) argc++;
argv2 = xmalloc(sizeof(*argv) * (argc+1));
ALLOC_ARRAY(argv2, argc + 1);
argv2[0] = (char *)cmd; /* full path to the script file */
memcpy(&argv2[1], &argv[1], sizeof(*argv) * argc);
pid = mingw_spawnv(prog, argv2, 1);

View File

@ -47,7 +47,7 @@ static void msort_with_tmp(void *b, size_t n, size_t s,
void git_qsort(void *b, size_t n, size_t s,
int (*cmp)(const void *, const void *))
{
const size_t size = n * s;
const size_t size = st_mult(n, s);
char buf[1024];
if (size < sizeof(buf)) {

View File

@ -18,7 +18,7 @@ int gitsetenv(const char *name, const char *value, int replace)
namelen = strlen(name);
valuelen = strlen(value);
envstr = malloc((namelen + valuelen + 2));
envstr = malloc(st_add3(namelen, valuelen, 2));
if (!envstr) {
errno = ENOMEM;
return -1;

View File

@ -32,7 +32,7 @@ void syslog(int priority, const char *fmt, ...)
return;
}
str = malloc(str_len + 1);
str = malloc(st_add(str_len, 1));
if (!str) {
warning("malloc failed: '%s'", strerror(errno));
return;
@ -43,7 +43,7 @@ void syslog(int priority, const char *fmt, ...)
va_end(ap);
while ((pos = strstr(str, "%1")) != NULL) {
str = realloc(str, ++str_len + 1);
str = realloc(str, st_add(++str_len, 1));
if (!str) {
warning("realloc failed: '%s'", strerror(errno));
return;

View File

@ -1902,7 +1902,7 @@ static int git_config_parse_key_1(const char *key, char **store_key, int *basele
* Validate the key and while at it, lower case it for matching.
*/
if (store_key)
*store_key = xmalloc(strlen(key) + 1);
*store_key = xmallocz(strlen(key));
dot = 0;
for (i = 0; key[i]; i++) {
@ -1926,8 +1926,6 @@ static int git_config_parse_key_1(const char *key, char **store_key, int *basele
if (store_key)
(*store_key)[i] = c;
}
if (store_key)
(*store_key)[i] = 0;
return 0;

View File

@ -808,7 +808,7 @@ static void check_dead_children(void)
cradle = &blanket->next;
}
static char **cld_argv;
static struct argv_array cld_argv = ARGV_ARRAY_INIT;
static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
{
struct child_process cld = CHILD_PROCESS_INIT;
@ -842,7 +842,7 @@ static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
#endif
}
cld.argv = (const char **)cld_argv;
cld.argv = cld_argv.argv;
cld.in = incoming;
cld.out = dup(incoming);
@ -1374,12 +1374,10 @@ int main(int argc, char **argv)
write_file(pid_file, "%"PRIuMAX, (uintmax_t) getpid());
/* prepare argv for serving-processes */
cld_argv = xmalloc(sizeof (char *) * (argc + 2));
cld_argv[0] = argv[0]; /* git-daemon */
cld_argv[1] = "--serve";
argv_array_push(&cld_argv, argv[0]); /* git-daemon */
argv_array_push(&cld_argv, "--serve");
for (i = 1; i < argc; ++i)
cld_argv[i+1] = argv[i];
cld_argv[argc+1] = NULL;
argv_array_push(&cld_argv, argv[i]);
return serve(&listen_addr, listen_port, cred);
}

23
diff.c
View File

@ -2607,12 +2607,9 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
struct diff_filespec *alloc_filespec(const char *path)
{
int namelen = strlen(path);
struct diff_filespec *spec = xmalloc(sizeof(*spec) + namelen + 1);
struct diff_filespec *spec;
memset(spec, 0, sizeof(*spec));
spec->path = (char *)(spec + 1);
memcpy(spec->path, path, namelen+1);
FLEXPTR_ALLOC_STR(spec, path, path);
spec->count = 1;
spec->is_binary = -1;
return spec;
@ -2707,21 +2704,21 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
static int diff_populate_gitlink(struct diff_filespec *s, int size_only)
{
int len;
char *data = xmalloc(100), *dirty = "";
struct strbuf buf = STRBUF_INIT;
char *dirty = "";
/* Are we looking at the work tree? */
if (s->dirty_submodule)
dirty = "-dirty";
len = snprintf(data, 100,
"Subproject commit %s%s\n", sha1_to_hex(s->sha1), dirty);
s->data = data;
s->size = len;
s->should_free = 1;
strbuf_addf(&buf, "Subproject commit %s%s\n", sha1_to_hex(s->sha1), dirty);
s->size = buf.len;
if (size_only) {
s->data = NULL;
free(data);
strbuf_release(&buf);
} else {
s->data = strbuf_detach(&buf, NULL);
s->should_free = 1;
}
return 0;
}

4
diff.h
View File

@ -222,8 +222,8 @@ struct combine_diff_path {
} parent[FLEX_ARRAY];
};
#define combine_diff_path_size(n, l) \
(sizeof(struct combine_diff_path) + \
sizeof(struct combine_diff_parent) * (n) + (l) + 1)
st_add4(sizeof(struct combine_diff_path), (l), 1, \
st_mult(sizeof(struct combine_diff_parent), (n)))
extern void show_combined_diff(struct combine_diff_path *elem, int num_parent,
int dense, struct rev_info *);

View File

@ -53,7 +53,8 @@ static struct spanhash_top *spanhash_rehash(struct spanhash_top *orig)
int osz = 1 << orig->alloc_log2;
int sz = osz << 1;
new = xmalloc(sizeof(*orig) + sizeof(struct spanhash) * sz);
new = xmalloc(st_add(sizeof(*orig),
st_mult(sizeof(struct spanhash), sz)));
new->alloc_log2 = orig->alloc_log2 + 1;
new->free = INITIAL_FREE(new->alloc_log2);
memset(new->data, 0, sizeof(struct spanhash) * sz);
@ -130,7 +131,8 @@ static struct spanhash_top *hash_chars(struct diff_filespec *one)
int is_text = !diff_filespec_is_binary(one);
i = INITIAL_HASH_SIZE;
hash = xmalloc(sizeof(*hash) + sizeof(struct spanhash) * (1<<i));
hash = xmalloc(st_add(sizeof(*hash),
st_mult(sizeof(struct spanhash), 1<<i)));
hash->alloc_log2 = i;
hash->free = INITIAL_FREE(i);
memset(hash->data, 0, sizeof(struct spanhash) * (1<<i));

View File

@ -52,7 +52,7 @@ static void prepare_order(const char *orderfile)
}
if (pass == 0) {
order_cnt = cnt;
order = xmalloc(sizeof(*order) * cnt);
ALLOC_ARRAY(order, cnt);
}
}
}
@ -120,7 +120,7 @@ void diffcore_order(const char *orderfile)
if (!q->nr)
return;
o = xmalloc(sizeof(*o) * q->nr);
ALLOC_ARRAY(o, q->nr);
for (i = 0; i < q->nr; i++)
o[i].obj = q->queue[i];
order_objects(orderfile, pair_pathtwo, o, q->nr);

View File

@ -537,7 +537,7 @@ void diffcore_rename(struct diff_options *options)
rename_dst_nr * rename_src_nr, 50, 1);
}
mx = xcalloc(num_create * NUM_CANDIDATE_PER_DST, sizeof(*mx));
mx = xcalloc(st_mult(num_create, NUM_CANDIDATE_PER_DST), sizeof(*mx));
for (dst_cnt = i = 0; i < rename_dst_nr; i++) {
struct diff_filespec *two = rename_dst[i].two;
struct diff_score *m;

37
dir.c
View File

@ -505,12 +505,7 @@ void add_exclude(const char *string, const char *base,
parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen);
if (flags & EXC_FLAG_MUSTBEDIR) {
char *s;
x = xmalloc(sizeof(*x) + patternlen + 1);
s = (char *)(x+1);
memcpy(s, string, patternlen);
s[patternlen] = '\0';
x->pattern = s;
FLEXPTR_ALLOC_MEM(x, pattern, string, patternlen);
} else {
x = xmalloc(sizeof(*x));
x->pattern = string;
@ -630,10 +625,7 @@ static struct untracked_cache_dir *lookup_untracked(struct untracked_cache *uc,
}
uc->dir_created++;
d = xmalloc(sizeof(*d) + len + 1);
memset(d, 0, sizeof(*d));
memcpy(d->name, name, len);
d->name[len] = '\0';
FLEX_ALLOC_MEM(d, name, name, len);
ALLOC_GROW(dir->dirs, dir->dirs_nr + 1, dir->dirs_alloc);
memmove(dir->dirs + first + 1, dir->dirs + first,
@ -702,7 +694,7 @@ static int add_excludes(const char *fname, const char *base, int baselen,
return 0;
}
if (buf[size-1] != '\n') {
buf = xrealloc(buf, size+1);
buf = xrealloc(buf, st_add(size, 1));
buf[size++] = '\n';
}
} else {
@ -716,7 +708,7 @@ static int add_excludes(const char *fname, const char *base, int baselen,
close(fd);
return 0;
}
buf = xmalloc(size+1);
buf = xmallocz(size);
if (read_in_full(fd, buf, size) != size) {
free(buf);
close(fd);
@ -1334,10 +1326,8 @@ static struct dir_entry *dir_entry_new(const char *pathname, int len)
{
struct dir_entry *ent;
ent = xmalloc(sizeof(*ent) + len + 1);
FLEX_ALLOC_MEM(ent, name, pathname, len);
ent->len = len;
memcpy(ent->name, pathname, len);
ent->name[len] = 0;
return ent;
}
@ -2568,16 +2558,15 @@ void write_untracked_extension(struct strbuf *out, struct untracked_cache *untra
struct ondisk_untracked_cache *ouc;
struct write_data wd;
unsigned char varbuf[16];
int len = 0, varint_len;
if (untracked->exclude_per_dir)
len = strlen(untracked->exclude_per_dir);
ouc = xmalloc(sizeof(*ouc) + len + 1);
int varint_len;
size_t len = strlen(untracked->exclude_per_dir);
FLEX_ALLOC_MEM(ouc, exclude_per_dir, untracked->exclude_per_dir, len);
stat_data_to_disk(&ouc->info_exclude_stat, &untracked->ss_info_exclude.stat);
stat_data_to_disk(&ouc->excludes_file_stat, &untracked->ss_excludes_file.stat);
hashcpy(ouc->info_exclude_sha1, untracked->ss_info_exclude.sha1);
hashcpy(ouc->excludes_file_sha1, untracked->ss_excludes_file.sha1);
ouc->dir_flags = htonl(untracked->dir_flags);
memcpy(ouc->exclude_per_dir, untracked->exclude_per_dir, len + 1);
varint_len = encode_varint(untracked->ident.len, varbuf);
strbuf_add(out, varbuf, varint_len);
@ -2682,21 +2671,21 @@ static int read_one_dir(struct untracked_cache_dir **untracked_,
ud.untracked_alloc = value;
ud.untracked_nr = value;
if (ud.untracked_nr)
ud.untracked = xmalloc(sizeof(*ud.untracked) * ud.untracked_nr);
ALLOC_ARRAY(ud.untracked, ud.untracked_nr);
data = next;
next = data;
ud.dirs_alloc = ud.dirs_nr = decode_varint(&next);
if (next > end)
return -1;
ud.dirs = xmalloc(sizeof(*ud.dirs) * ud.dirs_nr);
ALLOC_ARRAY(ud.dirs, ud.dirs_nr);
data = next;
len = strlen((const char *)data);
next = data + len + 1;
if (next > rd->end)
return -1;
*untracked_ = untracked = xmalloc(sizeof(*untracked) + len);
*untracked_ = untracked = xmalloc(st_add(sizeof(*untracked), len));
memcpy(untracked, &ud, sizeof(ud));
memcpy(untracked->name, data, len + 1);
data = next;
@ -2809,7 +2798,7 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
rd.data = next;
rd.end = end;
rd.index = 0;
rd.ucd = xmalloc(sizeof(*rd.ucd) * len);
ALLOC_ARRAY(rd.ucd, len);
if (read_one_dir(&uc->root, &rd) || rd.index != len)
goto done;

View File

@ -6,7 +6,7 @@
static void create_directories(const char *path, int path_len,
const struct checkout *state)
{
char *buf = xmalloc(path_len + 1);
char *buf = xmallocz(path_len);
int len = 0;
while (len < path_len) {

View File

@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "git-compat-util.h"
#include "cache.h"
#include "ewok.h"
#define EWAH_MASK(x) ((eword_t)1 << (x % BITS_IN_EWORD))
@ -25,8 +25,8 @@
struct bitmap *bitmap_new(void)
{
struct bitmap *bitmap = ewah_malloc(sizeof(struct bitmap));
bitmap->words = ewah_calloc(32, sizeof(eword_t));
struct bitmap *bitmap = xmalloc(sizeof(struct bitmap));
bitmap->words = xcalloc(32, sizeof(eword_t));
bitmap->word_alloc = 32;
return bitmap;
}
@ -38,9 +38,7 @@ void bitmap_set(struct bitmap *self, size_t pos)
if (block >= self->word_alloc) {
size_t old_size = self->word_alloc;
self->word_alloc = block * 2;
self->words = ewah_realloc(self->words,
self->word_alloc * sizeof(eword_t));
REALLOC_ARRAY(self->words, self->word_alloc);
memset(self->words + old_size, 0x0,
(self->word_alloc - old_size) * sizeof(eword_t));
}
@ -100,12 +98,7 @@ struct bitmap *ewah_to_bitmap(struct ewah_bitmap *ewah)
ewah_iterator_init(&it, ewah);
while (ewah_iterator_next(&blowup, &it)) {
if (i >= bitmap->word_alloc) {
bitmap->word_alloc *= 1.5;
bitmap->words = ewah_realloc(
bitmap->words, bitmap->word_alloc * sizeof(eword_t));
}
ALLOC_GROW(bitmap->words, i + 1, bitmap->word_alloc);
bitmap->words[i++] = blowup;
}
@ -134,8 +127,7 @@ void bitmap_or_ewah(struct bitmap *self, struct ewah_bitmap *other)
if (self->word_alloc < other_final) {
self->word_alloc = other_final;
self->words = ewah_realloc(self->words,
self->word_alloc * sizeof(eword_t));
REALLOC_ARRAY(self->words, self->word_alloc);
memset(self->words + original_size, 0x0,
(self->word_alloc - original_size) * sizeof(eword_t));
}

View File

@ -39,8 +39,7 @@ static inline void buffer_grow(struct ewah_bitmap *self, size_t new_size)
return;
self->alloc_size = new_size;
self->buffer = ewah_realloc(self->buffer,
self->alloc_size * sizeof(eword_t));
REALLOC_ARRAY(self->buffer, self->alloc_size);
self->rlw = self->buffer + (rlw_offset / sizeof(eword_t));
}
@ -282,12 +281,9 @@ struct ewah_bitmap *ewah_new(void)
{
struct ewah_bitmap *self;
self = ewah_malloc(sizeof(struct ewah_bitmap));
if (self == NULL)
return NULL;
self->buffer = ewah_malloc(32 * sizeof(eword_t));
self = xmalloc(sizeof(struct ewah_bitmap));
self->alloc_size = 32;
ALLOC_ARRAY(self->buffer, self->alloc_size);
ewah_clear(self);
return self;

View File

@ -134,11 +134,7 @@ int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len)
self->buffer_size = self->alloc_size = get_be32(ptr);
ptr += sizeof(uint32_t);
self->buffer = ewah_realloc(self->buffer,
self->alloc_size * sizeof(eword_t));
if (!self->buffer)
return -1;
REALLOC_ARRAY(self->buffer, self->alloc_size);
/*
* Copy the raw data for the bitmap as a whole chunk;
@ -180,11 +176,7 @@ int ewah_deserialize(struct ewah_bitmap *self, int fd)
return -1;
self->buffer_size = self->alloc_size = (size_t)ntohl(word_count);
self->buffer = ewah_realloc(self->buffer,
self->alloc_size * sizeof(eword_t));
if (!self->buffer)
return -1;
REALLOC_ARRAY(self->buffer, self->alloc_size);
/** 64 bit x N -- compressed words */
buffer = self->buffer;

View File

@ -20,16 +20,6 @@
#ifndef __EWOK_BITMAP_H__
#define __EWOK_BITMAP_H__
#ifndef ewah_malloc
# define ewah_malloc xmalloc
#endif
#ifndef ewah_realloc
# define ewah_realloc xrealloc
#endif
#ifndef ewah_calloc
# define ewah_calloc xcalloc
#endif
struct strbuf;
typedef uint64_t eword_t;
#define BITS_IN_EWORD (sizeof(eword_t) * 8)

View File

@ -1,6 +1,7 @@
#include "cache.h"
#include "exec_cmd.h"
#include "quote.h"
#include "argv-array.h"
#define MAX_ARGS 32
static const char *argv_exec_path;
@ -105,32 +106,25 @@ void setup_path(void)
strbuf_release(&new_path);
}
const char **prepare_git_cmd(const char **argv)
const char **prepare_git_cmd(struct argv_array *out, const char **argv)
{
int argc;
const char **nargv;
for (argc = 0; argv[argc]; argc++)
; /* just counting */
nargv = xmalloc(sizeof(*nargv) * (argc + 2));
nargv[0] = "git";
for (argc = 0; argv[argc]; argc++)
nargv[argc + 1] = argv[argc];
nargv[argc + 1] = NULL;
return nargv;
argv_array_push(out, "git");
argv_array_pushv(out, argv);
return out->argv;
}
int execv_git_cmd(const char **argv) {
const char **nargv = prepare_git_cmd(argv);
trace_argv_printf(nargv, "trace: exec:");
struct argv_array nargv = ARGV_ARRAY_INIT;
prepare_git_cmd(&nargv, argv);
trace_argv_printf(nargv.argv, "trace: exec:");
/* execvp() can only ever return if it fails */
sane_execvp("git", (char **)nargv);
sane_execvp("git", (char **)nargv.argv);
trace_printf("trace: exec failed: %s\n", strerror(errno));
free(nargv);
argv_array_clear(&nargv);
return -1;
}

View File

@ -1,11 +1,13 @@
#ifndef GIT_EXEC_CMD_H
#define GIT_EXEC_CMD_H
struct argv_array;
extern void git_set_argv_exec_path(const char *exec_path);
extern const char *git_extract_argv0_path(const char *path);
extern const char *git_exec_path(void);
extern void setup_path(void);
extern const char **prepare_git_cmd(const char **argv);
extern const char **prepare_git_cmd(struct argv_array *out, const char **argv);
extern int execv_git_cmd(const char **argv); /* NULL terminated */
LAST_ARG_MUST_BE_NULL
extern int execl_git_cmd(const char *cmd, ...);

View File

@ -622,7 +622,7 @@ static void *pool_alloc(size_t len)
return xmalloc(len);
}
total_allocd += sizeof(struct mem_pool) + mem_pool_alloc;
p = xmalloc(sizeof(struct mem_pool) + mem_pool_alloc);
p = xmalloc(st_add(sizeof(struct mem_pool), mem_pool_alloc));
p->next_pool = mem_pool;
p->next_free = (char *) p->space;
p->end = p->next_free + mem_pool_alloc;
@ -814,7 +814,8 @@ static struct tree_entry *new_tree_entry(void)
if (!avail_tree_entry) {
unsigned int n = tree_entry_alloc;
total_allocd += n * sizeof(struct tree_entry);
avail_tree_entry = e = xmalloc(n * sizeof(struct tree_entry));
ALLOC_ARRAY(e, n);
avail_tree_entry = e;
while (n-- > 1) {
*((void**)e) = e + 1;
e++;
@ -864,15 +865,12 @@ static void start_packfile(void)
{
static char tmp_file[PATH_MAX];
struct packed_git *p;
int namelen;
struct pack_header hdr;
int pack_fd;
pack_fd = odb_mkstemp(tmp_file, sizeof(tmp_file),
"pack/tmp_pack_XXXXXX");
namelen = strlen(tmp_file) + 2;
p = xcalloc(1, sizeof(*p) + namelen);
xsnprintf(p->pack_name, namelen, "%s", tmp_file);
FLEX_ALLOC_STR(p, pack_name, tmp_file);
p->pack_fd = pack_fd;
p->do_not_close = 1;
pack_file = sha1fd(pack_fd, p->pack_name);
@ -898,7 +896,7 @@ static const char *create_index(void)
struct object_entry_pool *o;
/* Build the table of object IDs. */
idx = xmalloc(object_count * sizeof(*idx));
ALLOC_ARRAY(idx, object_count);
c = idx;
for (o = blocks; o; o = o->next_pool)
for (e = o->next_free; e-- != o->entries;)

3
fsck.c
View File

@ -199,7 +199,8 @@ void fsck_set_msg_type(struct fsck_options *options,
if (!options->msg_type) {
int i;
int *msg_type = xmalloc(sizeof(int) * FSCK_MSG_MAX);
int *msg_type;
ALLOC_ARRAY(msg_type, FSCK_MSG_MAX);
for (i = 0; i < FSCK_MSG_MAX; i++)
msg_type[i] = fsck_msg_type(i, options);
options->msg_type = msg_type;

View File

@ -96,6 +96,14 @@
#define unsigned_add_overflows(a, b) \
((b) > maximum_unsigned_value_of_type(a) - (a))
/*
* Returns true if the multiplication of "a" and "b" will
* overflow. The types of "a" and "b" must match and must be unsigned.
* Note that this macro evaluates "a" twice!
*/
#define unsigned_mult_overflows(a, b) \
((a) && (b) > maximum_unsigned_value_of_type(a) / (a))
#ifdef __GNUC__
#define TYPEOF(x) (__typeof__(x))
#else
@ -669,7 +677,6 @@ extern int git_vsnprintf(char *str, size_t maxsize,
#ifdef __GLIBC_PREREQ
#if __GLIBC_PREREQ(2, 1)
#define HAVE_STRCHRNUL
#define HAVE_MEMPCPY
#endif
#endif
@ -683,14 +690,6 @@ static inline char *gitstrchrnul(const char *s, int c)
}
#endif
#ifndef HAVE_MEMPCPY
#define mempcpy gitmempcpy
static inline void *gitmempcpy(void *dest, const void *src, size_t n)
{
return (char *)memcpy(dest, src, n) + n;
}
#endif
#ifdef NO_INET_PTON
int inet_pton(int af, const char *src, void *dst);
#endif
@ -709,6 +708,32 @@ extern void release_pack_memory(size_t);
typedef void (*try_to_free_t)(size_t);
extern try_to_free_t set_try_to_free_routine(try_to_free_t);
static inline size_t st_add(size_t a, size_t b)
{
if (unsigned_add_overflows(a, b))
die("size_t overflow: %"PRIuMAX" + %"PRIuMAX,
(uintmax_t)a, (uintmax_t)b);
return a + b;
}
#define st_add3(a,b,c) st_add((a),st_add((b),(c)))
#define st_add4(a,b,c,d) st_add((a),st_add3((b),(c),(d)))
static inline size_t st_mult(size_t a, size_t b)
{
if (unsigned_mult_overflows(a, b))
die("size_t overflow: %"PRIuMAX" * %"PRIuMAX,
(uintmax_t)a, (uintmax_t)b);
return a * b;
}
static inline size_t st_sub(size_t a, size_t b)
{
if (a < b)
die("size_t underflow: %"PRIuMAX" - %"PRIuMAX,
(uintmax_t)a, (uintmax_t)b);
return a - b;
}
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
# define xalloca(size) (alloca(size))
@ -741,7 +766,70 @@ extern int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1);
extern char *xgetcwd(void);
extern FILE *fopen_for_writing(const char *path);
#define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), (alloc) * sizeof(*(x)))
#define ALLOC_ARRAY(x, alloc) (x) = xmalloc(st_mult(sizeof(*(x)), (alloc)))
#define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), st_mult(sizeof(*(x)), (alloc)))
/*
* These functions help you allocate structs with flex arrays, and copy
* the data directly into the array. For example, if you had:
*
* struct foo {
* int bar;
* char name[FLEX_ARRAY];
* };
*
* you can do:
*
* struct foo *f;
* FLEX_ALLOC_MEM(f, name, src, len);
*
* to allocate a "foo" with the contents of "src" in the "name" field.
* The resulting struct is automatically zero'd, and the flex-array field
* is NUL-terminated (whether the incoming src buffer was or not).
*
* The FLEXPTR_* variants operate on structs that don't use flex-arrays,
* but do want to store a pointer to some extra data in the same allocated
* block. For example, if you have:
*
* struct foo {
* char *name;
* int bar;
* };
*
* you can do:
*
* struct foo *f;
* FLEX_ALLOC_STR(f, name, src);
*
* and "name" will point to a block of memory after the struct, which will be
* freed along with the struct (but the pointer can be repointed anywhere).
*
* The *_STR variants accept a string parameter rather than a ptr/len
* combination.
*
* Note that these macros will evaluate the first parameter multiple
* times, and it must be assignable as an lvalue.
*/
#define FLEX_ALLOC_MEM(x, flexname, buf, len) do { \
(x) = NULL; /* silence -Wuninitialized for offset calculation */ \
(x) = xalloc_flex(sizeof(*(x)), (char *)(&((x)->flexname)) - (char *)(x), (buf), (len)); \
} while (0)
#define FLEXPTR_ALLOC_MEM(x, ptrname, buf, len) do { \
(x) = xalloc_flex(sizeof(*(x)), sizeof(*(x)), (buf), (len)); \
(x)->ptrname = (void *)((x)+1); \
} while(0)
#define FLEX_ALLOC_STR(x, flexname, str) \
FLEX_ALLOC_MEM((x), flexname, (str), strlen(str))
#define FLEXPTR_ALLOC_STR(x, ptrname, str) \
FLEXPTR_ALLOC_MEM((x), ptrname, (str), strlen(str))
static inline void *xalloc_flex(size_t base_len, size_t offset,
const void *src, size_t src_len)
{
unsigned char *ret = xcalloc(1, st_add3(base_len, src_len, 1));
memcpy(ret + offset, src, src_len);
return ret;
}
static inline char *xstrdup_or_null(const char *str)
{

14
git.c
View File

@ -247,20 +247,16 @@ static int handle_alias(int *argcp, const char ***argv)
alias_string = alias_lookup(alias_command);
if (alias_string) {
if (alias_string[0] == '!') {
const char **alias_argv;
int argc = *argcp, i;
struct child_process child = CHILD_PROCESS_INIT;
commit_pager_choice();
restore_env(1);
/* build alias_argv */
alias_argv = xmalloc(sizeof(*alias_argv) * (argc + 1));
alias_argv[0] = alias_string + 1;
for (i = 1; i < argc; ++i)
alias_argv[i] = (*argv)[i];
alias_argv[argc] = NULL;
child.use_shell = 1;
argv_array_push(&child.args, alias_string + 1);
argv_array_pushv(&child.args, (*argv) + 1);
ret = run_command_v_opt(alias_argv, RUN_USING_SHELL);
ret = run_command(&child);
if (ret >= 0) /* normal exit */
exit(ret);

10
graph.c
View File

@ -234,12 +234,10 @@ struct git_graph *graph_init(struct rev_info *opt)
* We'll automatically grow columns later if we need more room.
*/
graph->column_capacity = 30;
graph->columns = xmalloc(sizeof(struct column) *
graph->column_capacity);
graph->new_columns = xmalloc(sizeof(struct column) *
graph->column_capacity);
graph->mapping = xmalloc(sizeof(int) * 2 * graph->column_capacity);
graph->new_mapping = xmalloc(sizeof(int) * 2 * graph->column_capacity);
ALLOC_ARRAY(graph->columns, graph->column_capacity);
ALLOC_ARRAY(graph->new_columns, graph->column_capacity);
ALLOC_ARRAY(graph->mapping, 2 * graph->column_capacity);
ALLOC_ARRAY(graph->new_mapping, 2 * graph->column_capacity);
/*
* The diff output prefix callback, with this we can make

3
grep.c
View File

@ -1741,7 +1741,7 @@ static int grep_source_load_file(struct grep_source *gs)
i = open(filename, O_RDONLY);
if (i < 0)
goto err_ret;
data = xmalloc(size + 1);
data = xmallocz(size);
if (st.st_size != read_in_full(i, data, size)) {
error(_("'%s': short read %s"), filename, strerror(errno));
close(i);
@ -1749,7 +1749,6 @@ static int grep_source_load_file(struct grep_source *gs)
return -1;
}
close(i);
data[size] = 0;
gs->buf = data;
gs->size = size;

View File

@ -256,10 +256,9 @@ const void *memintern(const void *data, size_t len)
e = hashmap_get(&map, &key, data);
if (!e) {
/* not found: create it */
e = xmallocz(sizeof(struct pool_entry) + len);
FLEX_ALLOC_MEM(e, data, data, len);
hashmap_entry_init(e, key.ent.hash);
e->len = len;
memcpy(e->data, data, len);
hashmap_add(&map, e);
}
return e->data;

6
help.c
View File

@ -11,11 +11,9 @@
void add_cmdname(struct cmdnames *cmds, const char *name, int len)
{
struct cmdname *ent = xmalloc(sizeof(*ent) + len + 1);
struct cmdname *ent;
FLEX_ALLOC_MEM(ent, name, name, len);
ent->len = len;
memcpy(ent->name, name, len);
ent->name[len] = 0;
ALLOC_GROW(cmds->names, cmds->cnt + 1, cmds->alloc);
cmds->names[cmds->cnt++] = ent;

View File

@ -892,12 +892,11 @@ static char *cram(const char *challenge_64, const char *user, const char *pass)
response = xstrfmt("%s %s", user, hex);
resp_len = strlen(response) + 1;
response_64 = xmalloc(ENCODED_SIZE(resp_len) + 1);
response_64 = xmallocz(ENCODED_SIZE(resp_len));
encoded_len = EVP_EncodeBlock((unsigned char *)response_64,
(unsigned char *)response, resp_len);
if (encoded_len < 0)
die("EVP_EncodeBlock error");
response_64[encoded_len] = '\0';
return (char *)response_64;
}
@ -1188,7 +1187,7 @@ static void lf_to_crlf(struct strbuf *msg)
j++;
}
new = xmalloc(j + 1);
new = xmallocz(j);
/*
* Second pass: write the new string. Note that this loop is

View File

@ -117,7 +117,7 @@ static const double __ac_HASH_UPPER = 0.77;
if (new_n_buckets < 4) new_n_buckets = 4; \
if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \
else { /* hash table size to be changed (shrink or expand); rehash */ \
new_flags = (khint32_t*)xmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
ALLOC_ARRAY(new_flags, __ac_fsize(new_n_buckets)); \
if (!new_flags) return -1; \
memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
if (h->n_buckets < new_n_buckets) { /* expand */ \

View File

@ -42,11 +42,13 @@ int levenshtein(const char *string1, const char *string2,
int w, int s, int a, int d)
{
int len1 = strlen(string1), len2 = strlen(string2);
int *row0 = xmalloc(sizeof(int) * (len2 + 1));
int *row1 = xmalloc(sizeof(int) * (len2 + 1));
int *row2 = xmalloc(sizeof(int) * (len2 + 1));
int *row0, *row1, *row2;
int i, j;
ALLOC_ARRAY(row0, len2 + 1);
ALLOC_ARRAY(row1, len2 + 1);
ALLOC_ARRAY(row2, len2 + 1);
for (j = 0; j <= len2; j++)
row1[j] = j * a;
for (i = 0; i < len1; i++) {

View File

@ -14,6 +14,7 @@
#include "graph.h"
#include "userdiff.h"
#include "line-log.h"
#include "argv-array.h"
static void range_set_grow(struct range_set *rs, size_t extra)
{
@ -521,7 +522,7 @@ static void fill_line_ends(struct diff_filespec *spec, long *lines,
if (diff_populate_filespec(spec, 0))
die("Cannot read blob %s", sha1_to_hex(spec->sha1));
ends = xmalloc(size * sizeof(*ends));
ALLOC_ARRAY(ends, size);
ends[cur++] = 0;
data = spec->data;
while (num < spec->size) {
@ -746,22 +747,17 @@ void line_log_init(struct rev_info *rev, const char *prefix, struct string_list
add_line_range(rev, commit, range);
if (!rev->diffopt.detect_rename) {
int i, count = 0;
struct line_log_data *r = range;
struct line_log_data *r;
struct argv_array array = ARGV_ARRAY_INIT;
const char **paths;
while (r) {
count++;
r = r->next;
}
paths = xmalloc((count+1)*sizeof(char *));
r = range;
for (i = 0; i < count; i++) {
paths[i] = xstrdup(r->path);
r = r->next;
}
paths[count] = NULL;
for (r = range; r; r = r->next)
argv_array_push(&array, r->path);
paths = argv_array_detach(&array);
parse_pathspec(&rev->diffopt.pathspec, 0,
PATHSPEC_PREFER_FULL, "", paths);
/* strings are now owned by pathspec */
free(paths);
}
}
@ -1146,9 +1142,9 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
if (nparents > 1 && rev->first_parent_only)
nparents = 1;
diffqueues = xmalloc(nparents * sizeof(*diffqueues));
cand = xmalloc(nparents * sizeof(*cand));
parents = xmalloc(nparents * sizeof(*parents));
ALLOC_ARRAY(diffqueues, nparents);
ALLOC_ARRAY(cand, nparents);
ALLOC_ARRAY(parents, nparents);
p = commit->parents;
for (i = 0; i < nparents; i++) {

View File

@ -205,7 +205,7 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,
if (fstat(fd, &st))
goto close_bad;
result->size = st.st_size;
result->ptr = xmalloc(result->size + 1);
result->ptr = xmallocz(result->size);
if (read_in_full(fd, result->ptr, result->size) != result->size) {
free(result->ptr);
result->ptr = NULL;

View File

@ -77,9 +77,8 @@ int parse_decorate_color_config(const char *var, const char *slot_name, const ch
void add_name_decoration(enum decoration_type type, const char *name, struct object *obj)
{
int nlen = strlen(name);
struct name_decoration *res = xmalloc(sizeof(*res) + nlen + 1);
memcpy(res->name, name, nlen + 1);
struct name_decoration *res;
FLEX_ALLOC_STR(res, name, name);
res->type = type;
res->next = add_decoration(&name_decoration, obj, res);
}

View File

@ -55,10 +55,9 @@ static struct dir_entry *hash_dir_entry(struct index_state *istate,
dir = find_dir_entry(istate, ce->name, namelen);
if (!dir) {
/* not found, create it and add to hash table */
dir = xcalloc(1, sizeof(struct dir_entry) + namelen + 1);
FLEX_ALLOC_MEM(dir, name, ce->name, namelen);
hashmap_entry_init(dir, memihash(ce->name, namelen));
dir->namelen = namelen;
strncpy(dir->name, ce->name, namelen);
hashmap_add(&istate->dir_hash, dir);
/* recursively add missing parent directories */

View File

@ -1035,7 +1035,7 @@ struct notes_tree **load_notes_trees(struct string_list *refs, int flags)
struct string_list_item *item;
int counter = 0;
struct notes_tree **trees;
trees = xmalloc((refs->nr+1) * sizeof(struct notes_tree *));
ALLOC_ARRAY(trees, refs->nr + 1);
for_each_string_list_item(item, refs) {
struct notes_tree *t = xcalloc(1, sizeof(struct notes_tree));
init_notes(t, item->string, combine_notes_ignore, flags);

View File

@ -89,7 +89,7 @@ static int verify_packfile(struct packed_git *p,
* we do not do scan-streaming check on the pack file.
*/
nr_objects = p->num_objects;
entries = xmalloc((nr_objects + 1) * sizeof(*entries));
ALLOC_ARRAY(entries, nr_objects + 1);
entries[nr_objects].offset = pack_sig_ofs;
/* first sort entries by pack offset, since unpacking them is more efficient that way */
for (i = 0; i < nr_objects; i++) {

View File

@ -44,10 +44,14 @@ static void sort_revindex(struct revindex_entry *entries, unsigned n, off_t max)
* keep track of them with alias pointers, always sorting from "from"
* to "to".
*/
struct revindex_entry *tmp = xmalloc(n * sizeof(*tmp));
struct revindex_entry *from = entries, *to = tmp;
struct revindex_entry *tmp, *from, *to;
int bits;
unsigned *pos = xmalloc(BUCKETS * sizeof(*pos));
unsigned *pos;
ALLOC_ARRAY(pos, BUCKETS);
ALLOC_ARRAY(tmp, n);
from = entries;
to = tmp;
/*
* If (max >> bits) is zero, then we know that the radix digit we are
@ -121,7 +125,7 @@ static void create_pack_revindex(struct packed_git *p)
unsigned i;
const char *index = p->index_data;
p->revindex = xmalloc(sizeof(*p->revindex) * (num_ent + 1));
ALLOC_ARRAY(p->revindex, num_ent + 1);
index += 4 * 256;
if (p->index_version > 1) {

View File

@ -406,7 +406,8 @@ void parse_pathspec(struct pathspec *pathspec,
n++;
pathspec->nr = n;
pathspec->items = item = xmalloc(sizeof(*item) * n);
ALLOC_ARRAY(pathspec->items, n);
item = pathspec->items;
pathspec->_raw = argv;
prefixlen = prefix ? strlen(prefix) : 0;
@ -483,7 +484,7 @@ const char **get_pathspec(const char *prefix, const char **pathspec)
void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
{
*dst = *src;
dst->items = xmalloc(sizeof(struct pathspec_item) * dst->nr);
ALLOC_ARRAY(dst->items, dst->nr);
memcpy(dst->items, src->items,
sizeof(struct pathspec_item) * dst->nr);
}

View File

@ -247,7 +247,7 @@ void stop_progress_msg(struct progress **p_progress, const char *msg)
size_t len = strlen(msg) + 5;
struct throughput *tp = progress->throughput;
bufp = (len < sizeof(buf)) ? buf : xmalloc(len + 1);
bufp = (len < sizeof(buf)) ? buf : xmallocz(len);
if (tp) {
unsigned int rate = !tp->avg_misecs ? 0 :
tp->avg_bytes / tp->avg_misecs;

View File

@ -1321,10 +1321,8 @@ static struct ref_array_item *new_ref_array_item(const char *refname,
const unsigned char *objectname,
int flag)
{
size_t len = strlen(refname);
struct ref_array_item *ref = xcalloc(1, sizeof(struct ref_array_item) + len + 1);
memcpy(ref->refname, refname, len);
ref->refname[len] = '\0';
struct ref_array_item *ref;
FLEX_ALLOC_STR(ref, refname, refname);
hashcpy(ref->objectname, objectname);
ref->flag = flag;

10
refs.c
View File

@ -124,7 +124,7 @@ int refname_is_safe(const char *refname)
char *buf;
int result;
buf = xmalloc(strlen(refname) + 1);
buf = xmallocz(strlen(refname));
/*
* Does the refname try to escape refs/?
* For example: refs/foo/../bar is safe but refs/foo/../../bar
@ -761,10 +761,8 @@ void ref_transaction_free(struct ref_transaction *transaction)
static struct ref_update *add_update(struct ref_transaction *transaction,
const char *refname)
{
size_t len = strlen(refname) + 1;
struct ref_update *update = xcalloc(1, sizeof(*update) + len);
memcpy((char *)update->refname, refname, len); /* includes NUL */
struct ref_update *update;
FLEX_ALLOC_STR(update, refname, refname);
ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
transaction->updates[transaction->nr++] = update;
return update;
@ -908,7 +906,7 @@ char *shorten_unambiguous_ref(const char *refname, int strict)
/* -2 for strlen("%.*s") - strlen("%s"); +1 for NUL */
total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1;
scanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len);
scanf_fmts = xmalloc(st_add(st_mult(nr_rules, sizeof(char *)), total_len));
offset = 0;
for (i = 0; i < nr_rules; i++) {

View File

@ -199,17 +199,14 @@ static struct ref_entry *create_ref_entry(const char *refname,
const unsigned char *sha1, int flag,
int check_name)
{
int len;
struct ref_entry *ref;
if (check_name &&
check_refname_format(refname, REFNAME_ALLOW_ONELEVEL))
die("Reference has invalid format: '%s'", refname);
len = strlen(refname) + 1;
ref = xmalloc(sizeof(struct ref_entry) + len);
FLEX_ALLOC_STR(ref, name, refname);
hashcpy(ref->u.value.oid.hash, sha1);
oidclr(&ref->u.value.peeled);
memcpy(ref->name, refname, len);
ref->flag = flag;
return ref;
}
@ -268,9 +265,7 @@ static struct ref_entry *create_dir_entry(struct ref_cache *ref_cache,
int incomplete)
{
struct ref_entry *direntry;
direntry = xcalloc(1, sizeof(struct ref_entry) + len + 1);
memcpy(direntry->name, dirname, len);
direntry->name[len] = '\0';
FLEX_ALLOC_MEM(direntry, name, dirname, len);
direntry->u.subdir.ref_cache = ref_cache;
direntry->flag = REF_DIR | (incomplete ? REF_INCOMPLETE : 0);
return direntry;
@ -939,13 +934,10 @@ static void clear_loose_ref_cache(struct ref_cache *refs)
*/
static struct ref_cache *create_ref_cache(const char *submodule)
{
int len;
struct ref_cache *refs;
if (!submodule)
submodule = "";
len = strlen(submodule) + 1;
refs = xcalloc(1, sizeof(struct ref_cache) + len);
memcpy(refs->name, submodule, len);
FLEX_ALLOC_STR(refs, name, submodule);
refs->next = submodule_ref_caches;
submodule_ref_caches = refs;
return refs;
@ -2197,10 +2189,9 @@ static int pack_if_possible_fn(struct ref_entry *entry, void *cb_data)
/* Schedule the loose reference for pruning if requested. */
if ((cb->flags & PACK_REFS_PRUNE)) {
int namelen = strlen(entry->name) + 1;
struct ref_to_prune *n = xcalloc(1, sizeof(*n) + namelen);
struct ref_to_prune *n;
FLEX_ALLOC_STR(n, name, entry->name);
hashcpy(n->sha1, entry->u.value.oid.hash);
memcpy(n->name, entry->name, namelen); /* includes NUL */
n->next = cb->ref_to_prune;
cb->ref_to_prune = n;
}

View File

@ -721,9 +721,10 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
static int fetch_dumb(int nr_heads, struct ref **to_fetch)
{
struct walker *walker;
char **targets = xmalloc(nr_heads * sizeof(char*));
char **targets;
int ret, i;
ALLOC_ARRAY(targets, nr_heads);
if (options.depth)
die("dumb http transport does not support --depth");
for (i = 0; i < nr_heads; i++)
@ -870,23 +871,22 @@ static void parse_fetch(struct strbuf *buf)
static int push_dav(int nr_spec, char **specs)
{
const char **argv = xmalloc((10 + nr_spec) * sizeof(char*));
int argc = 0, i;
struct child_process child = CHILD_PROCESS_INIT;
size_t i;
argv[argc++] = "http-push";
argv[argc++] = "--helper-status";
child.git_cmd = 1;
argv_array_push(&child.args, "http-push");
argv_array_push(&child.args, "--helper-status");
if (options.dry_run)
argv[argc++] = "--dry-run";
argv_array_push(&child.args, "--dry-run");
if (options.verbosity > 1)
argv[argc++] = "--verbose";
argv[argc++] = url.buf;
argv_array_push(&child.args, "--verbose");
argv_array_push(&child.args, url.buf);
for (i = 0; i < nr_spec; i++)
argv[argc++] = specs[i];
argv[argc++] = NULL;
argv_array_push(&child.args, specs[i]);
if (run_command_v_opt(argv, RUN_GIT_CMD))
die("git-%s failed", argv[0]);
free(argv);
if (run_command(&child))
die("git-http-push failed");
return 0;
}

View File

@ -917,7 +917,7 @@ static struct ref *alloc_ref_with_prefix(const char *prefix, size_t prefixlen,
const char *name)
{
size_t len = strlen(name);
struct ref *ref = xcalloc(1, sizeof(struct ref) + prefixlen + len + 1);
struct ref *ref = xcalloc(1, st_add4(sizeof(*ref), prefixlen, len, 1));
memcpy(ref->name, prefix, prefixlen);
memcpy(ref->name + prefixlen, name, len);
return ref;
@ -934,9 +934,9 @@ struct ref *copy_ref(const struct ref *ref)
size_t len;
if (!ref)
return NULL;
len = strlen(ref->name);
cpy = xmalloc(sizeof(struct ref) + len + 1);
memcpy(cpy, ref, sizeof(struct ref) + len + 1);
len = st_add3(sizeof(struct ref), strlen(ref->name), 1);
cpy = xmalloc(len);
memcpy(cpy, ref, len);
cpy->next = NULL;
cpy->symref = xstrdup_or_null(ref->symref);
cpy->remote_status = xstrdup_or_null(ref->remote_status);
@ -2122,16 +2122,13 @@ static int one_local_ref(const char *refname, const struct object_id *oid,
{
struct ref ***local_tail = cb_data;
struct ref *ref;
int len;
/* we already know it starts with refs/ to get here */
if (check_refname_format(refname + 5, 0))
return 0;
len = strlen(refname) + 1;
ref = xcalloc(1, sizeof(*ref) + len);
ref = alloc_ref(refname);
oidcpy(&ref->new_oid, oid);
memcpy(ref->name, refname, len);
**local_tail = ref;
*local_tail = &ref->next;
return 0;

View File

@ -484,7 +484,7 @@ struct treesame_state {
static struct treesame_state *initialise_treesame(struct rev_info *revs, struct commit *commit)
{
unsigned n = commit_list_count(commit->parents);
struct treesame_state *st = xcalloc(1, sizeof(*st) + n);
struct treesame_state *st = xcalloc(1, st_add(sizeof(*st), n));
st->nparents = n;
add_decoration(&revs->treesame, &commit->object, st);
return st;

View File

@ -160,50 +160,41 @@ int sane_execvp(const char *file, char * const argv[])
return -1;
}
static const char **prepare_shell_cmd(const char **argv)
static const char **prepare_shell_cmd(struct argv_array *out, const char **argv)
{
int argc, nargc = 0;
const char **nargv;
for (argc = 0; argv[argc]; argc++)
; /* just counting */
/* +1 for NULL, +3 for "sh -c" plus extra $0 */
nargv = xmalloc(sizeof(*nargv) * (argc + 1 + 3));
if (argc < 1)
if (!argv[0])
die("BUG: shell command is empty");
if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
#ifndef GIT_WINDOWS_NATIVE
nargv[nargc++] = SHELL_PATH;
argv_array_push(out, SHELL_PATH);
#else
nargv[nargc++] = "sh";
argv_array_push(out, "sh");
#endif
nargv[nargc++] = "-c";
argv_array_push(out, "-c");
if (argc < 2)
nargv[nargc++] = argv[0];
else {
struct strbuf arg0 = STRBUF_INIT;
strbuf_addf(&arg0, "%s \"$@\"", argv[0]);
nargv[nargc++] = strbuf_detach(&arg0, NULL);
}
/*
* If we have no extra arguments, we do not even need to
* bother with the "$@" magic.
*/
if (!argv[1])
argv_array_push(out, argv[0]);
else
argv_array_pushf(out, "%s \"$@\"", argv[0]);
}
for (argc = 0; argv[argc]; argc++)
nargv[nargc++] = argv[argc];
nargv[nargc] = NULL;
return nargv;
argv_array_pushv(out, argv);
return out->argv;
}
#ifndef GIT_WINDOWS_NATIVE
static int execv_shell_cmd(const char **argv)
{
const char **nargv = prepare_shell_cmd(argv);
trace_argv_printf(nargv, "trace: exec:");
sane_execvp(nargv[0], (char **)nargv);
free(nargv);
struct argv_array nargv = ARGV_ARRAY_INIT;
prepare_shell_cmd(&nargv, argv);
trace_argv_printf(nargv.argv, "trace: exec:");
sane_execvp(nargv.argv[0], (char **)nargv.argv);
argv_array_clear(&nargv);
return -1;
}
#endif
@ -457,6 +448,7 @@ int start_command(struct child_process *cmd)
{
int fhin = 0, fhout = 1, fherr = 2;
const char **sargv = cmd->argv;
struct argv_array nargv = ARGV_ARRAY_INIT;
if (cmd->no_stdin)
fhin = open("/dev/null", O_RDWR);
@ -482,9 +474,9 @@ int start_command(struct child_process *cmd)
fhout = dup(cmd->out);
if (cmd->git_cmd)
cmd->argv = prepare_git_cmd(cmd->argv);
cmd->argv = prepare_git_cmd(&nargv, cmd->argv);
else if (cmd->use_shell)
cmd->argv = prepare_shell_cmd(cmd->argv);
cmd->argv = prepare_shell_cmd(&nargv, cmd->argv);
cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, (char**) cmd->env,
cmd->dir, fhin, fhout, fherr);
@ -494,9 +486,7 @@ int start_command(struct child_process *cmd)
if (cmd->clean_on_exit && cmd->pid >= 0)
mark_child_for_cleanup(cmd->pid);
if (cmd->git_cmd)
free(cmd->argv);
argv_array_clear(&nargv);
cmd->argv = sargv;
if (fhin != 0)
close(fhin);

View File

@ -124,42 +124,33 @@ static const char *action_name(const struct replay_opts *opts)
struct commit_message {
char *parent_label;
const char *label;
const char *subject;
char *label;
char *subject;
const char *message;
};
static int get_message(struct commit *commit, struct commit_message *out)
{
const char *abbrev, *subject;
int abbrev_len, subject_len;
char *q;
int subject_len;
if (!git_commit_encoding)
git_commit_encoding = "UTF-8";
out->message = logmsg_reencode(commit, NULL, git_commit_encoding);
out->message = logmsg_reencode(commit, NULL, get_commit_output_encoding());
abbrev = find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV);
abbrev_len = strlen(abbrev);
subject_len = find_commit_subject(out->message, &subject);
out->parent_label = xmalloc(strlen("parent of ") + abbrev_len +
strlen("... ") + subject_len + 1);
q = out->parent_label;
q = mempcpy(q, "parent of ", strlen("parent of "));
out->label = q;
q = mempcpy(q, abbrev, abbrev_len);
q = mempcpy(q, "... ", strlen("... "));
out->subject = q;
q = mempcpy(q, subject, subject_len);
*q = '\0';
out->subject = xmemdupz(subject, subject_len);
out->label = xstrfmt("%s... %s", abbrev, out->subject);
out->parent_label = xstrfmt("parent of %s", out->label);
return 0;
}
static void free_message(struct commit *commit, struct commit_message *msg)
{
free(msg->parent_label);
free(msg->label);
free(msg->subject);
unuse_commit_buffer(commit, msg->message);
}

View File

@ -88,7 +88,7 @@ char *prefix_path_gently(const char *prefix, int len,
const char *orig = path;
char *sanitized;
if (is_absolute_path(orig)) {
sanitized = xmalloc(strlen(path) + 1);
sanitized = xmallocz(strlen(path));
if (remaining_prefix)
*remaining_prefix = 0;
if (normalize_path_copy_len(sanitized, path, remaining_prefix)) {
@ -486,14 +486,13 @@ const char *read_gitfile_gently(const char *path, int *return_error_code)
error_code = READ_GITFILE_ERR_OPEN_FAILED;
goto cleanup_return;
}
buf = xmalloc(st.st_size + 1);
buf = xmallocz(st.st_size);
len = read_in_full(fd, buf, st.st_size);
close(fd);
if (len != st.st_size) {
error_code = READ_GITFILE_ERR_READ_FAILED;
goto cleanup_return;
}
buf[len] = '\0';
if (!starts_with(buf, "gitdir: ")) {
error_code = READ_GITFILE_ERR_INVALID_FORMAT;
goto cleanup_return;

View File

@ -253,7 +253,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
{
struct alternate_object_database *ent;
struct alternate_object_database *alt;
int pfxlen, entlen;
size_t pfxlen, entlen;
struct strbuf pathbuf = STRBUF_INIT;
if (!is_absolute_path(entry) && relative_base) {
@ -273,8 +273,8 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
while (pfxlen && pathbuf.buf[pfxlen-1] == '/')
pfxlen -= 1;
entlen = pfxlen + 43; /* '/' + 2 hex + '/' + 38 hex + NUL */
ent = xmalloc(sizeof(*ent) + entlen);
entlen = st_add(pfxlen, 43); /* '/' + 2 hex + '/' + 38 hex + NUL */
ent = xmalloc(st_add(sizeof(*ent), entlen));
memcpy(ent->base, pathbuf.buf, pfxlen);
strbuf_release(&pathbuf);
@ -1134,7 +1134,7 @@ unsigned char *use_pack(struct packed_git *p,
static struct packed_git *alloc_packed_git(int extra)
{
struct packed_git *p = xmalloc(sizeof(*p) + extra);
struct packed_git *p = xmalloc(st_add(sizeof(*p), extra));
memset(p, 0, sizeof(*p));
p->pack_fd = -1;
return p;
@ -1168,7 +1168,7 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
* ".pack" is long enough to hold any suffix we're adding (and
* the use xsnprintf double-checks that)
*/
alloc = path_len + strlen(".pack") + 1;
alloc = st_add3(path_len, strlen(".pack"), 1);
p = alloc_packed_git(alloc);
memcpy(p->pack_name, path, path_len);
@ -1196,7 +1196,7 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)
{
const char *path = sha1_pack_name(sha1);
int alloc = strlen(path) + 1;
size_t alloc = st_add(strlen(path), 1);
struct packed_git *p = alloc_packed_git(alloc);
memcpy(p->pack_name, path, alloc); /* includes NUL */
@ -1413,10 +1413,12 @@ static void mark_bad_packed_object(struct packed_git *p,
{
unsigned i;
for (i = 0; i < p->num_bad_objects; i++)
if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
if (!hashcmp(sha1, p->bad_object_sha1 + GIT_SHA1_RAWSZ * i))
return;
p->bad_object_sha1 = xrealloc(p->bad_object_sha1, 20 * (p->num_bad_objects + 1));
hashcpy(p->bad_object_sha1 + 20 * p->num_bad_objects, sha1);
p->bad_object_sha1 = xrealloc(p->bad_object_sha1,
st_mult(GIT_SHA1_RAWSZ,
st_add(p->num_bad_objects, 1)));
hashcpy(p->bad_object_sha1 + GIT_SHA1_RAWSZ * p->num_bad_objects, sha1);
p->num_bad_objects++;
}
@ -1942,7 +1944,7 @@ static enum object_type packed_to_object_type(struct packed_git *p,
/* Push the object we're going to leave behind */
if (poi_stack_nr >= poi_stack_alloc && poi_stack == small_poi_stack) {
poi_stack_alloc = alloc_nr(poi_stack_nr);
poi_stack = xmalloc(sizeof(off_t)*poi_stack_alloc);
ALLOC_ARRAY(poi_stack, poi_stack_alloc);
memcpy(poi_stack, small_poi_stack, sizeof(off_t)*poi_stack_nr);
} else {
ALLOC_GROW(poi_stack, poi_stack_nr+1, poi_stack_alloc);
@ -2308,7 +2310,7 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
if (delta_stack_nr >= delta_stack_alloc
&& delta_stack == small_delta_stack) {
delta_stack_alloc = alloc_nr(delta_stack_nr);
delta_stack = xmalloc(sizeof(*delta_stack)*delta_stack_alloc);
ALLOC_ARRAY(delta_stack, delta_stack_alloc);
memcpy(delta_stack, small_delta_stack,
sizeof(*delta_stack)*delta_stack_nr);
} else {

View File

@ -87,9 +87,8 @@ static void find_short_object_filename(int len, const char *hex_pfx, struct disa
* object databases including our own.
*/
const char *objdir = get_object_directory();
int objdir_len = strlen(objdir);
int entlen = objdir_len + 43;
fakeent = xmalloc(sizeof(*fakeent) + entlen);
size_t objdir_len = strlen(objdir);
fakeent = xmalloc(st_add3(sizeof(*fakeent), objdir_len, 43));
memcpy(fakeent->base, objdir, objdir_len);
fakeent->name = fakeent->base + objdir_len + 1;
fakeent->name[-1] = '/';

View File

@ -315,8 +315,8 @@ void prepare_shallow_info(struct shallow_info *info, struct sha1_array *sa)
info->shallow = sa;
if (!sa)
return;
info->ours = xmalloc(sizeof(*info->ours) * sa->nr);
info->theirs = xmalloc(sizeof(*info->theirs) * sa->nr);
ALLOC_ARRAY(info->ours, sa->nr);
ALLOC_ARRAY(info->theirs, sa->nr);
for (i = 0; i < sa->nr; i++) {
if (has_sha1_file(sa->sha1[i])) {
struct commit_graft *graft;
@ -389,7 +389,7 @@ static void paint_down(struct paint_info *info, const unsigned char *sha1,
unsigned int i, nr;
struct commit_list *head = NULL;
int bitmap_nr = (info->nr_bits + 31) / 32;
int bitmap_size = bitmap_nr * sizeof(uint32_t);
size_t bitmap_size = st_mult(bitmap_nr, sizeof(uint32_t));
uint32_t *tmp = xmalloc(bitmap_size); /* to be freed before return */
uint32_t *bitmap = paint_alloc(info);
struct commit *c = lookup_commit_reference_gently(sha1, 1);
@ -487,7 +487,7 @@ void assign_shallow_commits_to_refs(struct shallow_info *info,
struct paint_info pi;
trace_printf_key(&trace_shallow, "shallow: assign_shallow_commits_to_refs\n");
shallow = xmalloc(sizeof(*shallow) * (info->nr_ours + info->nr_theirs));
ALLOC_ARRAY(shallow, info->nr_ours + info->nr_theirs);
for (i = 0; i < info->nr_ours; i++)
shallow[nr_shallow++] = info->ours[i];
for (i = 0; i < info->nr_theirs; i++)

View File

@ -50,7 +50,8 @@ int main(int argc, char **argv)
unsigned char sha1[20];
uint32_t crc;
uint32_t off;
} *entries = xmalloc(nr * sizeof(entries[0]));
} *entries;
ALLOC_ARRAY(entries, nr);
for (i = 0; i < nr; i++)
if (fread(entries[i].sha1, 20, 1, stdin) != 1)
die("unable to read sha1 %u/%u", i, nr);

View File

@ -718,7 +718,7 @@ char *xstrdup_tolower(const char *string)
size_t len, i;
len = strlen(string);
result = xmalloc(len + 1);
result = xmallocz(len);
for (i = 0; i < len; i++)
result[i] = tolower(string[i]);
result[i] = '\0';

View File

@ -123,7 +123,7 @@ static int add_submodule_odb(const char *path)
struct strbuf objects_directory = STRBUF_INIT;
struct alternate_object_database *alt_odb;
int ret = 0;
int alloc;
size_t alloc;
strbuf_git_path_submodule(&objects_directory, path, "objects/");
if (!is_directory(objects_directory.buf)) {
@ -138,8 +138,8 @@ static int add_submodule_odb(const char *path)
objects_directory.len))
goto done;
alloc = objects_directory.len + 42; /* for "12/345..." sha1 */
alt_odb = xmalloc(sizeof(*alt_odb) + alloc);
alloc = st_add(objects_directory.len, 42); /* for "12/345..." sha1 */
alt_odb = xmalloc(st_add(sizeof(*alt_odb), alloc));
alt_odb->next = alt_odb_list;
xsnprintf(alt_odb->base, alloc, "%s", objects_directory.buf);
alt_odb->name = alt_odb->base + objects_directory.len;

View File

@ -8,21 +8,14 @@
*/
static int normalize_ceiling_entry(struct string_list_item *item, void *unused)
{
const char *ceil = item->string;
int len = strlen(ceil);
char buf[PATH_MAX+1];
char *ceil = item->string;
if (len == 0)
if (!*ceil)
die("Empty path is not supported");
if (len > PATH_MAX)
die("Path \"%s\" is too long", ceil);
if (!is_absolute_path(ceil))
die("Path \"%s\" is not absolute", ceil);
if (normalize_path_copy(buf, ceil) < 0)
if (normalize_path_copy(ceil, ceil) < 0)
die("Path \"%s\" could not be normalized", ceil);
len = strlen(buf);
free(item->string);
item->string = xstrdup(buf);
return 1;
}
@ -166,7 +159,7 @@ static struct test_data dirname_data[] = {
int main(int argc, char **argv)
{
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
char *buf = xmalloc(PATH_MAX + 1);
char *buf = xmallocz(strlen(argv[2]));
int rv = normalize_path_copy(buf, argv[2]);
if (rv)
buf = "++failed++";

View File

@ -983,7 +983,7 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs)
* This condition shouldn't be met in a non-deepening fetch
* (see builtin/fetch.c:quickfetch()).
*/
heads = xmalloc(nr_refs * sizeof(*heads));
ALLOC_ARRAY(heads, nr_refs);
for (rm = refs; rm; rm = rm->next)
heads[nr_heads++] = rm;
}
@ -1027,7 +1027,7 @@ int transport_disconnect(struct transport *transport)
*/
char *transport_anonymize_url(const char *url)
{
char *anon_url, *scheme_prefix, *anon_part;
char *scheme_prefix, *anon_part;
size_t anon_len, prefix_len = 0;
anon_part = strchr(url, '@');
@ -1061,10 +1061,8 @@ char *transport_anonymize_url(const char *url)
goto literal_copy;
prefix_len = scheme_prefix - url + 3;
}
anon_url = xcalloc(1, 1 + prefix_len + anon_len);
memcpy(anon_url, url, prefix_len);
memcpy(anon_url + prefix_len, anon_part, anon_len);
return anon_url;
return xstrfmt("%.*s%.*s", (int)prefix_len, url,
(int)anon_len, anon_part);
literal_copy:
return xstrdup(url);
}

View File

@ -124,8 +124,8 @@ static struct combine_diff_path *path_appendnew(struct combine_diff_path *last,
unsigned mode, const unsigned char *sha1)
{
struct combine_diff_path *p;
int len = base->len + pathlen;
int alloclen = combine_diff_path_size(nparent, len);
size_t len = st_add(base->len, pathlen);
size_t alloclen = combine_diff_path_size(nparent, len);
/* if last->next is !NULL - it is a pre-allocated memory, we can reuse */
p = last->next;

View File

@ -152,6 +152,9 @@ void *xcalloc(size_t nmemb, size_t size)
{
void *ret;
if (unsigned_mult_overflows(nmemb, size))
die("data too large to fit into virtual memory space");
memory_limit_check(size * nmemb, 0);
ret = calloc(nmemb, size);
if (!ret && (!nmemb || !size))

View File

@ -265,7 +265,7 @@ void xdiff_set_find_func(xdemitconf_t *xecfg, const char *value, int cflags)
for (i = 0, regs->nr = 1; value[i]; i++)
if (value[i] == '\n')
regs->nr++;
regs->array = xmalloc(regs->nr * sizeof(struct ff_reg));
ALLOC_ARRAY(regs->array, regs->nr);
for (i = 0; i < regs->nr; i++) {
struct ff_reg *reg = regs->array + i;
const char *ep = strchr(value, '\n'), *expression;