mirror of
https://git.savannah.gnu.org/git/gnulib.git
synced 2025-08-17 12:41:05 +03:00
getcwd: break fdopendir + save_cwd recursive loop (Bug#13516)
Reported for OS X 10.8.2 by Assaf Gordon in <http://bugs.gnu.org/13516>. * lib/getcwd.c (HAVE_OPENAT_SUPPORT): Do not define if !HAVE_OPENAT && !HAVE_FDOPENDIR. * m4/getcwd-abort-bug.m4: Reformat to match test-getcwd.c so that they can be kept in sync more easily. Avoid PATH_MAX test on the Hurd. Sync from test-getcwd.c for errno tests after mkdir or chdir failure. * tests/test-getcwd.c (HAVE_OPENAT_SUPPORT): New macro, from lib/getcwd.c. (test_abort_bug): Do not test for the deep directory bug unless we have openat support. Avoid PATH_MAX test on the Hurd.
This commit is contained in:
14
ChangeLog
14
ChangeLog
@@ -1,5 +1,19 @@
|
||||
2013-02-03 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
getcwd: break fdopendir + save_cwd recursive loop (Bug#13516)
|
||||
Reported for OS X 10.8.2 by Assaf Gordon in
|
||||
<http://bugs.gnu.org/13516>.
|
||||
* lib/getcwd.c (HAVE_OPENAT_SUPPORT): Do not define if
|
||||
!HAVE_OPENAT && !HAVE_FDOPENDIR.
|
||||
* m4/getcwd-abort-bug.m4: Reformat to match test-getcwd.c
|
||||
so that they can be kept in sync more easily. Avoid PATH_MAX
|
||||
test on the Hurd. Sync from test-getcwd.c for errno tests after
|
||||
mkdir or chdir failure.
|
||||
* tests/test-getcwd.c (HAVE_OPENAT_SUPPORT): New macro, from
|
||||
lib/getcwd.c.
|
||||
(test_abort_bug): Do not test for the deep directory bug unless we
|
||||
have openat support. Avoid PATH_MAX test on the Hurd.
|
||||
|
||||
regex-tests, regex: fix bug: memset undeclared
|
||||
* tests/test-regex.c: Don't include regex.h twice. Include
|
||||
string.h, to declare memset. Christensen's report also mentioned
|
||||
|
@@ -28,9 +28,9 @@
|
||||
#include <fcntl.h> /* For AT_FDCWD on Solaris 9. */
|
||||
|
||||
/* If this host provides the openat function or if we're using the
|
||||
gnulib replacement function, then enable code below to make getcwd
|
||||
more efficient and robust. */
|
||||
#if defined HAVE_OPENAT || defined GNULIB_OPENAT
|
||||
gnulib replacement function with a native fdopendir, then enable
|
||||
code below to make getcwd more efficient and robust. */
|
||||
#if defined HAVE_OPENAT || (defined GNULIB_OPENAT && defined HAVE_FDOPENDIR)
|
||||
# define HAVE_OPENAT_SUPPORT 1
|
||||
#else
|
||||
# define HAVE_OPENAT_SUPPORT 0
|
||||
|
@@ -58,16 +58,18 @@ AC_DEFUN([gl_FUNC_GETCWD_ABORT_BUG],
|
||||
int
|
||||
main ()
|
||||
{
|
||||
char const *dir_name = "confdir-14B---";
|
||||
char *cwd;
|
||||
size_t initial_cwd_len;
|
||||
int fail = 0;
|
||||
size_t desired_depth;
|
||||
size_t d;
|
||||
|
||||
/* The bug is triggered when PATH_MAX < getpagesize (), so skip
|
||||
this relatively expensive and invasive test if that's not true. */
|
||||
if (getpagesize () <= PATH_MAX)
|
||||
#ifdef PATH_MAX
|
||||
int bug_possible = PATH_MAX < getpagesize ();
|
||||
#else
|
||||
int bug_possible = 0;
|
||||
#endif
|
||||
if (! bug_possible)
|
||||
return 0;
|
||||
|
||||
cwd = getcwd (NULL, 0);
|
||||
@@ -76,35 +78,43 @@ main ()
|
||||
|
||||
initial_cwd_len = strlen (cwd);
|
||||
free (cwd);
|
||||
desired_depth = ((TARGET_LEN - 1 - initial_cwd_len)
|
||||
/ (1 + strlen (dir_name)));
|
||||
for (d = 0; d < desired_depth; d++)
|
||||
{
|
||||
if (mkdir (dir_name, S_IRWXU) < 0 || chdir (dir_name) < 0)
|
||||
{
|
||||
fail = 3; /* Unable to construct deep hierarchy. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If libc has the bug in question, this invocation of getcwd
|
||||
results in a failed assertion. */
|
||||
cwd = getcwd (NULL, 0);
|
||||
if (cwd == NULL)
|
||||
fail = 4; /* getcwd failed: it refuses to return a string longer
|
||||
than PATH_MAX. */
|
||||
free (cwd);
|
||||
|
||||
/* Call rmdir first, in case the above chdir failed. */
|
||||
rmdir (dir_name);
|
||||
while (0 < d--)
|
||||
if (1)
|
||||
{
|
||||
if (chdir ("..") < 0)
|
||||
static char const dir_name[] = "confdir-14B---";
|
||||
size_t desired_depth = ((TARGET_LEN - 1 - initial_cwd_len)
|
||||
/ sizeof dir_name);
|
||||
size_t d;
|
||||
for (d = 0; d < desired_depth; d++)
|
||||
{
|
||||
fail = 5;
|
||||
break;
|
||||
if (mkdir (dir_name, S_IRWXU) < 0 || chdir (dir_name) < 0)
|
||||
{
|
||||
if (! (errno == ERANGE || errno == ENAMETOOLONG
|
||||
|| errno == ENOENT))
|
||||
fail = 3; /* Unable to construct deep hierarchy. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If libc has the bug in question, this invocation of getcwd
|
||||
results in a failed assertion. */
|
||||
cwd = getcwd (NULL, 0);
|
||||
if (cwd == NULL)
|
||||
fail = 4; /* getcwd didn't assert, but it failed for a long name
|
||||
where the answer could have been learned. */
|
||||
free (cwd);
|
||||
|
||||
/* Call rmdir first, in case the above chdir failed. */
|
||||
rmdir (dir_name);
|
||||
while (0 < d--)
|
||||
{
|
||||
if (chdir ("..") < 0)
|
||||
{
|
||||
fail = 5;
|
||||
break;
|
||||
}
|
||||
rmdir (dir_name);
|
||||
}
|
||||
}
|
||||
|
||||
return fail;
|
||||
|
@@ -38,23 +38,29 @@
|
||||
trigger a bug in glibc's getcwd implementation before 2.4.90-10. */
|
||||
#define TARGET_LEN (5 * 1024)
|
||||
|
||||
#if defined HAVE_OPENAT || (defined GNULIB_OPENAT && defined HAVE_FDOPENDIR)
|
||||
# define HAVE_OPENAT_SUPPORT 1
|
||||
#else
|
||||
# define HAVE_OPENAT_SUPPORT 0
|
||||
#endif
|
||||
|
||||
/* Keep this test in sync with m4/getcwd-abort-bug.m4. */
|
||||
static int
|
||||
test_abort_bug (void)
|
||||
{
|
||||
char const *dir_name = "confdir-14B---";
|
||||
char *cwd;
|
||||
size_t initial_cwd_len;
|
||||
int fail = 0;
|
||||
size_t desired_depth;
|
||||
size_t d;
|
||||
|
||||
#ifdef PATH_MAX
|
||||
/* The bug is triggered when PATH_MAX < getpagesize (), so skip
|
||||
this relatively expensive and invasive test if that's not true. */
|
||||
if (getpagesize () <= PATH_MAX)
|
||||
return 0;
|
||||
#ifdef PATH_MAX
|
||||
int bug_possible = PATH_MAX < getpagesize ();
|
||||
#else
|
||||
int bug_possible = 0;
|
||||
#endif
|
||||
if (! bug_possible)
|
||||
return 0;
|
||||
|
||||
cwd = getcwd (NULL, 0);
|
||||
if (cwd == NULL)
|
||||
@@ -62,36 +68,43 @@ test_abort_bug (void)
|
||||
|
||||
initial_cwd_len = strlen (cwd);
|
||||
free (cwd);
|
||||
desired_depth = ((TARGET_LEN - 1 - initial_cwd_len)
|
||||
/ (1 + strlen (dir_name)));
|
||||
for (d = 0; d < desired_depth; d++)
|
||||
{
|
||||
if (mkdir (dir_name, S_IRWXU) < 0 || chdir (dir_name) < 0)
|
||||
{
|
||||
if (! (errno == ERANGE || errno == ENAMETOOLONG || errno == ENOENT))
|
||||
fail = 3; /* Unable to construct deep hierarchy. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If libc has the bug in question, this invocation of getcwd
|
||||
results in a failed assertion. */
|
||||
cwd = getcwd (NULL, 0);
|
||||
if (cwd == NULL)
|
||||
fail = 4; /* getcwd didn't assert, but it failed for a long name
|
||||
where the answer could have been learned. */
|
||||
free (cwd);
|
||||
|
||||
/* Call rmdir first, in case the above chdir failed. */
|
||||
rmdir (dir_name);
|
||||
while (0 < d--)
|
||||
if (HAVE_OPENAT_SUPPORT)
|
||||
{
|
||||
if (chdir ("..") < 0)
|
||||
static char const dir_name[] = "confdir-14B---";
|
||||
size_t desired_depth = ((TARGET_LEN - 1 - initial_cwd_len)
|
||||
/ sizeof dir_name);
|
||||
size_t d;
|
||||
for (d = 0; d < desired_depth; d++)
|
||||
{
|
||||
fail = 5;
|
||||
break;
|
||||
if (mkdir (dir_name, S_IRWXU) < 0 || chdir (dir_name) < 0)
|
||||
{
|
||||
if (! (errno == ERANGE || errno == ENAMETOOLONG
|
||||
|| errno == ENOENT))
|
||||
fail = 3; /* Unable to construct deep hierarchy. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If libc has the bug in question, this invocation of getcwd
|
||||
results in a failed assertion. */
|
||||
cwd = getcwd (NULL, 0);
|
||||
if (cwd == NULL)
|
||||
fail = 4; /* getcwd didn't assert, but it failed for a long name
|
||||
where the answer could have been learned. */
|
||||
free (cwd);
|
||||
|
||||
/* Call rmdir first, in case the above chdir failed. */
|
||||
rmdir (dir_name);
|
||||
while (0 < d--)
|
||||
{
|
||||
if (chdir ("..") < 0)
|
||||
{
|
||||
fail = 5;
|
||||
break;
|
||||
}
|
||||
rmdir (dir_name);
|
||||
}
|
||||
}
|
||||
|
||||
return fail;
|
||||
|
Reference in New Issue
Block a user