From b67dcfce4b8d5daf32340616b8bc1b106323c14a Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 17 Jan 2021 17:22:25 +0100 Subject: [PATCH] canonicalize[-lgpl] tests: Add more tests. * tests/test-canonicalize.c (main): Add detailed tests for // handling. * tests/test-canonicalize-lgpl.c (main): Likewise. --- ChangeLog | 6 +++++ tests/test-canonicalize-lgpl.c | 44 ++++++++++++++++++++++++++++++- tests/test-canonicalize.c | 47 +++++++++++++++++++++++++++++++++- 3 files changed, 95 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3c4a5133be..dad3119bfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2021-01-17 Bruno Haible + + canonicalize[-lgpl] tests: Add more tests. + * tests/test-canonicalize.c (main): Add detailed tests for // handling. + * tests/test-canonicalize-lgpl.c (main): Likewise. + 2021-01-17 Bruno Haible argp tests: Avoid test failures on Alpine Linux. diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c index d86f7262a6..c0a5a55150 100644 --- a/tests/test-canonicalize-lgpl.c +++ b/tests/test-canonicalize-lgpl.c @@ -67,6 +67,48 @@ main (void) ASSERT (close (fd) == 0); } + /* Check // handling (the easy cases, without symlinks). + This // handling is not mandated by POSIX. However, many applications + expect that canonicalize_file_name "canonicalizes" the file name, + that is, that different results of canonicalize_file_name correspond + to different files (except for hard links). */ + { + char *result0 = canonicalize_file_name ("/etc/passwd"); + if (result0 != NULL) /* This file does not exist on native Windows. */ + { + char *result; + + result = canonicalize_file_name ("/etc//passwd"); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + result = canonicalize_file_name ("/etc///passwd"); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + /* On Windows, the syntax //host/share/filename denotes a file + in a directory named 'share', exported from host 'host'. + See also m4/double-slash-root.m4. */ +#if !(defined _WIN32 || defined __CYGWIN__) + result = canonicalize_file_name ("//etc/passwd"); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + result = canonicalize_file_name ("//etc//passwd"); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + result = canonicalize_file_name ("//etc///passwd"); + ASSERT (result != NULL && strcmp (result, result0) == 0); +#endif + + result = canonicalize_file_name ("///etc/passwd"); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + result = canonicalize_file_name ("///etc//passwd"); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + result = canonicalize_file_name ("///etc///passwd"); + ASSERT (result != NULL && strcmp (result, result0) == 0); + } + } + /* Check for ., .., intermediate // handling, and for error cases. */ { char *result = canonicalize_file_name (BASE "//./..//" BASE "/tra"); @@ -209,7 +251,7 @@ main (void) ASSERT (errno == ELOOP); } - /* Check that leading // is honored correctly. */ + /* Check that leading // within symlinks is honored correctly. */ { struct stat st1; struct stat st2; diff --git a/tests/test-canonicalize.c b/tests/test-canonicalize.c index e85ca4557d..dbde6f2e98 100644 --- a/tests/test-canonicalize.c +++ b/tests/test-canonicalize.c @@ -58,6 +58,51 @@ main (void) ASSERT (close (fd) == 0); } + /* Check // handling (the easy cases, without symlinks). + This // handling is not mandated by POSIX. However, many applications + expect that canonicalize_filename_mode "canonicalizes" the file name, + that is, that different results of canonicalize_filename_mode correspond + to different files (except for hard links). */ + { + char *result0 = canonicalize_file_name ("/etc/passwd"); + if (result0 != NULL) /* This file does not exist on native Windows. */ + { + char *result; + + result = canonicalize_filename_mode ("/etc/passwd", CAN_MISSING); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + result = canonicalize_filename_mode ("/etc//passwd", CAN_MISSING); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + result = canonicalize_filename_mode ("/etc///passwd", CAN_MISSING); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + /* On Windows, the syntax //host/share/filename denotes a file + in a directory named 'share', exported from host 'host'. + See also m4/double-slash-root.m4. */ +#if !(defined _WIN32 || defined __CYGWIN__) + result = canonicalize_filename_mode ("//etc/passwd", CAN_MISSING); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + result = canonicalize_filename_mode ("//etc//passwd", CAN_MISSING); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + result = canonicalize_filename_mode ("//etc///passwd", CAN_MISSING); + ASSERT (result != NULL && strcmp (result, result0) == 0); +#endif + + result = canonicalize_filename_mode ("///etc/passwd", CAN_MISSING); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + result = canonicalize_filename_mode ("///etc//passwd", CAN_MISSING); + ASSERT (result != NULL && strcmp (result, result0) == 0); + + result = canonicalize_filename_mode ("///etc///passwd", CAN_MISSING); + ASSERT (result != NULL && strcmp (result, result0) == 0); + } + } + /* Check for ., .., intermediate // handling, and for error cases. */ { char *result1 = canonicalize_file_name (BASE "//./..//" BASE "/tra"); @@ -334,7 +379,7 @@ main (void) free (result2); } - /* Check that leading // is honored correctly. */ + /* Check that leading // within symlinks is honored correctly. */ { struct stat st1; struct stat st2; -- 2.39.5