mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-02 07:23:41 +02:00
fileutils: Add g_canonicalize_filename
Getting the canonical filename is a relatively common operation when dealing with symbolic links. This commit exposes GLocalFile's implementation of a filename canonicalizer function, with a few additions to make it more useful for consumers of it. Instead of always assuming g_get_current_dir(), the exposed function allows passing it as an additional parameter. This will be used to fix the GTimeZone code to retrieve the local timezone from a zoneinfo symlink. (Tweaked by Philip Withnall <withnall@endlessm.com> to drop g_autofree usage and add some additional tests.) https://bugzilla.gnome.org/show_bug.cgi?id=111848
This commit is contained in:
committed by
Philip Withnall
parent
a67dc37e9c
commit
b9b642de06
@@ -838,6 +838,43 @@ test_paths (void)
|
||||
{ "", NULL },
|
||||
};
|
||||
const guint n_skip_root_checks = G_N_ELEMENTS (skip_root_checks);
|
||||
struct {
|
||||
gchar *cwd;
|
||||
gchar *relative_path;
|
||||
gchar *canonical_path;
|
||||
} canonicalize_filename_checks[] = {
|
||||
{ "/etc", "../usr/share", "/usr/share" },
|
||||
{ "/", "/foo/bar", "/foo/bar" },
|
||||
{ "/usr/bin", "../../foo/bar", "/foo/bar" },
|
||||
{ "/", "../../foo/bar", "/foo/bar" },
|
||||
{ "/double//dash", "../../foo/bar", "/foo/bar" },
|
||||
{ "/usr/share/foo", ".././././bar", "/usr/share/bar" },
|
||||
{ "/foo/bar", "../bar/./.././bar", "/foo/bar" },
|
||||
{ "/test///dir", "../../././foo/bar", "/foo/bar" },
|
||||
{ "/test///dir", "../../././/foo///bar", "/foo/bar" },
|
||||
{ "/etc", "///triple/slash", "/triple/slash" },
|
||||
{ "/etc", "//double/slash", "//double/slash" },
|
||||
{ "///triple/slash", ".", "/triple/slash" },
|
||||
{ "//double/slash", ".", "//double/slash" },
|
||||
{ "/cwd/../with/./complexities/", "./hello", "/with/complexities/hello" },
|
||||
#ifdef G_OS_WIN32
|
||||
{ "\\etc", "..\\usr\\share", "\\usr\\share" },
|
||||
{ "\\", "\\foo\\bar", "\\foo\\bar" },
|
||||
{ "\\usr\\bin", "..\\..\\foo\\bar", "\\foo\\bar" },
|
||||
{ "\\", "..\\..\\foo\\bar", "\\foo\\bar" },
|
||||
{ "\\double\\\\dash", "..\\..\\foo\\bar", "\\foo\\bar" },
|
||||
{ "\\usr\\share\\foo", "..\\.\\.\\.\\bar", "\\usr\\share\\bar" },
|
||||
{ "\\foo\\bar", "..\\bar\\.\\..\\.\\bar", "\\foo\\bar" },
|
||||
{ "\\test\\\\\\dir", "..\\..\\.\\.\\foo\\bar", "\\foo\\bar" },
|
||||
{ "\\test\\\\\\dir", "..\\..\\.\\.\\\\foo\\\\\\bar", "\\foo\\bar" },
|
||||
{ "\\etc", "\\\\\\triple\\slash", "\\triple\\slash" },
|
||||
{ "\\etc", "\\\\double\\slash", "\\\\double\\slash" },
|
||||
{ "\\\\\\triple\\slash", ".", "\\triple\\slash" },
|
||||
{ "\\\\double\\slash", ".", "\\\\double\\slash" },
|
||||
{ "\\cwd\\..\\with\\.\\complexities\\", ".\\hello", "\\cwd\\with\\complexities\\hello" },
|
||||
#endif
|
||||
};
|
||||
const guint n_canonicalize_filename_checks = G_N_ELEMENTS (canonicalize_filename_checks);
|
||||
gchar *string;
|
||||
guint i;
|
||||
if (g_test_verbose())
|
||||
@@ -896,6 +933,43 @@ test_paths (void)
|
||||
}
|
||||
if (g_test_verbose())
|
||||
g_printerr ("ok\n");
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_printerr ("checking g_canonicalize_filename()...");
|
||||
for (i = 0; i < n_canonicalize_filename_checks; i++)
|
||||
{
|
||||
gchar *canonical_path = g_canonicalize_filename (canonicalize_filename_checks[i].relative_path,
|
||||
canonicalize_filename_checks[i].cwd);
|
||||
if (g_strcmp0 (canonical_path, canonicalize_filename_checks[i].canonical_path) != 0)
|
||||
{
|
||||
g_error ("\nfailed for \"%s\"==\"%s\" (returned: \"%s\")\n",
|
||||
canonicalize_filename_checks[i].relative_path,
|
||||
canonicalize_filename_checks[i].canonical_path,
|
||||
canonical_path);
|
||||
}
|
||||
g_free (canonical_path);
|
||||
}
|
||||
if (g_test_verbose ())
|
||||
g_printerr ("ok\n");
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_printerr ("checking g_canonicalize_filename() supports NULL...");
|
||||
|
||||
{
|
||||
const gchar *relative_path = "./";
|
||||
gchar *canonical_path = g_canonicalize_filename (relative_path, NULL);
|
||||
gchar *cwd = g_get_current_dir ();
|
||||
if (g_strcmp0 (canonical_path, cwd) != 0)
|
||||
{
|
||||
g_error ("\nfailed for \"%s\"==\"%s\" (returned: \"%s\")\n",
|
||||
relative_path, cwd, canonical_path);
|
||||
}
|
||||
g_free (cwd);
|
||||
g_free (canonical_path);
|
||||
}
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_printerr ("ok\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
Reference in New Issue
Block a user