Blob Blame History Raw
diff -rup libvirt-0.7.1/src/libvirt_private.syms paths/src/libvirt_private.syms
--- libvirt-0.7.1/src/libvirt_private.syms	2010-05-26 12:48:49.276277000 -0400
+++ paths/src/libvirt_private.syms	2010-05-26 13:00:47.501023000 -0400
@@ -417,6 +417,7 @@ virParseMacAddr;
 virFileDeletePid;
 virFindFileInPath;
 virFileExists;
+virFileSanitizePath;
 virFileHasSuffix;
 virFileLinkPointsTo;
 virFileMakePath;
diff -rup libvirt-0.7.1/src/storage_conf.c paths/src/storage_conf.c
--- libvirt-0.7.1/src/storage_conf.c	2010-05-26 12:48:48.885306000 -0400
+++ paths/src/storage_conf.c	2010-05-26 13:00:17.027330000 -0400
@@ -463,6 +463,7 @@ virStoragePoolDefParseXML(virConnectPtr 
     char *type = NULL;
     char *uuid = NULL;
     char *authType = NULL;
+    char *tmppath;
 
     if (VIR_ALLOC(ret) < 0) {
         virReportOOMError(conn);
@@ -610,11 +611,15 @@ virStoragePoolDefParseXML(virConnectPtr 
             goto cleanup;
     }
 
-    if ((ret->target.path = virXPathString(conn, "string(./target/path)", ctxt)) == NULL) {
+    if ((tmppath = virXPathString(conn, "string(./target/path)", ctxt)) == NULL) {
         virStorageReportError(conn, VIR_ERR_XML_ERROR,
                               "%s", _("missing storage pool target path"));
         goto cleanup;
     }
+    ret->target.path = virFileSanitizePath(tmppath);
+    VIR_FREE(tmppath);
+    if (!ret->target.path)
+        goto cleanup;
 
     if (virStorageDefParsePerms(conn, ctxt, &ret->target.perms,
                                 "./target/permissions", 0700) < 0)
diff -rup libvirt-0.7.1/src/storage_driver.c paths/src/storage_driver.c
--- libvirt-0.7.1/src/storage_driver.c	2009-09-10 09:45:00.000000000 -0400
+++ paths/src/storage_driver.c	2010-05-26 12:59:14.815537000 -0400
@@ -1152,6 +1152,11 @@ storageVolumeLookupByPath(virConnectPtr 
     virStorageDriverStatePtr driver = conn->storagePrivateData;
     unsigned int i;
     virStorageVolPtr ret = NULL;
+    char *cleanpath;
+
+    cleanpath = virFileSanitizePath(path);
+    if (!cleanpath)
+        return NULL;
 
     storageDriverLock(driver);
     for (i = 0 ; i < driver->pools.count && !ret ; i++) {
@@ -1162,7 +1167,7 @@ storageVolumeLookupByPath(virConnectPtr 
 
             stable_path = virStorageBackendStablePath(conn,
                                                       driver->pools.objs[i],
-                                                      path);
+                                                      cleanpath);
             /*
              * virStorageBackendStablePath already does
              * virStorageReportError if it fails; we just need to keep
@@ -1191,6 +1196,7 @@ storageVolumeLookupByPath(virConnectPtr 
                               "%s", _("no storage vol with matching path"));
 
 cleanup:
+    VIR_FREE(cleanpath);
     storageDriverUnlock(driver);
     return ret;
 }
diff -rup libvirt-0.7.1/src/util.c paths/src/util.c
--- libvirt-0.7.1/src/util.c	2010-05-26 12:48:48.840341000 -0400
+++ paths/src/util.c	2010-05-26 12:58:02.088721000 -0400
@@ -1126,6 +1126,55 @@ int virFileExists(const char *path)
     return(0);
 }
 
+/* Remove spurious / characters from a path. The result must be freed */
+char *
+virFileSanitizePath(const char *path)
+{
+    const char *cur = path;
+    char *cleanpath;
+    int idx = 0;
+
+    cleanpath = strdup(path);
+    if (!cleanpath) {
+        virReportOOMError(NULL);
+        return NULL;
+    }
+
+    /* Need to sanitize:
+     * //           -> //
+     * ///          -> /
+     * /../foo      -> /../foo
+     * /foo///bar/  -> /foo/bar
+     */
+
+    /* Starting with // is valid posix, but ///foo == /foo */
+    if (cur[0] == '/' && cur[1] == '/' && cur[2] != '/') {
+        idx = 2;
+        cur += 2;
+    }
+
+    /* Sanitize path in place */
+    while (*cur != '\0') {
+        if (*cur != '/') {
+            cleanpath[idx++] = *cur++;
+            continue;
+        }
+
+        /* Skip all extra / */
+        while (*++cur == '/')
+            continue;
+
+        /* Don't add a trailing / */
+        if (idx != 0 && *cur == '\0')
+            break;
+
+        cleanpath[idx++] = '/';
+    }
+    cleanpath[idx] = '\0';
+
+    return cleanpath;
+}
+
 int virFileMakePath(const char *path)
 {
     struct stat st;
diff -rup libvirt-0.7.1/src/util.h paths/src/util.h
--- libvirt-0.7.1/src/util.h	2010-05-26 12:48:48.749342000 -0400
+++ paths/src/util.h	2010-05-26 12:56:57.494264000 -0400
@@ -107,6 +107,9 @@ char *virFindFileInPath(const char *file
 
 int virFileExists(const char *path);
 
+char *virFileSanitizePath(const char *path);
+
+
 int virFileMakePath(const char *path);
 
 int virFileBuildPath(const char *dir,