Thread (47 messages) flat view 47 messages, 5 authors, 2016-06-15

Re: [PATCH v2 2/2] setup: Don't dereference in-tree symlinks for absolute paths

From: Duy Nguyen <hidden>
Date: 2016-06-15 22:59:45

On Mon, Jan 27, 2014 at 7:07 AM, Martin Erik Werner
[off-list ref] wrote:
quoted hunk ↗ jump to hunk
diff --git a/setup.c b/setup.c
index 5432a31..0789a96 100644
--- a/setup.c
+++ b/setup.c
@@ -22,11 +22,51 @@ char *prefix_path_gently(const char *prefix, int len,
        const char *orig = path;
        char *sanitized;
        if (is_absolute_path(orig)) {
-               const char *temp = real_path(path);
-               sanitized = xmalloc(len + strlen(temp) + 1);
-               strcpy(sanitized, temp);
+               int i, match;
+               size_t wtpartlen;
+               char *npath, *wtpart;
+               struct string_list list = STRING_LIST_INIT_DUP;
+               const char *work_tree = get_git_work_tree();
+               if (!work_tree)
+                       return NULL;
+               npath = xmalloc(strlen(path) + 1);
                if (remaining_prefix)
                        *remaining_prefix = 0;
+               if (normalize_path_copy_len(npath, path, remaining_prefix)) {
+                       free(npath);
+                       return NULL;
+               }
+
+               string_list_split(&list, npath, '/', -1);
+               wtpart = xmalloc(strlen(npath) + 1);
+               i = 0;
+               match = 0;
+               strcpy(wtpart, list.items[i++].string);
+               strcat(wtpart, "/");
+               if (strcmp(real_path(wtpart), work_tree) == 0) {
+                       match = 1;
+               } else {
Could we remove this part and let the while loop handle the first path
component too? The only difference I see is if this code matches, we
have a trailing slash, while the "while" loop does not have a trailing
slash in wtpart.
+                       while (i < list.nr) {
+                               strcat(wtpart, list.items[i++].string);
+                               if (strcmp(real_path(wtpart), work_tree) == 0) {
+                                       match = 1;
+                                       break;
+                               }
+                               strcat(wtpart, "/");
+                       }
+               }
+               string_list_clear(&list, 0);
+               if (!match) {
+                       free(npath);
+                       free(wtpart);
+                       return NULL;
+               }
+
+               wtpartlen = strlen(wtpart);
+               sanitized = xmalloc(strlen(npath) - wtpartlen);
+               strcpy(sanitized, npath + wtpartlen + 1);
This "+ 1" is to ignore '/', isn't it? If so we should not do if match
is set 1 outside "while" loop.
+               free(npath);
+               free(wtpart);
All this new code looks long enough to be a separate function with a
meaningful name. And we could travese through each path component in
npath without wtpart (replacing '/' with '\0' to terminate the string
temporarily for real_path()). But it's up to you. Whichever way is
easier to read to you.
quoted hunk ↗ jump to hunk
        } else {
                sanitized = xmalloc(len + strlen(path) + 1);
                if (len)
@@ -34,26 +74,10 @@ char *prefix_path_gently(const char *prefix, int len,
                strcpy(sanitized + len, path);
                if (remaining_prefix)
                        *remaining_prefix = len;
-       }
-       if (normalize_path_copy_len(sanitized, sanitized, remaining_prefix))
-               goto error_out;
-       if (is_absolute_path(orig)) {
-               size_t root_len, len, total;
-               const char *work_tree = get_git_work_tree();
-               if (!work_tree)
-                       goto error_out;
-               len = strlen(work_tree);
-               root_len = offset_1st_component(work_tree);
-               total = strlen(sanitized) + 1;
-               if (strncmp(sanitized, work_tree, len) ||
-                   (len > root_len && sanitized[len] != '\0' && sanitized[len] != '/')) {
-               error_out:
+               if (normalize_path_copy_len(sanitized, sanitized, remaining_prefix)) {
                        free(sanitized);
                        return NULL;
                }
-               if (sanitized[len] == '/')
-                       len++;
-               memmove(sanitized, sanitized + len, total - len);
        }
        return sanitized;
 }
-- 
Duy
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help