summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2013-06-08 18:29:06 +0200
committerYorhel <git@yorhel.nl>2013-06-08 18:44:35 +0200
commitbada622b15fbb18e9843634cd4586a909987efcd (patch)
treebb945a0a3cd145dc8cf21d98d391f56d443d7608
parente8e1735124b766e4ecfcdbb05040b30ae41b04d6 (diff)
util/path: Add path_isancestor() function
Despite its simplicity, I keep finding it hard to get such string comparison functions right. This function makes it significantly harder to make any mistakes in path matching, and also keeps the intent of the code clear.
-rw-r--r--src/util/path.h9
-rw-r--r--test/path.c19
2 files changed, 27 insertions, 1 deletions
diff --git a/src/util/path.h b/src/util/path.h
index 024e5ad..998864e 100644
--- a/src/util/path.h
+++ b/src/util/path.h
@@ -41,5 +41,14 @@
*/
char *path_normalize(char *);
+
+/* Returns true if a is an ancestor of b. e.g. "/" and "/some" are ancestors of
+ * "/some/path". Both paths are assumed to be absolute and normalized according
+ * to path_normalize(). */
+static inline bool path_isancestor(const char *a, const char *b) {
+ size_t alen = strlen(a);
+ return strncmp(a, b, alen) == 0 && (b[alen] == '/' || (alen == 1 && b[alen]));
+}
+
#endif
/* vim: set noet sw=4 ts=4: */
diff --git a/test/path.c b/test/path.c
index 717cd84..b46e83b 100644
--- a/test/path.c
+++ b/test/path.c
@@ -34,7 +34,7 @@
free(buf);\
} while(0)
-int main(int argc, char **argv) {
+static void t_normalize() {
T("/", "/");
T("//", "/");
T("/abc", "/abc");
@@ -73,6 +73,23 @@ int main(int argc, char **argv) {
T("/..a..", "/..a..");
T("/..a.", "/..a.");
T("/.a..", "/.a..");
+}
+
+#undef T
+
+
+int main(int argc, char **argv) {
+ t_normalize();
+
+ assert(path_isancestor("/", "/some/path"));
+ assert(path_isancestor("/some", "/some/path"));
+ assert(path_isancestor("/", "/some"));
+ assert(!path_isancestor("/", "/"));
+ assert(!path_isancestor("/some/path", "/some/path"));
+ assert(!path_isancestor("/some/path/a", "/some/path"));
+ assert(!path_isancestor("/some/patha", "/some/path"));
+ assert(!path_isancestor("/some/pa", "/some/path"));
+ assert(!path_isancestor("/som", "/some/path"));
return 0;
}