summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authornulltoken <emeric.fermas@gmail.com>2011-03-18 16:56:43 +0100
committerVicent Marti <tanoku@gmail.com>2011-03-23 00:17:24 +0200
commitc90292ce4f852ff9f0e8ec4ddc7cdc438745790d (patch)
tree4a22d71960db0c0c6381af32402cf2d4009da9d8 /src
parent6279abda7370ebb046571437012dc6bb96e1edba (diff)
downloadlibgit2-c90292ce4f852ff9f0e8ec4ddc7cdc438745790d.tar.gz
Change gitfo_prettify_dir_path() and gitfo_prettify_file_path() behavior
Those functions now return prettified rooted path.
Diffstat (limited to 'src')
-rw-r--r--src/fileops.c60
-rw-r--r--src/fileops.h7
-rw-r--r--src/repository.c10
3 files changed, 51 insertions, 26 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 4ed53bc97..41239091b 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -443,22 +443,29 @@ int gitfo_dirent(
return GIT_SUCCESS;
}
-#ifdef GIT_WIN32
-static int is_windows_rooted_path(const char *path)
+int retrieve_path_root_offset(const char *path)
{
+ int offset = 0;
+
+#ifdef GIT_WIN32
+
/* Does the root of the path look like a windows drive ? */
if (isalpha(path[0]) && (path[1] == ':'))
- return GIT_SUCCESS;
+ offset += 2;
+
+#endif
+
+ if (*(path + offset) == '/')
+ return offset;
return GIT_ERROR;
}
-#endif
int gitfo_mkdir_recurs(const char *path, int mode)
{
- int error;
+ int error, root_path_offset;
char *pp, *sp;
char *path_copy = git__strdup(path);
@@ -468,12 +475,9 @@ int gitfo_mkdir_recurs(const char *path, int mode)
error = GIT_SUCCESS;
pp = path_copy;
-#ifdef GIT_WIN32
-
- if (!is_windows_rooted_path(pp))
- pp += 2; /* Skip the drive name (eg. C: or D:) */
-
-#endif
+ root_path_offset = retrieve_path_root_offset(pp);
+ if (root_path_offset > 0)
+ pp += root_path_offset; /* On Windows, will skip the drive name (eg. C: or D:) */
while (error == GIT_SUCCESS && (sp = strchr(pp, '/')) != 0) {
if (sp != pp && gitfo_isdir(path_copy) < GIT_SUCCESS) {
@@ -504,6 +508,8 @@ static int retrieve_previous_path_component_start(const char *path)
len = strlen(path);
offset = len - 1;
+ //TODO: Deal with Windows rooted path
+
/* Skip leading slash */
if (path[start] == '/')
start++;
@@ -522,15 +528,25 @@ static int retrieve_previous_path_component_start(const char *path)
return offset;
}
-int gitfo_prettify_dir_path(char *buffer_out, const char *path)
+int gitfo_prettify_dir_path(char *buffer_out, size_t size, const char *path)
{
- int len = 0, segment_len, only_dots;
+ int len = 0, segment_len, only_dots, root_path_offset, error = GIT_SUCCESS;
char *current;
const char *buffer_out_start, *buffer_end;
- buffer_out_start = buffer_out;
current = (char *)path;
buffer_end = path + strlen(path);
+ buffer_out_start = buffer_out;
+
+ root_path_offset = retrieve_path_root_offset(path);
+ if (root_path_offset < 0) {
+ error = gitfo_getcwd(buffer_out, size);
+ if (error < GIT_SUCCESS)
+ return error;
+
+ len = strlen(buffer_out);
+ buffer_out += len;
+ }
while (current < buffer_end) {
/* Prevent multiple slashes from being added to the output */
@@ -543,7 +559,7 @@ int gitfo_prettify_dir_path(char *buffer_out, const char *path)
segment_len = 0;
/* Copy path segment to the output */
- while (current < buffer_end && *current !='/')
+ while (current < buffer_end && *current != '/')
{
only_dots &= (*current == '.');
*buffer_out++ = *current++;
@@ -568,7 +584,9 @@ int gitfo_prettify_dir_path(char *buffer_out, const char *path)
*buffer_out ='\0';
len = retrieve_previous_path_component_start(buffer_out_start);
- if (len < GIT_SUCCESS)
+
+ /* Are we escaping out of the root dir? */
+ if (len < 0)
return GIT_EINVALIDPATH;
buffer_out = (char *)buffer_out_start + len;
@@ -576,7 +594,7 @@ int gitfo_prettify_dir_path(char *buffer_out, const char *path)
}
/* Guard against potential multiple dot path traversal (cf http://cwe.mitre.org/data/definitions/33.html) */
- if (only_dots &&segment_len > 0)
+ if (only_dots && segment_len > 0)
return GIT_EINVALIDPATH;
*buffer_out++ = '/';
@@ -588,20 +606,24 @@ int gitfo_prettify_dir_path(char *buffer_out, const char *path)
return GIT_SUCCESS;
}
-int gitfo_prettify_file_path(char *buffer_out, const char *path)
+int gitfo_prettify_file_path(char *buffer_out, size_t size, const char *path)
{
int error, path_len, i;
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_EINVALIDPATH;
+
/* 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_EINVALIDPATH;
}
- error = gitfo_prettify_dir_path(buffer_out, path);
+ error = gitfo_prettify_dir_path(buffer_out, size, path);
if (error < GIT_SUCCESS)
return error;
diff --git a/src/fileops.h b/src/fileops.h
index c2c038b26..ce236f608 100644
--- a/src/fileops.h
+++ b/src/fileops.h
@@ -163,12 +163,13 @@ extern int gitfo_getcwd(char *buffer_out, size_t size);
* 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 gitfo_prettify_dir_path(char *buffer_out, const char *path);
+int gitfo_prettify_dir_path(char *buffer_out, size_t size, const char *path);
/**
* Clean up a provided absolute or relative file path.
@@ -185,11 +186,13 @@ int gitfo_prettify_dir_path(char *buffer_out, const char *path);
* 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 gitfo_prettify_file_path(char *buffer_out, const char *path);
+int gitfo_prettify_file_path(char *buffer_out, size_t size, const char *path);
+int retrieve_path_root_offset(const char *path);
#endif /* INCLUDE_fileops_h__ */
diff --git a/src/repository.c b/src/repository.c
index 132969402..91b95a881 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -66,7 +66,7 @@ static int assign_repository_dirs(
if (git_dir == NULL)
return GIT_ENOTFOUND;
- error = gitfo_prettify_dir_path(path_aux, git_dir);
+ error = gitfo_prettify_dir_path(path_aux, sizeof(path_aux), git_dir);
if (error < GIT_SUCCESS)
return error;
@@ -81,7 +81,7 @@ static int assign_repository_dirs(
if (git_object_directory == NULL)
git__joinpath(path_aux, repo->path_repository, GIT_OBJECTS_DIR);
else {
- error = gitfo_prettify_dir_path(path_aux, git_object_directory);
+ error = gitfo_prettify_dir_path(path_aux, sizeof(path_aux), git_object_directory);
if (error < GIT_SUCCESS)
return error;
}
@@ -95,7 +95,7 @@ static int assign_repository_dirs(
if (git_work_tree == NULL)
repo->is_bare = 1;
else {
- error = gitfo_prettify_dir_path(path_aux, git_work_tree);
+ error = gitfo_prettify_dir_path(path_aux, sizeof(path_aux), git_work_tree);
if (error < GIT_SUCCESS)
return error;
@@ -108,7 +108,7 @@ static int assign_repository_dirs(
if (git_index_file == NULL)
git__joinpath(path_aux, repo->path_repository, GIT_INDEX_FILE);
else {
- error = gitfo_prettify_file_path(path_aux, git_index_file);
+ error = gitfo_prettify_file_path(path_aux, sizeof(path_aux), git_index_file);
if (error < GIT_SUCCESS)
return error;
}
@@ -403,7 +403,7 @@ static int repo_init_find_dir(repo_init *results, const char* path)
char temp_path[GIT_PATH_MAX];
int error = GIT_SUCCESS;
- error = gitfo_prettify_dir_path(temp_path, path);
+ error = gitfo_prettify_dir_path(temp_path, sizeof(temp_path), path);
if (error < GIT_SUCCESS)
return error;