changeset 9599:895b5215b578

Make it possible to avoid all memory leaks when calling relocate().
author Bruno Haible <bruno@clisp.org>
date Thu, 10 Jan 2008 11:12:06 +0100
parents 2ef16c5bba5b
children 99268e709d31
files ChangeLog lib/relocatable.c lib/relocatable.h
diffstat 3 files changed, 30 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,12 @@
-2008-01-10   Colin Watson  <cjwatson@debian.org>
+2008-01-10  Bruno Haible  <bruno@clisp.org>
+
+	* lib/relocatable.h (relocate): State whether result is freshly
+	allocated or not.
+	* lib/relocatable.c (relocate): Return a freshly allocated string
+	instead of a pointer to a privately held string.
+	Reported by Sylvain Beucler <beuc@gnu.org>.
+
+2008-01-10  Colin Watson  <cjwatson@debian.org>
 
 	* lib/canonicalize-lgpl.c [!_LIBC]: Fix typo in #if directive:
 	s/S_ISNLK/S_ISLNK/.
--- a/lib/relocatable.c
+++ b/lib/relocatable.c
@@ -409,7 +409,9 @@
 #endif /* PIC */
 
 /* Returns the pathname, relocated according to the current installation
-   directory.  */
+   directory.
+   The returned string is either PATHNAME unmodified or a freshly allocated
+   string that you can free with free() after casting it to 'char *'.  */
 const char *
 relocate (const char *pathname)
 {
@@ -455,9 +457,19 @@
       && strncmp (pathname, orig_prefix, orig_prefix_len) == 0)
     {
       if (pathname[orig_prefix_len] == '\0')
-	/* pathname equals orig_prefix.  */
-	return curr_prefix;
-      if (ISSLASH (pathname[orig_prefix_len]))
+	{
+	  /* pathname equals orig_prefix.  */
+	  char *result = (char *) xmalloc (strlen (curr_prefix) + 1);
+
+#ifdef NO_XMALLOC
+	  if (result != NULL)
+#endif
+	    {
+	      strcpy (result, curr_prefix);
+	      return result;
+	    }
+	}
+      else if (ISSLASH (pathname[orig_prefix_len]))
 	{
 	  /* pathname starts with orig_prefix.  */
 	  const char *pathname_tail = &pathname[orig_prefix_len];
--- a/lib/relocatable.h
+++ b/lib/relocatable.h
@@ -49,12 +49,15 @@
 			      const char *curr_prefix);
 
 /* Returns the pathname, relocated according to the current installation
-   directory.  */
+   directory.
+   The returned string is either PATHNAME unmodified or a freshly allocated
+   string that you can free with free() after casting it to 'char *'.  */
 extern const char * relocate (const char *pathname);
 
 /* Memory management: relocate() leaks memory, because it has to construct
    a fresh pathname.  If this is a problem because your program calls
-   relocate() frequently, think about caching the result.  */
+   relocate() frequently, think about caching the result.  Or free the
+   return value if it was different from the argument pathname.  */
 
 /* Convenience function:
    Computes the current installation prefix, based on the original