loader: Remove duplicated delimiting chars in paths
authorMartin Blanchard <tchaik@gmx.com>
Wed, 9 May 2018 21:47:12 +0000 (22:47 +0100)
committerLenny Komow <lenny@lunarg.com>
Thu, 10 May 2018 17:10:33 +0000 (11:10 -0600)
Before loading a manifest file, its full path is strcmp() with already
loaded ones in order not to load the same file twice. While being simple
and efficent, this mechanism is not able to detect subtle duplicates
like these:

/usr/share/vulkan/icd.d/intel_icd.x86_64.json
/usr/share//vulkan/icd.d/intel_icd.x86_64.json

This patch ensure that searched paths do not contains such duplicated
directory delimiting characters in order to avoid this kind of problem.

Fixes #2331
Fixes #2629

loader/loader.c

index 7298c67247c083e21847f6d8095c13b39ebc38fd..26ff520034009b9890f7aaf6b84cd35217d8925d 100644 (file)
@@ -3029,6 +3029,7 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, co
     const char *override = NULL;
     char *override_getenv = NULL;
     char *loc, *orig_loc = NULL;
+    size_t loc_size = 0;
     char *reg = NULL;
     char *file, *next_file, *name;
     size_t alloced_count = 64;
@@ -3076,7 +3077,6 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, co
     // Make a copy of the input we are using so it is not modified
     // Also handle getting the location(s) from registry on Windows
     if (override == NULL) {
-        size_t loc_size = 0;
 #if !defined(_WIN32)
         const char *xdgconfdirs = loader_secure_getenv("XDG_CONFIG_DIRS", inst);
         const char *xdgdatadirs = loader_secure_getenv("XDG_DATA_DIRS", inst);
@@ -3257,6 +3257,18 @@ static VkResult loader_get_manifest_files(const struct loader_instance *inst, co
         strcpy(loc, override);
     }
 
+    size_t n = 0;
+    loc_size = strlen(loc);
+    // Remove duplicated directory symbols (could hide duplicated paths)
+    for (size_t i = 0; i < loc_size; i++) {
+        if (n > 0) loc[i] = loc[i + n];
+        if (loc[i] == DIRECTORY_SYMBOL && loc[i + 1 + n] == DIRECTORY_SYMBOL) {
+            loc_size--;
+            n++;
+        }
+    }
+    loc[loc_size] = '\0';
+
     // Print out the paths being searched if debugging is enabled
     loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Searching the following paths for manifest files: %s\n", loc);