diff options
| author | nulltoken <emeric.fermas@gmail.com> | 2011-03-18 16:56:43 +0100 |
|---|---|---|
| committer | Vicent Marti <tanoku@gmail.com> | 2011-03-23 00:17:24 +0200 |
| commit | c90292ce4f852ff9f0e8ec4ddc7cdc438745790d (patch) | |
| tree | 4a22d71960db0c0c6381af32402cf2d4009da9d8 /src | |
| parent | 6279abda7370ebb046571437012dc6bb96e1edba (diff) | |
| download | libgit2-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.c | 60 | ||||
| -rw-r--r-- | src/fileops.h | 7 | ||||
| -rw-r--r-- | src/repository.c | 10 |
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; |
