diff options
author | Andreas Gruenbacher <andreas.gruenbacher@gmail.com> | 2015-01-20 10:09:00 +0100 |
---|---|---|
committer | Andreas Gruenbacher <andreas.gruenbacher@gmail.com> | 2015-01-20 10:10:10 +0100 |
commit | ae88d1c270df6ba685bd422f3bf2607367de7cfc (patch) | |
tree | ffe17ec63d9e9a3549f974f55b46ca99367f7f47 | |
parent | 4e9269a5fc1fe80a1095a92593dd85db871e1fd3 (diff) | |
download | patch-ae88d1c270df6ba685bd422f3bf2607367de7cfc.tar.gz |
Move symlink_target_is_valid() and cwd_is_root()
* src/util.c: Move symlink_target_is_valid() and cwd_is_root() here from
src/pch.c.
-rw-r--r-- | src/pch.c | 77 | ||||
-rw-r--r-- | src/pch.h | 1 | ||||
-rw-r--r-- | src/util.c | 77 | ||||
-rw-r--r-- | src/util.h | 1 |
4 files changed, 78 insertions, 78 deletions
@@ -387,29 +387,6 @@ skip_hex_digits (char const *str) return s == str ? NULL : s; } -/* Check if we are in the root of a particular filesystem namespace ("/" on - UNIX or a particular drive's root on DOS-like systems). */ -static bool -cwd_is_root (char const *name) -{ - unsigned int prefix_len = FILE_SYSTEM_PREFIX_LEN (name); - char root[prefix_len + 2]; - struct stat st; - dev_t root_dev; - ino_t root_ino; - - memcpy (root, name, prefix_len); - root[prefix_len] = '/'; - root[prefix_len + 1] = 0; - if (stat (root, &st)) - return false; - root_dev = st.st_dev; - root_ino = st.st_ino; - if (stat (".", &st)) - return false; - return root_dev == st.st_dev && root_ino == st.st_ino; -} - static bool name_is_valid (char const *name) { @@ -454,60 +431,6 @@ name_is_valid (char const *name) return is_valid; } -bool -symlink_target_is_valid (char const *target, char const *to) -{ - bool is_valid; - - if (IS_ABSOLUTE_FILE_NAME (to)) - is_valid = true; - else if (IS_ABSOLUTE_FILE_NAME (target)) - is_valid = false; - else - { - unsigned int depth = 0; - char const *t; - - is_valid = true; - t = to; - while (*t) - { - while (*t && ! ISSLASH (*t)) - t++; - if (ISSLASH (*t)) - { - while (ISSLASH (*t)) - t++; - depth++; - } - } - - t = target; - while (*t) - { - if (*t == '.' && *++t == '.' && (! *++t || ISSLASH (*t))) - { - if (! depth--) - { - is_valid = false; - break; - } - } - else - { - while (*t && ! ISSLASH (*t)) - t++; - depth++; - } - while (ISSLASH (*t)) - t++; - } - } - - /* Allow any symlink target if we are in the filesystem root. */ - return is_valid || cwd_is_root (to); -} - /* Determine what kind of diff is in the remaining part of the patch file. */ static enum diff @@ -37,7 +37,6 @@ bool pch_write_line (lin, FILE *); bool there_is_another_patch (bool, mode_t *); char *pfetch (lin) _GL_ATTRIBUTE_PURE; char pch_char (lin) _GL_ATTRIBUTE_PURE; -bool symlink_target_is_valid (char const *, char const *); int another_hunk (enum diff, bool); int pch_says_nonexistent (bool) _GL_ATTRIBUTE_PURE; size_t pch_line_len (lin) _GL_ATTRIBUTE_PURE; @@ -423,6 +423,60 @@ create_backup (char const *to, const struct stat *to_st, bool leave_original) } } +static bool +symlink_target_is_valid (char const *target, char const *to) +{ + bool is_valid; + + if (IS_ABSOLUTE_FILE_NAME (to)) + is_valid = true; + else if (IS_ABSOLUTE_FILE_NAME (target)) + is_valid = false; + else + { + unsigned int depth = 0; + char const *t; + + is_valid = true; + t = to; + while (*t) + { + while (*t && ! ISSLASH (*t)) + t++; + if (ISSLASH (*t)) + { + while (ISSLASH (*t)) + t++; + depth++; + } + } + + t = target; + while (*t) + { + if (*t == '.' && *++t == '.' && (! *++t || ISSLASH (*t))) + { + if (! depth--) + { + is_valid = false; + break; + } + } + else + { + while (*t && ! ISSLASH (*t)) + t++; + depth++; + } + while (ISSLASH (*t)) + t++; + } + } + + /* Allow any symlink target if we are in the filesystem root. */ + return is_valid || cwd_is_root (to); +} + /* Move a file FROM (where *FROM_NEEDS_REMOVAL is nonzero if FROM needs removal when cleaning up at the end of execution, and where *FROMST is FROM's status if known), @@ -1665,3 +1719,26 @@ int stat_file (char const *filename, struct stat *st) return xstat (filename, st) == 0 ? 0 : errno; } + +/* Check if we are in the root of a particular filesystem namespace ("/" on + UNIX or a particular drive's root on DOS-like systems). */ +bool +cwd_is_root (char const *name) +{ + unsigned int prefix_len = FILE_SYSTEM_PREFIX_LEN (name); + char root[prefix_len + 2]; + struct stat st; + dev_t root_dev; + ino_t root_ino; + + memcpy (root, name, prefix_len); + root[prefix_len] = '/'; + root[prefix_len + 1] = 0; + if (stat (root, &st)) + return false; + root_dev = st.st_dev; + root_ino = st.st_ino; + if (stat (".", &st)) + return false; + return root_dev == st.st_dev && root_ino == st.st_ino; +} @@ -69,6 +69,7 @@ enum file_id_type lookup_file_id (struct stat const *); void set_queued_output (struct stat const *, bool); bool has_queued_output (struct stat const *); int stat_file (char const *, struct stat *); +bool cwd_is_root (char const *); enum file_attributes { FA_TIMES = 1, |