aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/util.h6
-rw-r--r--lib/util/canonicalize_name.c78
2 files changed, 41 insertions, 43 deletions
diff --git a/include/util.h b/include/util.h
index 28d21bc..d5b20dd 100644
--- a/include/util.h
+++ b/include/util.h
@@ -6,9 +6,9 @@
#include <stdint.h>
/*
- Removes all preceeding and trailing slashes, shortens all sequences of
- slashes to a single slash and returns failure state if one of the path
- components is '..' or '.'.
+ Convert back to forward slashed, remove all preceeding and trailing slashes,
+ collapse all sequences of slashes, remove all path components that are '.'
+ and returns failure state if one of the path components is '..'.
Returns 0 on success.
*/
diff --git a/lib/util/canonicalize_name.c b/lib/util/canonicalize_name.c
index 6703b66..57e4d66 100644
--- a/lib/util/canonicalize_name.c
+++ b/lib/util/canonicalize_name.c
@@ -1,56 +1,54 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
-#include <string.h>
-
#include "util.h"
-int canonicalize_name(char *filename)
+static void normalize_slashes(char *filename)
{
- char *ptr = filename;
- int i;
-
- while (*ptr == '/')
- ++ptr;
-
- if (ptr != filename) {
- memmove(filename, ptr, strlen(ptr) + 1);
- ptr = filename;
- }
-
- while (*ptr != '\0') {
- if (*ptr == '/') {
- for (i = 0; ptr[i] == '/'; ++i)
- ;
-
- if (i > 1)
- memmove(ptr + 1, ptr + i, strlen(ptr + i) + 1);
- }
-
- if (ptr[0] == '/' && ptr[1] == '\0') {
- *ptr = '\0';
- break;
+ char *dst = filename, *src = filename;
+
+ while (*src == '/' || *src == '\\')
+ ++src;
+
+ while (*src != '\0') {
+ if (*src == '/' || *src == '\\') {
+ while (*src == '/' || *src == '\\')
+ ++src;
+ if (*src == '\0')
+ break;
+ *(dst++) = '/';
+ } else {
+ *(dst++) = *(src++);
}
-
- ++ptr;
}
- ptr = filename;
+ *dst = '\0';
+}
- while (*ptr != '\0') {
- if (ptr[0] == '.') {
- if (ptr[1] == '/' || ptr[1] == '\0')
- return -1;
+int canonicalize_name(char *filename)
+{
+ char *dst = filename, *src = filename;
- if (ptr[1] == '.' &&
- (ptr[2] == '/' || ptr[2] == '\0')) {
- return -1;
+ normalize_slashes(filename);
+
+ while (*src != '\0') {
+ if (src[0] == '.') {
+ if (src[1] == '\0')
+ break;
+ if (src[1] == '/') {
+ src += 2;
+ continue;
}
+ if (src[1] == '.' && (src[2] == '/' || src[2] == '\0'))
+ return -1;
}
- while (*ptr != '\0' && *ptr != '/')
- ++ptr;
- if (*ptr == '/')
- ++ptr;
+ while (*src != '\0' && *src != '/')
+ *(dst++) = *(src++);
+
+ if (*src == '/')
+ *(dst++) = *(src++);
}
+ *dst = '\0';
+ normalize_slashes(filename);
return 0;
}