Commit e16c2f6a4cfff50907699d73daad2c10565ec686

nulltoken 2011-01-20T19:51:34

Small enhancements to git_prettify_dir_path(). - Secured buffer ahead reading. - Guard against potential multiple dot path traversal (cf http://cwe.mitre.org/data/definitions/33.html)

diff --git a/src/fileops.c b/src/fileops.c
index 1c480e7..5953f26 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -413,9 +413,13 @@ int git_prettify_dir_path(char *buffer_out, const char *path)
 			current++;
 
 			/* Handle the double-dot upward directory navigation */
-			if (*current == '.') {
+			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;
+
 				*buffer_out ='\0';
 				len = retrieve_previous_path_component_start(buffer_out_start);
 				if (len < GIT_SUCCESS)
@@ -424,7 +428,7 @@ int git_prettify_dir_path(char *buffer_out, const char *path)
 				buffer_out = (char *)buffer_out_start + len;
 			}
 
-			if (*current == '/')
+			if (current < buffer_end && *current == '/')
 				current++;
 
 			continue;
diff --git a/tests/t0005-path.c b/tests/t0005-path.c
index b00989f..222e07c 100644
--- a/tests/t0005-path.c
+++ b/tests/t0005-path.c
@@ -47,6 +47,12 @@ BEGIN_TEST(path_prettifying)
 	must_pass(ensure_normalized("d1/s1///s2/..//../s3/", "d1/s3/"));
 	must_pass(ensure_normalized("d1/s1//../s2/../../d2", "d2/"));
 	must_pass(ensure_normalized("dir/sub/../", "dir/"));
+	must_fail(ensure_normalized("....", NULL));
+	must_fail(ensure_normalized("...", NULL));
+	must_fail(ensure_normalized("./...", NULL));
+	must_fail(ensure_normalized("d1/...", NULL));
+	must_fail(ensure_normalized("d1/.../", NULL));
+	must_fail(ensure_normalized("d1/.../d2", NULL));
 	
 	must_pass(ensure_normalized("/", "/"));
 	must_pass(ensure_normalized("//", "/"));
@@ -70,4 +76,10 @@ BEGIN_TEST(path_prettifying)
 	must_pass(ensure_normalized("/dir/s1/../s2/", "/dir/s2/"));
 	must_pass(ensure_normalized("/d1/s1///s2/..//../s3/", "/d1/s3/"));
 	must_pass(ensure_normalized("/d1/s1//../s2/../../d2", "/d2/"));
+	must_fail(ensure_normalized("/....", NULL));
+	must_fail(ensure_normalized("/...", NULL));
+	must_fail(ensure_normalized("/./...", NULL));
+	must_fail(ensure_normalized("/d1/...", NULL));
+	must_fail(ensure_normalized("/d1/.../", NULL));
+	must_fail(ensure_normalized("/d1/.../d2", NULL));
 END_TEST