diff options
| author | nulltoken <emeric.fermas@gmail.com> | 2011-01-22 14:04:32 +0100 |
|---|---|---|
| committer | Vicent Marti <tanoku@gmail.com> | 2011-01-29 03:29:32 +0200 |
| commit | ae7ffea96132ee8df08f7c18aac6b36acbd689cf (patch) | |
| tree | 69aaaa853c691b382884e707e844ced9fe5b9bdd /src/fileops.c | |
| parent | b29e8f19300bb95b9f8307f1438193271233adc8 (diff) | |
| download | libgit2-ae7ffea96132ee8df08f7c18aac6b36acbd689cf.tar.gz | |
Fixed a parsing issue in git_prettify_dir_path().
Diffstat (limited to 'src/fileops.c')
| -rw-r--r-- | src/fileops.c | 65 |
1 files changed, 39 insertions, 26 deletions
diff --git a/src/fileops.c b/src/fileops.c index 5953f26f6..191aa91fa 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -394,8 +394,9 @@ static int retrieve_previous_path_component_start(const char *path) int git_prettify_dir_path(char *buffer_out, const char *path) { int len = 0; - char *current; + char *current, *end; const char *buffer_out_start, *buffer_end; + int only_dots; buffer_out_start = buffer_out; current = (char *)path; @@ -408,40 +409,52 @@ int git_prettify_dir_path(char *buffer_out, const char *path) continue; } - /* Skip current directory */ - if (*current == '.') { - current++; - - /* Handle the double-dot upward directory navigation */ - if (current < buffer_end && *current == '.') { - current++; - - /* Guard against potential multiple dot path traversal (cf http://cwe.mitre.org/data/definitions/33.html) */ - if (*current == '.') - return GIT_ERROR; + end = current; + only_dots = 1; + + /* Seek end of path segment */ + while (end < buffer_end && *end !='/') + { + only_dots &= (*end == '.'); + end++; + } - *buffer_out ='\0'; - len = retrieve_previous_path_component_start(buffer_out_start); - if (len < GIT_SUCCESS) - return GIT_ERROR; + /* Skip current directory */ + if (only_dots && end == current + 1) + { + current += 2; + continue; + } - buffer_out = (char *)buffer_out_start + len; - } + /* Handle the double-dot upward directory navigation */ + if (only_dots && end == current + 2) + { + *buffer_out ='\0'; + len = retrieve_previous_path_component_start(buffer_out_start); + if (len < GIT_SUCCESS) + return GIT_ERROR; + + buffer_out = (char *)buffer_out_start + len; + + current += 3; + continue; + } - if (current < buffer_end && *current == '/') - current++; + /* Guard against potential multiple dot path traversal (cf http://cwe.mitre.org/data/definitions/33.html) */ + if (only_dots && end > current) + return GIT_ERROR; - continue; + /* Copy to output the path segment */ + while (current < end) + { + *buffer_out++ = *current++; + len++; } - *buffer_out++ = *current++; + *buffer_out++ = '/'; len++; } - /* Add a trailing slash if required */ - if (len > 0 && buffer_out_start[len-1] != '/') - *buffer_out++ = '/'; - *buffer_out = '\0'; return GIT_SUCCESS; |
