Not only did this function leak(p), but it would also over-allocate (by the length of basename(base_file)), and then later, re-alloc to compensate, so I rewrote it: >From 1dc52930daa000b407d8a8f18588a19cf4e8b7f5 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering@xxxxxxxxxx> Date: Thu, 4 Feb 2010 16:55:57 +0100 Subject: [PATCH] absolutePathFromBaseFile: don't leak when first arg contains no "/" * src/util/storage_file.c: Include "dirname.h". (absolutePathFromBaseFile): Rewrite not to leak, and to require fewer allocations. * bootstrap (modules): Add dirname-lgpl and stpncpy. * .gnulib: Update submodule to the latest. --- .gnulib | 2 +- bootstrap | 2 ++ src/util/storage_file.c | 27 ++++++++++----------------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/.gnulib b/.gnulib index 146d914..9d0ad65 160000 --- a/.gnulib +++ b/.gnulib @@ -1 +1 @@ -Subproject commit 146d9145073e62a2096a2d6b33f75e93908fedf3 +Subproject commit 9d0ad652de159d08e5f679842f8a2a5658196361 diff --git a/bootstrap b/bootstrap index cc3c6ef..5cc43c5 100755 --- a/bootstrap +++ b/bootstrap @@ -71,6 +71,7 @@ c-ctype canonicalize-lgpl close connect +dirname-lgpl getaddrinfo gethostname getpass @@ -93,6 +94,7 @@ send setsockopt socket stpcpy +stpncpy strchrnul strndup strerror diff --git a/src/util/storage_file.c b/src/util/storage_file.c index 44057d2..8c53fba 100644 --- a/src/util/storage_file.c +++ b/src/util/storage_file.c @@ -1,7 +1,7 @@ /* * storage_file.c: file utility functions for FS storage backend * - * Copyright (C) 2007-2009 Red Hat, Inc. + * Copyright (C) 2007-2010 Red Hat, Inc. * Copyright (C) 2007-2008 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -26,6 +26,7 @@ #include <unistd.h> #include <fcntl.h> +#include "dirname.h" #include "memory.h" #include "virterror_internal.h" @@ -246,26 +247,18 @@ vmdk4GetBackingStore(virConnectPtr conn, static char * absolutePathFromBaseFile(const char *base_file, const char *path) { - size_t base_size, path_size; - char *res, *p; + char *res; + size_t d_len = dir_len (base_file); - if (*path == '/') + /* If path is already absolute, or if dirname(base_file) is ".", + just return a copy of path. */ + if (*path == '/' || d_len == 0) return strdup(path); - base_size = strlen(base_file) + 1; - path_size = strlen(path) + 1; - if (VIR_ALLOC_N(res, base_size - 1 + path_size) < 0) + if (VIR_ALLOC_N(res, d_len + 1 + strlen(path) + 1) < 0) return NULL; - memcpy(res, base_file, base_size); - p = strrchr(res, '/'); - if (p != NULL) - p++; - else - p = res; - memcpy(p, path, path_size); - if (VIR_REALLOC_N(res, (p + path_size) - res) < 0) { - /* Ignore failure */ - } + + stpcpy(stpcpy(stpncpy(res, base_file, d_len), "/"), path); return res; } -- 1.7.0.rc1.199.g9253a -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list