mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-28 16:50:16 +01:00
core: add nm_utils_file_is_in_path() for checking paths
Add a helper function for the common check whether a file is inside a path. Also, this function handles special cases like repeated file separators. However, as it is still entirely text based, it also cannot recognize if two (literally) different paths reference the same inode/file.
This commit is contained in:
parent
9dce4a426b
commit
f90b3adc15
4 changed files with 91 additions and 0 deletions
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "platform/nm-platform.h"
|
||||
#include "nm-auth-utils.h"
|
||||
#include "systemd/nm-sd-utils.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -998,3 +999,62 @@ nm_shutdown_wait_obj_unregister (NMShutdownWaitObjHandle *handle)
|
|||
g_object_weak_unref (handle->watched_obj, _shutdown_waitobj_cb, handle);
|
||||
_shutdown_waitobj_unregister (handle);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_utils_file_is_in_path:
|
||||
* @abs_filename: the absolute filename to test
|
||||
* @abs_path: the absolute path, to check whether filename is in.
|
||||
*
|
||||
* This tests, whether @abs_filename is a file which lies inside @abs_path.
|
||||
* Basically, this checks whether @abs_filename is the same as @abs_path +
|
||||
* basename(@abs_filename). It allows simple normalizations, like coalescing
|
||||
* multiple "//".
|
||||
*
|
||||
* However, beware that this function is purely filename based. That means,
|
||||
* it will reject files that reference the same file (i.e. inode) via
|
||||
* symlinks or bind mounts. Maybe one would like to check for file (inode)
|
||||
* identity, but that is not really possible based on the file name alone.
|
||||
*
|
||||
* This means, that nm_utils_file_is_in_path("/var/run/some-file", "/var/run")
|
||||
* will succeed, but nm_utils_file_is_in_path("/run/some-file", "/var/run")
|
||||
* will not (although, it's well known that they reference the same path).
|
||||
*
|
||||
* Also, note that @abs_filename must not have trailing slashes itself.
|
||||
* So, this will reject nm_utils_file_is_in_path("/usr/lib/", "/usr") as
|
||||
* invalid, because the function searches for file names (and "lib/" is
|
||||
* clearly a directory).
|
||||
*
|
||||
* Returns: if @abs_filename is a file inside @abs_path, returns the
|
||||
* trailing part of @abs_filename which is the filename. Otherwise
|
||||
* %NULL.
|
||||
*/
|
||||
const char *
|
||||
nm_utils_file_is_in_path (const char *abs_filename,
|
||||
const char *abs_path)
|
||||
{
|
||||
const char *path;
|
||||
|
||||
g_return_val_if_fail (abs_filename && abs_filename[0] == '/', NULL);
|
||||
g_return_val_if_fail (abs_path && abs_path[0] == '/', NULL);
|
||||
|
||||
path = nm_sd_utils_path_startswith (abs_filename, abs_path);
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
nm_assert (path[0] != '/');
|
||||
nm_assert (path > abs_filename);
|
||||
nm_assert (path <= &abs_filename[strlen (abs_filename)]);
|
||||
|
||||
/* we require a non-empty remainder with no slashes. That is, only a filename.
|
||||
*
|
||||
* Note this will reject "/var/run/" as not being in "/var",
|
||||
* while "/var/run" would pass. The function searches for files
|
||||
* only, so a trailing slash (indicating a directory) is not allowed).
|
||||
* This is despite that the function cannot determine whether "/var/run"
|
||||
* is itself a file or a directory. "*/
|
||||
return path[0] && !strchr (path, '/')
|
||||
? path
|
||||
: NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,4 +86,10 @@ void nm_shutdown_wait_obj_unregister (NMShutdownWaitObjHandle *handle);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *
|
||||
nm_utils_file_is_in_path (const char *abs_filename,
|
||||
const char *abs_path);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif /* __NETWORKMANAGER_UTILS_H__ */
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@
|
|||
#include "nm-setting-wireless.h"
|
||||
#include "nm-setting-wireless-security.h"
|
||||
|
||||
#ifdef __NM_SD_UTILS_H__
|
||||
#error "nm-core-utils.c should stay independent of systemd utils. Are you looking for NetworkMangerUtils.c? "
|
||||
#endif
|
||||
|
||||
G_STATIC_ASSERT (sizeof (NMUtilsTestFlags) <= sizeof (int));
|
||||
static int _nm_utils_testing = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1845,6 +1845,25 @@ test_nm_utils_exp10 (void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_utils_file_is_in_path (void)
|
||||
{
|
||||
g_assert (!nm_utils_file_is_in_path ("/", "/"));
|
||||
g_assert (!nm_utils_file_is_in_path ("//", "/"));
|
||||
g_assert (!nm_utils_file_is_in_path ("/a/", "/"));
|
||||
g_assert ( nm_utils_file_is_in_path ("/a", "/"));
|
||||
g_assert ( nm_utils_file_is_in_path ("///a", "/"));
|
||||
g_assert ( nm_utils_file_is_in_path ("//b/a", "/b//"));
|
||||
g_assert ( nm_utils_file_is_in_path ("//b///a", "/b//"));
|
||||
g_assert (!nm_utils_file_is_in_path ("//b///a/", "/b//"));
|
||||
g_assert (!nm_utils_file_is_in_path ("//b///a/", "/b/a/"));
|
||||
g_assert (!nm_utils_file_is_in_path ("//b///a", "/b/a/"));
|
||||
g_assert ( nm_utils_file_is_in_path ("//b///a/.", "/b/a/"));
|
||||
g_assert ( nm_utils_file_is_in_path ("//b///a/..", "/b/a/"));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
||||
int
|
||||
|
|
@ -1891,6 +1910,8 @@ main (int argc, char **argv)
|
|||
g_test_add_func ("/general/stable-id/parse", test_stable_id_parse);
|
||||
g_test_add_func ("/general/stable-id/generated-complete", test_stable_id_generated_complete);
|
||||
|
||||
g_test_add_func ("/general/test_utils_file_is_in_path", test_utils_file_is_in_path);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue