mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-08 18:36:17 +01:00
Merge branch 'ossfuzz-41563-canonical-triple-slash-dot-dot' into 'main'
gfileutils: Correctly reset start value when canonicalising paths See merge request GNOME/glib!2382
This commit is contained in:
commit
9538e05387
@ -2736,7 +2736,7 @@ gchar *
|
||||
g_canonicalize_filename (const gchar *filename,
|
||||
const gchar *relative_to)
|
||||
{
|
||||
gchar *canon, *input, *output, *start;
|
||||
gchar *canon, *input, *output, *after_root, *output_start;
|
||||
|
||||
g_return_val_if_fail (relative_to == NULL || g_path_is_absolute (relative_to), NULL);
|
||||
|
||||
@ -2758,9 +2758,9 @@ g_canonicalize_filename (const gchar *filename,
|
||||
canon = g_strdup (filename);
|
||||
}
|
||||
|
||||
start = (char *)g_path_skip_root (canon);
|
||||
after_root = (char *)g_path_skip_root (canon);
|
||||
|
||||
if (start == NULL)
|
||||
if (after_root == NULL)
|
||||
{
|
||||
/* This shouldn't really happen, as g_get_current_dir() should
|
||||
return an absolute pathname, but bug 573843 shows this is
|
||||
@ -2770,21 +2770,24 @@ g_canonicalize_filename (const gchar *filename,
|
||||
}
|
||||
|
||||
/* Find the first dir separator and use the canonical dir separator. */
|
||||
for (output = start - 1;
|
||||
for (output = after_root - 1;
|
||||
(output >= canon) && G_IS_DIR_SEPARATOR (*output);
|
||||
output--)
|
||||
*output = G_DIR_SEPARATOR;
|
||||
|
||||
/* 1 to re-increment after the final decrement above (so that output >= canon),
|
||||
* and 1 to skip the first `/` */
|
||||
output += 2;
|
||||
|
||||
/* POSIX allows double slashes at the start to mean something special
|
||||
* (as does windows too). So, "//" != "/", but more than two slashes
|
||||
* is treated as "/".
|
||||
*/
|
||||
if (start - output == 1)
|
||||
if (after_root - output == 1)
|
||||
output++;
|
||||
|
||||
input = start;
|
||||
input = after_root;
|
||||
output_start = output;
|
||||
while (*input)
|
||||
{
|
||||
/* input points to the next non-separator to be processed. */
|
||||
@ -2809,13 +2812,13 @@ g_canonicalize_filename (const gchar *filename,
|
||||
else if (input[0] == '.' && input[1] == '.' &&
|
||||
(input[2] == 0 || G_IS_DIR_SEPARATOR (input[2])))
|
||||
{
|
||||
if (output > start)
|
||||
if (output > output_start)
|
||||
{
|
||||
do
|
||||
{
|
||||
output--;
|
||||
}
|
||||
while (!G_IS_DIR_SEPARATOR (output[-1]) && output > start);
|
||||
while (!G_IS_DIR_SEPARATOR (output[-1]) && output > output_start);
|
||||
}
|
||||
if (input[2] == 0)
|
||||
break;
|
||||
@ -2835,7 +2838,7 @@ g_canonicalize_filename (const gchar *filename,
|
||||
}
|
||||
|
||||
/* Remove a potentially trailing dir separator */
|
||||
if (output > start && G_IS_DIR_SEPARATOR (output[-1]))
|
||||
if (output > output_start && G_IS_DIR_SEPARATOR (output[-1]))
|
||||
output--;
|
||||
|
||||
*output = '\0';
|
||||
|
@ -1063,6 +1063,7 @@ test_paths (void)
|
||||
{ "/", "./", "/" },
|
||||
{ "/", "/.", "/" },
|
||||
{ "/", "/./", "/" },
|
||||
{ "/", "///usr/../usr", "/usr" },
|
||||
#else
|
||||
{ "/etc", "../usr/share", "\\usr\\share" },
|
||||
{ "/", "/foo/bar", "\\foo\\bar" },
|
||||
@ -1090,6 +1091,7 @@ test_paths (void)
|
||||
{ "/", "./", "/" },
|
||||
{ "/", "/.", "/" },
|
||||
{ "/", "/./", "/" },
|
||||
{ "/", "///usr/../usr", "/usr" },
|
||||
|
||||
{ "\\etc", "..\\usr\\share", "\\usr\\share" },
|
||||
{ "\\", "\\foo\\bar", "\\foo\\bar" },
|
||||
@ -1117,6 +1119,7 @@ test_paths (void)
|
||||
{ "\\", ".\\", "\\" },
|
||||
{ "\\", "\\.", "\\" },
|
||||
{ "\\", "\\.\\", "\\" },
|
||||
{ "\\", "\\\\\\usr\\..\\usr", "\\usr" },
|
||||
#endif
|
||||
};
|
||||
const guint n_canonicalize_filename_checks = G_N_ELEMENTS (canonicalize_filename_checks);
|
||||
|
Loading…
Reference in New Issue
Block a user