
On 05/20/2010 10:04 AM, Cole Robinson wrote:
Spurious / in a pool target path makes life difficult for apps using the GetVolByPath, and doing other path based comparisons with pools. This has caused a few issues for virt-manager users:
https://bugzilla.redhat.com/show_bug.cgi?id=494005 https://bugzilla.redhat.com/show_bug.cgi?id=593565
Add a new util API which removes spurious /, virFileSanitizePath. Sanitize target paths when parsing pool XML, and for paths passed to GetVolByPath.
In general, I like the idea, whether or not we should be moving the sanitization into a gnulib function. But I don't think it's ready for an ack quite yet.
index e937d39..8f86ed6 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1921,6 +1921,41 @@ int virFileAbsPath(const char *path, char **abspath) 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(); + return NULL; + } + + /* Sanitize path in place */ + while (*cur != '\0') { + if (*cur == '/') { + /* Skip all extra / */ + while (*++cur == '/') + continue;
POSIX says that you must be careful of "//file" - you cannot blindly simplify to "/file" (case in point - cygwin). But POSIX also says that "///file" sanitizes to "/file".
+ + /* Don't add a trailing / */ + if (*cur == '\0') + break; + + cleanpath[idx++] = '/'; + } + + cleanpath[idx++] = *cur++; + } + cleanpath[idx] = '\0'; + + return cleanpath;
Sanitizing "a/b/../c" to "a/c" might not always be the right thing (what if a is a symlink?), but it would also be safe to sanitize "a/./b" to "a/b".
+} + /* Like strtol, but produce an "int" result, and check more carefully. Return 0 upon success; return -1 to indicate failure. When END_PTR is NULL, the byte after the final valid digit must be NUL. diff --git a/src/util/util.h b/src/util/util.h index 6bf6bcc..abc2688 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -118,6 +118,8 @@ char *virFindFileInPath(const char *file);
int virFileExists(const char *path);
+char *virFileSanitizePath(const char *path);
Mark this with ATTRIBUTE_NONNULL(1). -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org