Commit eec3fe39 by Vicent Marti

fileutils: Finish dropping the old `prettify_path`

parent 19ac1ed7
......@@ -306,153 +306,6 @@ int git_futils_mkdir_r(const char *path, int mode)
return GIT_SUCCESS;
}
static int retrieve_previous_path_component_start(const char *path)
{
int offset, len, root_offset, start = 0;
root_offset = git_path_root(path);
if (root_offset > -1)
start += root_offset;
len = strlen(path);
offset = len - 1;
/* Skip leading slash */
if (path[start] == '/')
start++;
/* Skip trailing slash */
if (path[offset] == '/')
offset--;
if (offset < root_offset)
return git__throw(GIT_ERROR, "Failed to retrieve path component. Wrong offset");
while (offset > start && path[offset-1] != '/') {
offset--;
}
return offset;
}
int git_futils_prettify_dir(char *buffer_out, size_t size, const char *path, const char *base_path)
{
int len = 0, segment_len, only_dots, root_path_offset, error = GIT_SUCCESS;
char *current;
const char *buffer_out_start, *buffer_end;
current = (char *)path;
buffer_end = path + strlen(path);
buffer_out_start = buffer_out;
root_path_offset = git_path_root(path);
if (root_path_offset < 0) {
if (base_path == NULL) {
error = p_getcwd(buffer_out, size);
if (error < GIT_SUCCESS)
return error; /* The callee already takes care of setting the correct error message. */
} else {
if (size < (strlen(base_path) + 1) * sizeof(char))
return git__throw(GIT_EOVERFLOW, "Failed to prettify dir path: the base path is too long for the buffer.");
strcpy(buffer_out, base_path);
git_path_mkposix(buffer_out);
git_path_join(buffer_out, buffer_out, "");
}
len = strlen(buffer_out);
buffer_out += len;
}
while (current < buffer_end) {
/* Prevent multiple slashes from being added to the output */
if (*current == '/' && len > 0 && buffer_out_start[len - 1] == '/') {
current++;
continue;
}
only_dots = 1;
segment_len = 0;
/* Copy path segment to the output */
while (current < buffer_end && *current != '/')
{
only_dots &= (*current == '.');
*buffer_out++ = *current++;
segment_len++;
len++;
}
/* Skip current directory */
if (only_dots && segment_len == 1)
{
current++;
buffer_out -= segment_len;
len -= segment_len;
continue;
}
/* Handle the double-dot upward directory navigation */
if (only_dots && segment_len == 2)
{
current++;
buffer_out -= segment_len;
*buffer_out ='\0';
len = retrieve_previous_path_component_start(buffer_out_start);
/* Are we escaping out of the root dir? */
if (len < 0)
return git__throw(GIT_EINVALIDPATH, "Failed to normalize path `%s`. The path escapes out of the root directory", path);
buffer_out = (char *)buffer_out_start + len;
continue;
}
/* Guard against potential multiple dot path traversal (cf http://cwe.mitre.org/data/definitions/33.html) */
if (only_dots && segment_len > 0)
return git__throw(GIT_EINVALIDPATH, "Failed to normalize path `%s`. The path contains a segment with three `.` or more", path);
*buffer_out++ = '/';
len++;
}
*buffer_out = '\0';
return GIT_SUCCESS;
}
int git_futils_prettyify_file(char *buffer_out, size_t size, const char *path, const char *base_path)
{
int error, path_len, i, root_offset;
const char* pattern = "/..";
path_len = strlen(path);
/* Let's make sure the filename isn't empty nor a dot */
if (path_len == 0 || (path_len == 1 && *path == '.'))
return git__throw(GIT_EINVALIDPATH, "Failed to normalize file path `%s`. The path is either empty or equals `.`", path);
/* Let's make sure the filename doesn't end with "/", "/." or "/.." */
for (i = 1; path_len > i && i < 4; i++) {
if (!strncmp(path + path_len - i, pattern, i))
return git__throw(GIT_EINVALIDPATH, "Failed to normalize file path `%s`. The path points to a folder", path);
}
error = git_futils_prettify_dir(buffer_out, size, path, base_path);
if (error < GIT_SUCCESS)
return error; /* The callee already takes care of setting the correct error message. */
path_len = strlen(buffer_out);
root_offset = git_path_root(buffer_out) + 1;
if (path_len == root_offset)
return git__throw(GIT_EINVALIDPATH, "Failed to normalize file path `%s`. The path points to a folder", path);
/* Remove the trailing slash */
buffer_out[path_len - 1] = '\0';
return GIT_SUCCESS;
}
int git_futils_cmp_path(const char *name1, int len1, int isdir1,
const char *name2, int len2, int isdir2)
{
......
......@@ -149,54 +149,4 @@ extern int git_futils_direach(
extern int git_futils_cmp_path(const char *name1, int len1, int isdir1,
const char *name2, int len2, int isdir2);
/**
* Clean up a provided absolute or relative directory path.
*
* This prettification relies on basic operations such as coalescing
* multiple forward slashes into a single slash, removing '.' and
* './' current directory segments, and removing parent directory
* whenever '..' is encountered.
*
* If not empty, the returned path ends with a forward slash.
*
* For instance, this will turn "d1/s1///s2/..//../s3" into "d1/s3/".
*
* This only performs a string based analysis of the path.
* No checks are done to make sure the path actually makes sense from
* the file system perspective.
*
* @param buffer_out buffer to populate with the normalized path.
* @param size buffer size.
* @param path directory path to clean up.
* @return
* - GIT_SUCCESS on success;
* - GIT_ERROR when the input path is invalid or escapes the current directory.
*/
int git_futils_prettify_dir(char *buffer_out, size_t size, const char *path, const char *base_path);
/**
* Clean up a provided absolute or relative file path.
*
* This prettification relies on basic operations such as coalescing
* multiple forward slashes into a single slash, removing '.' and
* './' current directory segments, and removing parent directory
* whenever '..' is encountered.
*
* For instance, this will turn "d1/s1///s2/..//../s3" into "d1/s3".
*
* This only performs a string based analysis of the path.
* No checks are done to make sure the path actually makes sense from
* the file system perspective.
*
* @param buffer_out buffer to populate with the normalized path.
* @param size buffer size.
* @param path file path to clean up.
* @return
* - GIT_SUCCESS on success;
* - GIT_ERROR when the input path is invalid or escapes the current directory.
*/
int git_futils_prettyify_file(char *buffer_out, size_t size, const char *path, const char *base_path);
#endif /* INCLUDE_fileops_h__ */
......@@ -67,7 +67,7 @@ static int assign_repository_dirs(
if (git_dir == NULL)
return git__throw(GIT_ENOTFOUND, "Failed to open repository. Git dir not found");
error = git_futils_prettify_dir(path_aux, sizeof(path_aux), git_dir, NULL);
error = git_path_prettify_dir(path_aux, git_dir, NULL);
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to open repository");
......@@ -80,7 +80,7 @@ static int assign_repository_dirs(
if (git_object_directory == NULL)
git_path_join(path_aux, repo->path_repository, GIT_OBJECTS_DIR);
else {
error = git_futils_prettify_dir(path_aux, sizeof(path_aux), git_object_directory, NULL);
error = git_path_prettify_dir(path_aux, git_object_directory, NULL);
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to open repository");
}
......@@ -94,7 +94,7 @@ static int assign_repository_dirs(
if (git_work_tree == NULL)
repo->is_bare = 1;
else {
error = git_futils_prettify_dir(path_aux, sizeof(path_aux), git_work_tree, NULL);
error = git_path_prettify_dir(path_aux, git_work_tree, NULL);
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to open repository");
......@@ -107,7 +107,7 @@ static int assign_repository_dirs(
if (git_index_file == NULL)
git_path_join(path_aux, repo->path_repository, GIT_INDEX_FILE);
else {
error = git_futils_prettyify_file(path_aux, sizeof(path_aux), git_index_file, NULL);
error = git_path_prettify(path_aux, git_index_file, NULL);
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to open repository");
}
......@@ -670,12 +670,15 @@ static int repo_init_find_dir(repo_init *results, const char* path)
char temp_path[GIT_PATH_MAX];
int error;
error = git_futils_prettify_dir(temp_path, sizeof(temp_path), path, NULL);
if (error < GIT_SUCCESS)
return git__throw(GIT_ENOTFOUND, "Invalid directory to initialize repository");
if (git_futils_isdir(path) < GIT_SUCCESS) {
error = git_futils_mkdir_r(path, 0755);
if (error < GIT_SUCCESS)
return git__throw(GIT_EOSERR,
"Failed to initialize repository; cannot create full path");
}
// if (p_realpath(path, temp_path) == NULL)
// return git__throw(GIT_ENOTFOUND, "Invalid directory to initialize repository");
if (git_path_prettify_dir(temp_path, path, NULL) < GIT_SUCCESS)
return git__throw(GIT_ENOTFOUND, "Failed to resolve repository path (%s)", path);
if (!results->is_bare)
git_path_join(temp_path, temp_path, GIT_DIR);
......
......@@ -374,7 +374,7 @@ static int append_ceiling_dir(char *ceiling_dirs, const char *path)
int len = strlen(ceiling_dirs);
int error;
error = git_futils_prettify_dir(ceiling_dirs + len + (len ? 1 : 0), GIT_PATH_MAX, path, NULL);
error = git_path_prettify_dir(ceiling_dirs + len + (len ? 1 : 0), path, NULL);
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to append ceiling directory.");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment