commit - ec7988073791f4ddb1c17661eb379ff607fa636b
commit + e6eac3b8ebc595e916b1133437b204ca21ebee29
blob - eabdbf935d8610815257c95226a9987a6e95b775
blob + 435ee1d97e2cbf7f07b5608aec1e115279fc7850
--- lib/got_lib_path.h
+++ lib/got_lib_path.h
* The result is allocated with malloc(3).
*/
char *got_path_normalize(const char *);
+
+/*
+ * Canonicalize absolute paths by removing redundant path separators
+ * and resolving references to parent directories ("/../").
+ * Relative paths are copied from input to buf as-is.
+ */
+int got_canonpath(const char *input, char *buf, size_t bufsize)
blob - 99967297bba6bcde7d6126012e0a62fb85809082
blob + fa26c7a7e5b5421a2282d81af15d789f189d004b
--- lib/path.c
+++ lib/path.c
/*
* Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
+ * Copyright (c) 2015 Theo de Raadt <deraadt@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
return resolved;
}
+
+/* canonpath() from kern_pledge.c */
+int
+got_canonpath(const char *input, char *buf, size_t bufsize)
+{
+ const char *p;
+ char *q;
+
+ /* can't canon relative paths, don't bother */
+ if (!got_path_is_absolute(input)) {
+ if (strlcpy(buf, input, bufsize) >= bufsize)
+ return ENAMETOOLONG;
+ return 0;
+ }
+
+ p = input;
+ q = buf;
+ while (*p && (q - buf < bufsize)) {
+ if (p[0] == '/' && (p[1] == '/' || p[1] == '\0')) {
+ p += 1;
+
+ } else if (p[0] == '/' && p[1] == '.' &&
+ (p[2] == '/' || p[2] == '\0')) {
+ p += 2;
+
+ } else if (p[0] == '/' && p[1] == '.' && p[2] == '.' &&
+ (p[3] == '/' || p[3] == '\0')) {
+ p += 3;
+ if (q != buf) /* "/../" at start of buf */
+ while (*--q != '/')
+ continue;
+
+ } else {
+ *q++ = *p++;
+ }
+ }
+ if ((*p == '\0') && (q - buf < bufsize)) {
+ *q = 0;
+ return 0;
+ } else
+ return ENAMETOOLONG;
+}