summaryrefslogtreecommitdiff
path: root/src/fileops.c
diff options
context:
space:
mode:
authornulltoken <emeric.fermas@gmail.com>2011-01-22 14:38:47 +0100
committerVicent Marti <tanoku@gmail.com>2011-01-29 03:29:32 +0200
commit4581c22abcb3bbb27f254f06215651df8ce6fee2 (patch)
treea323030c8a92adc9d3177c36b94008c3a635614b /src/fileops.c
parent9dd34b1e89f9d52397dacba1575e3b25cfd6e52e (diff)
downloadlibgit2-4581c22abcb3bbb27f254f06215651df8ce6fee2.tar.gz
Optimized git_prettify_dir_path() parsing.
Diffstat (limited to 'src/fileops.c')
-rw-r--r--src/fileops.c39
1 files changed, 18 insertions, 21 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 191aa91fa..00eb4fc37 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -393,10 +393,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, *end;
+ int len = 0, segment_len, only_dots;
+ char *current;
const char *buffer_out_start, *buffer_end;
- int only_dots;
buffer_out_start = buffer_out;
current = (char *)path;
@@ -409,48 +408,46 @@ int git_prettify_dir_path(char *buffer_out, const char *path)
continue;
}
- end = current;
only_dots = 1;
+ segment_len = 0;
- /* Seek end of path segment */
- while (end < buffer_end && *end !='/')
+ /* Copy path segment to the output */
+ while (current < buffer_end && *current !='/')
{
- only_dots &= (*end == '.');
- end++;
+ only_dots &= (*current == '.');
+ *buffer_out++ = *current++;
+ segment_len++;
+ len++;
}
/* Skip current directory */
- if (only_dots && end == current + 1)
+ if (only_dots && segment_len == 1)
{
- current += 2;
+ current++;
+ buffer_out -= segment_len;
+ len -= segment_len;
continue;
}
/* Handle the double-dot upward directory navigation */
- if (only_dots && end == current + 2)
+ if (only_dots && segment_len == 2)
{
+ current++;
+ buffer_out -= segment_len;
+
*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;
}
/* Guard against potential multiple dot path traversal (cf http://cwe.mitre.org/data/definitions/33.html) */
- if (only_dots && end > current)
+ if (only_dots &&segment_len > 0)
return GIT_ERROR;
- /* Copy to output the path segment */
- while (current < end)
- {
- *buffer_out++ = *current++;
- len++;
- }
-
*buffer_out++ = '/';
len++;
}