summaryrefslogtreecommitdiff
path: root/src/fileops.c
diff options
context:
space:
mode:
authornulltoken <emeric.fermas@gmail.com>2011-01-22 14:04:32 +0100
committerVicent Marti <tanoku@gmail.com>2011-01-29 03:29:32 +0200
commitae7ffea96132ee8df08f7c18aac6b36acbd689cf (patch)
tree69aaaa853c691b382884e707e844ced9fe5b9bdd /src/fileops.c
parentb29e8f19300bb95b9f8307f1438193271233adc8 (diff)
downloadlibgit2-ae7ffea96132ee8df08f7c18aac6b36acbd689cf.tar.gz
Fixed a parsing issue in git_prettify_dir_path().
Diffstat (limited to 'src/fileops.c')
-rw-r--r--src/fileops.c65
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;