aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-12-26 02:07:44 +0100
committerMax Kellermann <max@duempel.org>2009-12-27 14:17:25 +0100
commitaf964e8929407c43e6c45c2bd3f1a0c534b2f0cc (patch)
treed01305076ab19c81691932230f602600dafba044
parent554b2b0ed9f8e27e3e03e1174f0c1feb7a5bf130 (diff)
downloadmpd-af964e8929407c43e6c45c2bd3f1a0c534b2f0cc.tar.gz
mpd-af964e8929407c43e6c45c2bd3f1a0c534b2f0cc.tar.xz
mpd-af964e8929407c43e6c45c2bd3f1a0c534b2f0cc.zip
uri: added function uri_safe_local()
-rw-r--r--src/uri.c30
-rw-r--r--src/uri.h12
2 files changed, 42 insertions, 0 deletions
diff --git a/src/uri.c b/src/uri.c
index 41a613de7..3e622de3b 100644
--- a/src/uri.c
+++ b/src/uri.c
@@ -22,6 +22,7 @@
#include <glib.h>
+#include <assert.h>
#include <string.h>
bool uri_has_scheme(const char *uri)
@@ -45,6 +46,35 @@ uri_get_suffix(const char *uri)
return suffix;
}
+static const char *
+verify_uri_segment(const char *p)
+{
+ const char *q;
+
+ if (*p == 0 || *p == '/' || *p == '.')
+ return NULL;
+
+ q = strchr(p + 1, '/');
+ return q != NULL ? q : "";
+}
+
+bool
+uri_safe_local(const char *uri)
+{
+ while (true) {
+ uri = verify_uri_segment(uri);
+ if (uri == NULL)
+ return false;
+
+ if (*uri == 0)
+ return true;
+
+ assert(*uri == '/');
+
+ ++uri;
+ }
+}
+
char *
uri_remove_auth(const char *uri)
{
diff --git a/src/uri.h b/src/uri.h
index 46d36308b..857080f84 100644
--- a/src/uri.h
+++ b/src/uri.h
@@ -36,6 +36,18 @@ const char *
uri_get_suffix(const char *uri);
/**
+ * Returns true if this is a safe "local" URI:
+ *
+ * - non-empty
+ * - does not begin or end with a slash
+ * - no double slashes
+ * - no path component begins with a dot
+ */
+G_GNUC_PURE
+bool
+uri_safe_local(const char *uri);
+
+/**
* Removes HTTP username and password from the URI. This may be
* useful for displaying an URI without disclosing secrets. Returns
* NULL if nothing needs to be removed, or if the URI is not