Re: [PATCH v3 3/4] setup: Add 'abspath_part_inside_repo' function
From: Duy Nguyen <hidden>
Date: 2016-06-15 22:59:47
On Sat, Feb 1, 2014 at 3:22 AM, Martin Erik Werner [off-list ref] wrote:
quoted hunk ↗ jump to hunk
diff --git a/setup.c b/setup.c index 5432a31..e606846 100644 --- a/setup.c +++ b/setup.c@@ -77,6 +77,69 @@ int path_inside_repo(const char *prefix, const char *path) return 0; } +/* + * It is ok if dst == src, but they should not overlap otherwise. + * No checking if the path is in fact an absolute path is done, and it must + * already be normalized. + * + * Find the part of an absolute path that lies inside the work tree by + * dereferencing symlinks outside the work tree, for example: + * /dir1/repo/dir2/file (work tree is /dir1/repo) -> dir2/file + * /dir/file (work tree is /) -> dir/file + * /dir/symlink1/symlink2 (symlink1 points to work tree) -> symlink2 + * /dir/repo (exactly equal to work tree) -> (empty string) + */ +int abspath_part_inside_repo(char *dst, const char* src) +{ + size_t len; + char *dst0; + char temp; + + const char* work_tree = get_git_work_tree(); + if (!work_tree) + return -1; + len = strlen(src); + dst0 = dst; + + // check root level
Um.. no C++ style comments. And there should be a test that work_tree is the prefix of src (common case). If so we can return early and do not need to do real_path() on every path component.
+ if (has_dos_drive_prefix(src)) {
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ } else {
+ *dst++ = *src++;
+ }
+ temp = *dst;
+ *dst = '\0';
+ if (strcmp(real_path(dst0), work_tree) == 0) {
+ *dst = temp;
+ memmove(dst0, src, len - (dst - dst0) + 1);
+ return 0;
+ }
+ *dst = temp;
+
+ // check each level
+ while (*dst != '\0') {
+ *dst++ = *src++;
+ if (*dst == '/') {
+ *dst = '\0';
+ if (strcmp(real_path(dst0), work_tree) == 0) {
+ memmove(dst0, src + 1, len - (dst - dst0));
+ return 0;
+ }
+ *dst = '/';
+ }
+ }
+
+ // check whole path
+ if (strcmp(real_path(dst0), work_tree) == 0) {
+ *dst0 = '\0';
+ return 0;
+ }
+
+ return -1;
+}
+
int check_filename(const char *prefix, const char *arg)
{
const char *name;
--
1.8.5.2-- Duy