From 598019769cbaa38495b0c04297efa13d0f4a572e Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 20 Mar 2017 21:21:27 -0400 Subject: prefix_filename: move docstring to header file This is a public function, so we should make its documentation available near the declaration. While we're at it, we can give a few details about how it works. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- cache.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 9b2157f591..a01668fc42 100644 --- a/cache.h +++ b/cache.h @@ -529,7 +529,19 @@ extern const char *setup_git_directory_gently(int *); extern const char *setup_git_directory(void); extern char *prefix_path(const char *prefix, int len, const char *path); extern char *prefix_path_gently(const char *prefix, int len, int *remaining, const char *path); + +/* + * Concatenate "prefix" (if len is non-zero) and "path", with no + * connecting characters (so "prefix" should end with a "/"). + * Unlike prefix_path, this should be used if the named file does + * not have to interact with index entry; i.e. name of a random file + * on the filesystem. + * + * The return value may point to static storage which will be overwritten by + * further calls. + */ extern const char *prefix_filename(const char *prefix, int len, const char *path); + extern int check_filename(const char *prefix, const char *name); extern void verify_filename(const char *prefix, const char *name, -- cgit v1.2.1 From 116fb64e439d3744d0f244a51d7a6d714b7703ae Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 20 Mar 2017 21:22:28 -0400 Subject: prefix_filename: drop length parameter This function takes the prefix as a ptr/len pair, but in every caller the length is exactly strlen(ptr). Let's simplify the interface and just take the string. This saves callers specifying it (and in some cases handling a NULL prefix). In a handful of cases we had the length already without calling strlen, so this is technically slower. But it's not likely to matter (after all, if the prefix is non-empty we'll allocate and copy it into a buffer anyway). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- cache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cache.h') diff --git a/cache.h b/cache.h index a01668fc42..0b53aef0ed 100644 --- a/cache.h +++ b/cache.h @@ -540,7 +540,7 @@ extern char *prefix_path_gently(const char *prefix, int len, int *remaining, con * The return value may point to static storage which will be overwritten by * further calls. */ -extern const char *prefix_filename(const char *prefix, int len, const char *path); +extern const char *prefix_filename(const char *prefix, const char *path); extern int check_filename(const char *prefix, const char *name); extern void verify_filename(const char *prefix, -- cgit v1.2.1 From e4da43b1f063d227b5f7d2922d27458748763a2d Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 20 Mar 2017 21:28:49 -0400 Subject: prefix_filename: return newly allocated string The prefix_filename() function returns a pointer to static storage, which makes it easy to use dangerously. We already fixed one buggy caller in hash-object recently, and the calls in apply.c are suspicious (I didn't dig in enough to confirm that there is a bug, but we call the function once in apply_all_patches() and then again indirectly from parse_chunk()). Let's make it harder to get wrong by allocating the return value. For simplicity, we'll do this even when the prefix is empty (and we could just return the original file pointer). That will cause us to allocate sometimes when we wouldn't otherwise need to, but this function isn't called in performance critical code-paths (and it already _might_ allocate on any given call, so a caller that cares about performance is questionable anyway). The downside is that the callers need to remember to free() the result to avoid leaking. Most of them already used xstrdup() on the result, so we know they are OK. The remainder have been converted to use free() as appropriate. I considered retaining a prefix_filename_unsafe() for cases where we know the static lifetime is OK (and handling the cleanup is awkward). This is only a handful of cases, though, and it's not worth the mental energy in worrying about whether the "unsafe" variant is OK to use in any situation. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- cache.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 0b53aef0ed..aa6a0fb91a 100644 --- a/cache.h +++ b/cache.h @@ -537,10 +537,10 @@ extern char *prefix_path_gently(const char *prefix, int len, int *remaining, con * not have to interact with index entry; i.e. name of a random file * on the filesystem. * - * The return value may point to static storage which will be overwritten by - * further calls. + * The return value is always a newly allocated string (even if the + * prefix was empty). */ -extern const char *prefix_filename(const char *prefix, const char *path); +extern char *prefix_filename(const char *prefix, const char *path); extern int check_filename(const char *prefix, const char *name); extern void verify_filename(const char *prefix, -- cgit v1.2.1