git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Subject: [PATCH 67/68] use strbuf_complete to conditionally append slash
Date: Thu, 24 Sep 2015 17:08:35 -0400	[thread overview]
Message-ID: <20150924210835.GL30946@sigill.intra.peff.net> (raw)
In-Reply-To: <20150924210225.GA23624@sigill.intra.peff.net>

When working with paths in strbufs, we frequently want to
ensure that a directory contains a trailing slash before
appending to it. We can shorten this code (and make the
intent more obvious) by calling strbuf_complete.

Most of these cases are trivially identical conversions, but
there are two things to note:

  - in a few cases we did not check that the strbuf is
    non-empty (which would lead to an out-of-bounds memory
    access). These were generally not triggerable in
    practice, either from earlier assertions, or typically
    because we would have just fed the strbuf to opendir(),
    which would choke on an empty path.

  - in a few cases we indexed the buffer with "original_len"
    or similar, rather than the current sb->len, and it is
    not immediately obvious from the diff that they are the
    same. In all of these cases, I manually verified that
    the strbuf does not change between the assignment and
    the strbuf_complete call.

This does not convert cases which look like:

  if (sb->len && !is_dir_sep(sb->buf[sb->len - 1]))
	  strbuf_addch(sb, '/');

as those are obviously semantically different. Some of these
cases arguably should be doing that, but that is out of
scope for this change, which aims purely for cleanup with no
behavior change (and at least it will make such sites easier
to find and examine in the future, as we can grep for
strbuf_complete).

Signed-off-by: Jeff King <peff@peff.net>
---
 builtin/clean.c | 6 ++----
 builtin/log.c   | 3 +--
 diff-no-index.c | 6 ++----
 dir.c           | 6 ++----
 path.c          | 3 +--
 refs.c          | 3 +--
 url.c           | 3 +--
 7 files changed, 10 insertions(+), 20 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index df53def..d7acb94 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -159,8 +159,7 @@ static int is_git_repository(struct strbuf *path)
 	int gitfile_error;
 	size_t orig_path_len = path->len;
 	assert(orig_path_len != 0);
-	if (path->buf[orig_path_len - 1] != '/')
-		strbuf_addch(path, '/');
+	strbuf_complete(path, '/');
 	strbuf_addstr(path, ".git");
 	if (read_gitfile_gently(path->buf, &gitfile_error) || is_git_directory(path->buf))
 		ret = 1;
@@ -206,8 +205,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
 		return res;
 	}
 
-	if (path->buf[original_len - 1] != '/')
-		strbuf_addch(path, '/');
+	strbuf_complete(path, '/');
 
 	len = path->len;
 	while ((e = readdir(dir)) != NULL) {
diff --git a/builtin/log.c b/builtin/log.c
index a491d3d..dda671d 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -796,8 +796,7 @@ static int reopen_stdout(struct commit *commit, const char *subject,
 		if (filename.len >=
 		    PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len)
 			return error(_("name of output directory is too long"));
-		if (filename.buf[filename.len - 1] != '/')
-			strbuf_addch(&filename, '/');
+		strbuf_complete(&filename, '/');
 	}
 
 	if (rev->numbered_files)
diff --git a/diff-no-index.c b/diff-no-index.c
index 0320605..8e0fd27 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -136,15 +136,13 @@ static int queue_diff(struct diff_options *o,
 
 		if (name1) {
 			strbuf_addstr(&buffer1, name1);
-			if (buffer1.len && buffer1.buf[buffer1.len - 1] != '/')
-				strbuf_addch(&buffer1, '/');
+			strbuf_complete(&buffer1, '/');
 			len1 = buffer1.len;
 		}
 
 		if (name2) {
 			strbuf_addstr(&buffer2, name2);
-			if (buffer2.len && buffer2.buf[buffer2.len - 1] != '/')
-				strbuf_addch(&buffer2, '/');
+			strbuf_complete(&buffer2, '/');
 			len2 = buffer2.len;
 		}
 
diff --git a/dir.c b/dir.c
index 7b25634..79fdad8 100644
--- a/dir.c
+++ b/dir.c
@@ -1519,8 +1519,7 @@ static enum path_treatment treat_path_fast(struct dir_struct *dir,
 	}
 	strbuf_addstr(path, cdir->ucd->name);
 	/* treat_one_path() does this before it calls treat_directory() */
-	if (path->buf[path->len - 1] != '/')
-		strbuf_addch(path, '/');
+	strbuf_complete(path, '/');
 	if (cdir->ucd->check_only)
 		/*
 		 * check_only is set as a result of treat_directory() getting
@@ -2126,8 +2125,7 @@ static int remove_dir_recurse(struct strbuf *path, int flag, int *kept_up)
 		else
 			return -1;
 	}
-	if (path->buf[original_len - 1] != '/')
-		strbuf_addch(path, '/');
+	strbuf_complete(path, '/');
 
 	len = path->len;
 	while ((e = readdir(dir)) != NULL) {
diff --git a/path.c b/path.c
index c597473..c105a9e 100644
--- a/path.c
+++ b/path.c
@@ -240,8 +240,7 @@ static void do_submodule_path(struct strbuf *buf, const char *path,
 	const char *git_dir;
 
 	strbuf_addstr(buf, path);
-	if (buf->len && buf->buf[buf->len - 1] != '/')
-		strbuf_addch(buf, '/');
+	strbuf_complete(buf, '/');
 	strbuf_addstr(buf, ".git");
 
 	git_dir = read_gitfile(buf->buf);
diff --git a/refs.c b/refs.c
index 9937a40..b2a9229 100644
--- a/refs.c
+++ b/refs.c
@@ -2193,8 +2193,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, '*');
 	}
diff --git a/url.c b/url.c
index 7ca2a69..2d89ad1 100644
--- a/url.c
+++ b/url.c
@@ -120,8 +120,7 @@ char *url_decode_parameter_value(const char **query)
 void end_url_with_slash(struct strbuf *buf, const char *url)
 {
 	strbuf_addstr(buf, url);
-	if (buf->len && buf->buf[buf->len - 1] != '/')
-		strbuf_addch(buf, '/');
+	strbuf_complete(buf, '/');
 }
 
 void str_end_url_with_slash(const char *url, char **dest) {
-- 
2.6.0.rc3.454.g204ad51

  parent reply	other threads:[~2015-09-24 21:09 UTC|newest]

Thread overview: 93+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-24 21:02 [PATCH v2 0/68] war on sprintf Jeff King
2015-09-24 21:02 ` [PATCH 01/68] show-branch: avoid segfault with --reflog of unborn branch Jeff King
2015-09-24 21:03 ` [PATCH 02/68] mailsplit: fix FILE* leak in split_maildir Jeff King
2015-09-24 21:03 ` [PATCH 03/68] archive-tar: fix minor indentation violation Jeff King
2015-09-24 21:05 ` [PATCH 04/68] fsck: don't fsck alternates for connectivity-only check Jeff King
2015-09-24 21:05 ` [PATCH 05/68] add xsnprintf helper function Jeff King
2015-09-24 21:05 ` [PATCH 06/68] add git_path_buf " Jeff King
2015-09-24 21:05 ` [PATCH 07/68] strbuf: make strbuf_complete_line more generic Jeff King
2015-09-24 21:05 ` [PATCH 08/68] add reentrant variants of sha1_to_hex and find_unique_abbrev Jeff King
2015-09-24 21:05 ` [PATCH 09/68] fsck: use strbuf to generate alternate directories Jeff King
2015-09-24 21:05 ` [PATCH 10/68] mailsplit: make PATH_MAX buffers dynamic Jeff King
2015-09-24 21:05 ` [PATCH 11/68] trace: use strbuf for quote_crnl output Jeff King
2015-09-24 21:05 ` [PATCH 12/68] progress: store throughput display in a strbuf Jeff King
2015-09-24 21:06 ` [PATCH 13/68] test-dump-cache-tree: avoid overflow of cache-tree name Jeff King
2015-09-24 21:06 ` [PATCH 14/68] compat/inet_ntop: fix off-by-one in inet_ntop4 Jeff King
2015-09-24 21:06 ` [PATCH 15/68] convert trivial sprintf / strcpy calls to xsnprintf Jeff King
2015-09-24 21:06 ` [PATCH 16/68] archive-tar: use xsnprintf for trivial formatting Jeff King
2015-09-24 21:06 ` [PATCH 17/68] use xsnprintf for generating git object headers Jeff King
2015-09-24 21:06 ` [PATCH 18/68] find_short_object_filename: convert sprintf to xsnprintf Jeff King
2015-09-24 21:06 ` [PATCH 19/68] stop_progress_msg: " Jeff King
2015-09-24 21:06 ` [PATCH 20/68] compat/hstrerror: convert sprintf to snprintf Jeff King
2015-09-24 21:06 ` [PATCH 21/68] grep: use xsnprintf to format failure message Jeff King
2015-09-24 21:06 ` [PATCH 22/68] entry.c: convert strcpy to xsnprintf Jeff King
2015-09-24 21:06 ` [PATCH 23/68] add_packed_git: convert strcpy into xsnprintf Jeff King
2015-09-24 21:06 ` [PATCH 24/68] http-push: replace strcat with xsnprintf Jeff King
2015-09-24 21:07 ` [PATCH 25/68] receive-pack: convert strncpy to xsnprintf Jeff King
2015-09-24 21:07 ` [PATCH 26/68] replace trivial malloc + sprintf / strcpy calls with xstrfmt Jeff King
2015-09-24 21:07 ` [PATCH 27/68] config: use xstrfmt in normalize_value Jeff King
2015-09-24 21:07 ` [PATCH 28/68] fetch: replace static buffer with xstrfmt Jeff King
2015-09-24 21:07 ` [PATCH 29/68] use strip_suffix and xstrfmt to replace suffix Jeff King
2015-09-24 21:07 ` [PATCH 30/68] ref-filter: drop sprintf and strcpy calls Jeff King
2015-09-24 21:07 ` [PATCH 31/68] help: drop prepend function in favor of xstrfmt Jeff King
2015-09-24 21:07 ` [PATCH 32/68] mailmap: replace strcpy with xstrdup Jeff King
2015-09-24 21:07 ` [PATCH 33/68] read_branches_file: simplify string handling Jeff King
2015-09-24 21:07 ` [PATCH 34/68] read_remotes_file: " Jeff King
2015-09-24 21:07 ` [PATCH 35/68] resolve_ref: use strbufs for internal buffers Jeff King
2015-09-24 21:07 ` [PATCH 36/68] upload-archive: convert sprintf to strbuf Jeff King
2015-09-24 21:07 ` [PATCH 37/68] remote-ext: simplify git pkt-line generation Jeff King
2015-09-24 21:07 ` [PATCH 38/68] http-push: use strbuf instead of fwrite_buffer Jeff King
2015-09-24 21:07 ` [PATCH 39/68] http-walker: store url in a strbuf Jeff King
2015-09-24 21:07 ` [PATCH 40/68] sha1_get_pack_name: use " Jeff King
2015-09-24 21:07 ` [PATCH 41/68] init: use strbufs to store paths Jeff King
2015-09-29 23:50   ` Michael Blume
2015-09-30  0:23     ` Jeff King
2015-09-30 20:00       ` Junio C Hamano
2015-10-01  2:51         ` Jeff King
2015-10-02  6:00           ` Torsten Bögershausen
2015-10-02 15:33             ` Jeff King
2015-10-03  5:58       ` Torsten Bögershausen
2015-10-03 16:54         ` Junio C Hamano
2015-10-03 21:12           ` Torsten Bögershausen
2015-10-04  3:37             ` Jeff King
2015-10-04  6:31               ` Torsten Bögershausen
2015-10-05  3:41                 ` Jeff King
2015-10-05  3:43                   ` [PATCH 1/3] precompose_utf8: drop unused variable Jeff King
2015-10-06  3:24                     ` Torsten Bögershausen
2015-10-05  3:45                   ` [PATCH 2/3] probe_utf8_pathname_composition: use internal strbuf Jeff King
2015-10-05  3:46                   ` [PATCH 3/3] init: use strbufs to store paths Jeff King
2015-09-24 21:07 ` [PATCH 42/68] apply: convert root string to strbuf Jeff King
2015-09-24 21:07 ` [PATCH 43/68] transport: use strbufs for status table "quickref" strings Jeff King
2015-09-24 21:07 ` [PATCH 44/68] merge-recursive: convert malloc / strcpy to strbuf Jeff King
2015-09-24 21:07 ` [PATCH 45/68] enter_repo: convert fixed-size buffers to strbufs Jeff King
2015-09-24 21:07 ` [PATCH 46/68] remove_leading_path: use a strbuf for internal storage Jeff King
2015-09-24 21:07 ` [PATCH 47/68] write_loose_object: convert to strbuf Jeff King
2015-09-24 21:07 ` [PATCH 48/68] diagnose_invalid_index_path: use strbuf to avoid strcpy/strcat Jeff King
2015-09-24 21:07 ` [PATCH 49/68] fetch-pack: use argv_array for index-pack / unpack-objects Jeff King
2015-09-24 21:07 ` [PATCH 50/68] http-push: use an argv_array for setup_revisions Jeff King
2015-09-24 21:07 ` [PATCH 51/68] stat_tracking_info: convert to argv_array Jeff King
2015-09-24 21:08 ` [PATCH 52/68] daemon: use cld->env_array when re-spawning Jeff King
2015-09-24 21:08 ` [PATCH 53/68] use sha1_to_hex_r() instead of strcpy Jeff King
2015-09-24 21:08 ` [PATCH 54/68] drop strcpy in favor of raw sha1_to_hex Jeff King
2015-09-24 23:42   ` Eric Sunshine
2015-09-25  1:36     ` Jeff King
2015-09-24 21:08 ` [PATCH 55/68] color: add overflow checks for parsing colors Jeff King
2015-09-24 21:08 ` [PATCH 56/68] use alloc_ref rather than hand-allocating "struct ref" Jeff King
2015-09-24 21:08 ` [PATCH 57/68] avoid sprintf and strcpy with flex arrays Jeff King
2015-09-24 21:08 ` [PATCH 58/68] receive-pack: simplify keep_arg computation Jeff King
2015-09-24 21:08 ` [PATCH 59/68] help: clean up kfmclient munging Jeff King
2015-09-24 21:08 ` [PATCH 60/68] prefer memcpy to strcpy Jeff King
2015-09-27 11:19   ` René Scharfe
2015-09-27 13:06     ` Torsten Bögershausen
2015-09-27 13:13       ` René Scharfe
2015-09-27 13:24         ` René Scharfe
2015-09-28  7:09   ` Rasmus Villemoes
2015-09-24 21:08 ` [PATCH 61/68] color: add color_set helper for copying raw colors Jeff King
2015-09-24 21:08 ` [PATCH 62/68] notes: document length of fanout path with a constant Jeff King
2015-09-24 21:08 ` [PATCH 63/68] convert strncpy to memcpy Jeff King
2015-09-24 21:08 ` [PATCH 64/68] fsck: drop inode-sorting code Jeff King
2015-09-24 21:08 ` [PATCH 65/68] Makefile: drop D_INO_IN_DIRENT build knob Jeff King
2015-09-24 21:08 ` [PATCH 66/68] fsck: use for_each_loose_file_in_objdir Jeff King
2015-09-26  3:36   ` Jeff King
2015-09-24 21:08 ` Jeff King [this message]
2015-09-24 21:08 ` [PATCH 68/68] name-rev: use strip_suffix to avoid magic numbers Jeff King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150924210835.GL30946@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).