diff options
author | Junio C Hamano <gitster@pobox.com> | 2015-10-21 01:24:00 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-10-21 01:24:01 +0300 |
commit | 78891795df91a313fac590dd6cff9d8aace0dc9a (patch) | |
tree | 6acc4a524a76633c058d675481b266b1fc56a222 /refs.c | |
parent | 614a2aced1ba739dfe5bf17a85f9d376efb235b1 (diff) | |
parent | 34e02deb60b4db22243d47846eb926de9e0d1cf9 (diff) |
Merge branch 'jk/war-on-sprintf'
Many allocations that is manually counted (correctly) that are
followed by strcpy/sprintf have been replaced with a less error
prone constructs such as xstrfmt.
Macintosh-specific breakage was noticed and corrected in this
reroll.
* jk/war-on-sprintf: (70 commits)
name-rev: use strip_suffix to avoid magic numbers
use strbuf_complete to conditionally append slash
fsck: use for_each_loose_file_in_objdir
Makefile: drop D_INO_IN_DIRENT build knob
fsck: drop inode-sorting code
convert strncpy to memcpy
notes: document length of fanout path with a constant
color: add color_set helper for copying raw colors
prefer memcpy to strcpy
help: clean up kfmclient munging
receive-pack: simplify keep_arg computation
avoid sprintf and strcpy with flex arrays
use alloc_ref rather than hand-allocating "struct ref"
color: add overflow checks for parsing colors
drop strcpy in favor of raw sha1_to_hex
use sha1_to_hex_r() instead of strcpy
daemon: use cld->env_array when re-spawning
stat_tracking_info: convert to argv_array
http-push: use an argv_array for setup_revisions
fetch-pack: use argv_array for index-pack / unpack-objects
...
Diffstat (limited to 'refs.c')
-rw-r--r-- | refs.c | 76 |
1 files changed, 39 insertions, 37 deletions
@@ -1602,16 +1602,15 @@ static int resolve_missing_loose_ref(const char *refname, } /* This function needs to return a meaningful errno on failure */ -static const char *resolve_ref_unsafe_1(const char *refname, - int resolve_flags, - unsigned char *sha1, - int *flags, - struct strbuf *sb_path) +static const char *resolve_ref_1(const char *refname, + int resolve_flags, + unsigned char *sha1, + int *flags, + struct strbuf *sb_refname, + struct strbuf *sb_path, + struct strbuf *sb_contents) { int depth = MAXDEPTH; - ssize_t len; - char buffer[256]; - static char refname_buffer[256]; int bad_name = 0; if (flags) @@ -1677,19 +1676,18 @@ static const char *resolve_ref_unsafe_1(const char *refname, /* Follow "normalized" - ie "refs/.." symlinks by hand */ if (S_ISLNK(st.st_mode)) { - len = readlink(path, buffer, sizeof(buffer)-1); - if (len < 0) { + strbuf_reset(sb_contents); + if (strbuf_readlink(sb_contents, path, 0) < 0) { if (errno == ENOENT || errno == EINVAL) /* inconsistent with lstat; retry */ goto stat_ref; else return NULL; } - buffer[len] = 0; - if (starts_with(buffer, "refs/") && - !check_refname_format(buffer, 0)) { - strcpy(refname_buffer, buffer); - refname = refname_buffer; + if (starts_with(sb_contents->buf, "refs/") && + !check_refname_format(sb_contents->buf, 0)) { + strbuf_swap(sb_refname, sb_contents); + refname = sb_refname->buf; if (flags) *flags |= REF_ISSYMREF; if (resolve_flags & RESOLVE_REF_NO_RECURSE) { @@ -1718,28 +1716,26 @@ static const char *resolve_ref_unsafe_1(const char *refname, else return NULL; } - len = read_in_full(fd, buffer, sizeof(buffer)-1); - if (len < 0) { + strbuf_reset(sb_contents); + if (strbuf_read(sb_contents, fd, 256) < 0) { int save_errno = errno; close(fd); errno = save_errno; return NULL; } close(fd); - while (len && isspace(buffer[len-1])) - len--; - buffer[len] = '\0'; + strbuf_rtrim(sb_contents); /* * Is it a symbolic ref? */ - if (!starts_with(buffer, "ref:")) { + if (!starts_with(sb_contents->buf, "ref:")) { /* * Please note that FETCH_HEAD has a second * line containing other data. */ - if (get_sha1_hex(buffer, sha1) || - (buffer[40] != '\0' && !isspace(buffer[40]))) { + if (get_sha1_hex(sb_contents->buf, sha1) || + (sb_contents->buf[40] != '\0' && !isspace(sb_contents->buf[40]))) { if (flags) *flags |= REF_ISBROKEN; errno = EINVAL; @@ -1754,10 +1750,12 @@ static const char *resolve_ref_unsafe_1(const char *refname, } if (flags) *flags |= REF_ISSYMREF; - buf = buffer + 4; + buf = sb_contents->buf + 4; while (isspace(*buf)) buf++; - refname = strcpy(refname_buffer, buf); + strbuf_reset(sb_refname); + strbuf_addstr(sb_refname, buf); + refname = sb_refname->buf; if (resolve_flags & RESOLVE_REF_NO_RECURSE) { hashclr(sha1); return refname; @@ -1779,10 +1777,15 @@ static const char *resolve_ref_unsafe_1(const char *refname, const char *resolve_ref_unsafe(const char *refname, int resolve_flags, unsigned char *sha1, int *flags) { + static struct strbuf sb_refname = STRBUF_INIT; + struct strbuf sb_contents = STRBUF_INIT; struct strbuf sb_path = STRBUF_INIT; - const char *ret = resolve_ref_unsafe_1(refname, resolve_flags, - sha1, flags, &sb_path); + const char *ret; + + ret = resolve_ref_1(refname, resolve_flags, sha1, flags, + &sb_refname, &sb_path, &sb_contents); strbuf_release(&sb_path); + strbuf_release(&sb_contents); return ret; } @@ -2222,8 +2225,7 @@ int for_each_glob_ref_in(each_ref_fn fn, const char *pattern, if (!has_glob_specials(pattern)) { /* Append implied '/' '*' if not present. */ - if (real_pattern.buf[real_pattern.len - 1] != '/') - strbuf_addch(&real_pattern, '/'); + strbuf_complete(&real_pattern, '/'); /* No need to check for '*', there is none. */ strbuf_addch(&real_pattern, '*'); } @@ -2730,7 +2732,7 @@ static int pack_if_possible_fn(struct ref_entry *entry, void *cb_data) int namelen = strlen(entry->name) + 1; struct ref_to_prune *n = xcalloc(1, sizeof(*n) + namelen); hashcpy(n->sha1, entry->u.value.oid.hash); - strcpy(n->name, entry->name); + memcpy(n->name, entry->name, namelen); /* includes NUL */ n->next = cb->ref_to_prune; cb->ref_to_prune = n; } @@ -3365,10 +3367,10 @@ static int log_ref_write_fd(int fd, const unsigned char *old_sha1, msglen = msg ? strlen(msg) : 0; maxlen = strlen(committer) + msglen + 100; logrec = xmalloc(maxlen); - len = sprintf(logrec, "%s %s %s\n", - sha1_to_hex(old_sha1), - sha1_to_hex(new_sha1), - committer); + len = xsnprintf(logrec, maxlen, "%s %s %s\n", + sha1_to_hex(old_sha1), + sha1_to_hex(new_sha1), + committer); if (msglen) len += copy_msg(logrec + len - 1, msg) - 1; @@ -4020,10 +4022,10 @@ 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); - struct ref_update *update = xcalloc(1, sizeof(*update) + len + 1); + size_t len = strlen(refname) + 1; + struct ref_update *update = xcalloc(1, sizeof(*update) + len); - strcpy((char *)update->refname, refname); + memcpy((char *)update->refname, refname, len); /* includes NUL */ ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc); transaction->updates[transaction->nr++] = update; return update; |