When DOUBLE_SLASH_IS_DISTINCT_ROOT is non-zero, then we were
reading the contents of rpath[1] even when we had never written
anything there, which meant that "///" would usually canonicalize
to "/" but sometimes to "//" if a '/' was leftover in the heap.
This condition could also occur via 'ln -s / //some/path' and
canonicalizing //some/path, where we rewind rpath but do not
clear out the previous round. Platforms where "//" and "/" are
equivalent do not suffer from this read-beyond-written bounds.
* lib/canonicalize-lgpl.c (__realpath): Avoid possibility of
random '/' left in dest.
* lib/canonicalize.c (canonicalize_filename_mode): Likewise.
Signed-off-by: Eric Blake <eblake@redhat.com>
+2012-02-04 Eric Blake <eblake@redhat.com>
+
+ canonicalize: avoid uninitialized memory use
+ * lib/canonicalize-lgpl.c (__realpath): Avoid possibility of
+ random '/' left in dest.
+ * lib/canonicalize.c (canonicalize_filename_mode): Likewise.
+
2012-02-04 Bruno Haible <bruno@clisp.org>
isatty: Fix test failure of ptsname_r on native Windows.
{
rpath[0] = '/';
dest = rpath + 1;
- if (DOUBLE_SLASH_IS_DISTINCT_ROOT && name[1] == '/' && name[2] != '/')
- *dest++ = '/';
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
+ {
+ if (name[1] == '/' && name[2] != '/')
+ *dest++ = '/';
+ *dest = '\0';
+ }
}
for (start = end = name; *start; start = end)
if (buf[0] == '/')
{
dest = rpath + 1; /* It's an absolute symlink */
- if (DOUBLE_SLASH_IS_DISTINCT_ROOT
- && buf[1] == '/' && buf[2] != '/')
- *dest++ = '/';
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
+ {
+ if (buf[1] == '/' && buf[2] != '/')
+ *dest++ = '/';
+ *dest = '\0';
+ }
}
else
{
rname_limit = rname + PATH_MAX;
rname[0] = '/';
dest = rname + 1;
- if (DOUBLE_SLASH_IS_DISTINCT_ROOT && name[1] == '/' && name[2] != '/')
- *dest++ = '/';
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
+ {
+ if (name[1] == '/' && name[2] != '/')
+ *dest++ = '/';
+ *dest = '\0';
+ }
}
for (start = name; *start; start = end)
if (buf[0] == '/')
{
dest = rname + 1; /* It's an absolute symlink */
- if (DOUBLE_SLASH_IS_DISTINCT_ROOT
- && buf[1] == '/' && buf[2] != '/')
- *dest++ = '/';
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
+ {
+ if (buf[1] == '/' && buf[2] != '/')
+ *dest++ = '/';
+ *dest = '\0';
+ }
}
else
{