summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2017-06-21 16:31:31 +0200
committerFlorian Weimer <fweimer@redhat.com>2017-06-21 16:31:31 +0200
commit9695dd0c9309712ed8e9c17a7040fe7af347f2dc (patch)
tree4b76b86576b2308113d31d176536aa0b92418840
parente535139e82e5a4bb0ed63b0b5165f03a9b2d0e52 (diff)
downloadglibc-9695dd0c9309712ed8e9c17a7040fe7af347f2dc.tar.gz
glibc-9695dd0c9309712ed8e9c17a7040fe7af347f2dc.tar.xz
glibc-9695dd0c9309712ed8e9c17a7040fe7af347f2dc.zip
DCIGETTEXT: Use getcwd, asprintf to construct absolute pathname
-rw-r--r--ChangeLog5
-rw-r--r--intl/dcigettext.c42
2 files changed, 19 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index 22889ee2e8..2d07c200fe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2017-06-21  Florian Weimer  <fweimer@redhat.com>
+
+	* intl/dcigettext.c (DCIGETTEXT): Use getcwd (NULL, 0) and
+	asprintf to construct an absolute pathname.
+
 2017-06-21  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
 
 	* misc/tst-preadvwritev2-common.c: New file.
diff --git a/intl/dcigettext.c b/intl/dcigettext.c
index d97746cae5..f63b34b0f5 100644
--- a/intl/dcigettext.c
+++ b/intl/dcigettext.c
@@ -59,6 +59,7 @@ extern int errno;
 
 #include <stddef.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 
 #if defined HAVE_UNISTD_H || defined _LIBC
@@ -495,6 +496,7 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
   const char *categoryname;
   const char *categoryvalue;
   const char *dirname;
+  char *xdirname = NULL;
   char *xdomainname;
   char *single_locale;
   char *retval;
@@ -624,35 +626,17 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
       if (!IS_ABSOLUTE_PATH (dirname))
 	{
 	  /* We have a relative path.  Make it absolute now.  */
-	  size_t dirname_len = strlen (dirname) + 1;
-	  size_t path_max;
-	  char *resolved_dirname;
-	  char *ret;
-
-	  path_max = (unsigned int) PATH_MAX;
-	  path_max += 2;		/* The getcwd docs say to do this.  */
-
-	  for (;;)
-	    {
-	      resolved_dirname = (char *) alloca (path_max + dirname_len);
-	      ADD_BLOCK (block_list, tmp_dirname);
-
-	      __set_errno (0);
-	      ret = getcwd (resolved_dirname, path_max);
-	      if (ret != NULL || errno != ERANGE)
-		break;
-
-	      path_max += path_max / 2;
-	      path_max += PATH_INCR;
-	    }
-
-	  if (ret == NULL)
-	    /* We cannot get the current working directory.  Don't signal an
-	       error but simply return the default string.  */
+	  char *cwd = getcwd (NULL, 0);
+	  if (cwd == NULL)
+	    /* We cannot get the current working directory.  Don't
+	       signal an error but simply return the default
+	       string.  */
 	    goto return_untranslated;
-
-	  stpcpy (stpcpy (strchr (resolved_dirname, '\0'), "/"), dirname);
-	  dirname = resolved_dirname;
+	  int ret = __asprintf (&xdirname, "%s/%s", cwd, dirname);
+	  free (cwd);
+	  if (ret < 0)
+	      return NULL;
+	  dirname = xdirname;
 	}
 #ifndef IN_LIBGLOCALE
     }
@@ -767,6 +751,7 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
 	    {
 	      /* Found the translation of MSGID1 in domain DOMAIN:
 		 starting at RETVAL, RETLEN bytes.  */
+	      free (xdirname);
 	      FREE_BLOCKS (block_list);
 	      if (foundp == NULL)
 		{
@@ -850,6 +835,7 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
 
  return_untranslated:
   /* Return the untranslated MSGID.  */
+  free (xdirname);
   FREE_BLOCKS (block_list);
   gl_rwlock_unlock (_nl_state_lock);
 #ifdef _LIBC