Merge branch 'mm/config-pathname-tilde-expand'
* mm/config-pathname-tilde-expand: Documentation: avoid xmlto input error expand_user_path: expand ~ to $HOME, not to the actual homedir. Expand ~ and ~user in core.excludesfile, commit.template
This commit is contained in:
83
path.c
83
path.c
@ -11,6 +11,7 @@
|
||||
* which is what it's designed for.
|
||||
*/
|
||||
#include "cache.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
static char bad_path[] = "/bad-path/";
|
||||
|
||||
@ -207,43 +208,49 @@ int validate_headref(const char *path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char *user_path(char *buf, char *path, int sz)
|
||||
static struct passwd *getpw_str(const char *username, size_t len)
|
||||
{
|
||||
struct passwd *pw;
|
||||
char *slash;
|
||||
int len, baselen;
|
||||
char *username_z = xmalloc(len + 1);
|
||||
memcpy(username_z, username, len);
|
||||
username_z[len] = '\0';
|
||||
pw = getpwnam(username_z);
|
||||
free(username_z);
|
||||
return pw;
|
||||
}
|
||||
|
||||
if (!path || path[0] != '~')
|
||||
return NULL;
|
||||
path++;
|
||||
slash = strchr(path, '/');
|
||||
if (path[0] == '/' || !path[0]) {
|
||||
pw = getpwuid(getuid());
|
||||
}
|
||||
else {
|
||||
if (slash) {
|
||||
*slash = 0;
|
||||
pw = getpwnam(path);
|
||||
*slash = '/';
|
||||
/*
|
||||
* Return a string with ~ and ~user expanded via getpw*. If buf != NULL,
|
||||
* then it is a newly allocated string. Returns NULL on getpw failure or
|
||||
* if path is NULL.
|
||||
*/
|
||||
char *expand_user_path(const char *path)
|
||||
{
|
||||
struct strbuf user_path = STRBUF_INIT;
|
||||
const char *first_slash = strchrnul(path, '/');
|
||||
const char *to_copy = path;
|
||||
|
||||
if (path == NULL)
|
||||
goto return_null;
|
||||
if (path[0] == '~') {
|
||||
const char *username = path + 1;
|
||||
size_t username_len = first_slash - username;
|
||||
if (username_len == 0) {
|
||||
const char *home = getenv("HOME");
|
||||
strbuf_add(&user_path, home, strlen(home));
|
||||
} else {
|
||||
struct passwd *pw = getpw_str(username, username_len);
|
||||
if (!pw)
|
||||
goto return_null;
|
||||
strbuf_add(&user_path, pw->pw_dir, strlen(pw->pw_dir));
|
||||
}
|
||||
else
|
||||
pw = getpwnam(path);
|
||||
to_copy = first_slash;
|
||||
}
|
||||
if (!pw || !pw->pw_dir || sz <= strlen(pw->pw_dir))
|
||||
return NULL;
|
||||
baselen = strlen(pw->pw_dir);
|
||||
memcpy(buf, pw->pw_dir, baselen);
|
||||
while ((1 < baselen) && (buf[baselen-1] == '/')) {
|
||||
buf[baselen-1] = 0;
|
||||
baselen--;
|
||||
}
|
||||
if (slash && slash[1]) {
|
||||
len = strlen(slash);
|
||||
if (sz <= baselen + len)
|
||||
return NULL;
|
||||
memcpy(buf + baselen, slash, len + 1);
|
||||
}
|
||||
return buf;
|
||||
strbuf_add(&user_path, to_copy, strlen(to_copy));
|
||||
return strbuf_detach(&user_path, NULL);
|
||||
return_null:
|
||||
strbuf_release(&user_path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -291,8 +298,18 @@ char *enter_repo(char *path, int strict)
|
||||
if (PATH_MAX <= len)
|
||||
return NULL;
|
||||
if (path[0] == '~') {
|
||||
if (!user_path(used_path, path, PATH_MAX))
|
||||
char *newpath = expand_user_path(path);
|
||||
if (!newpath || (PATH_MAX - 10 < strlen(newpath))) {
|
||||
free(newpath);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* Copy back into the static buffer. A pity
|
||||
* since newpath was not bounded, but other
|
||||
* branches of the if are limited by PATH_MAX
|
||||
* anyway.
|
||||
*/
|
||||
strcpy(used_path, newpath); free(newpath);
|
||||
strcpy(validated_path, path);
|
||||
path = used_path;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user