From 4ab7767e0b900cad25970c8127c38a25415421bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Basile=20Cl=C3=A9ment?= Date: Wed, 7 Jun 2023 10:02:27 +0200 Subject: [PATCH] Fix `same_file` check, reloaded In #67 the `same_file` check was changed from an (incorrect) comparison of the device number to a call to `Sys.command`. There are two issues with this change: - This means we are now creating a new process (three new processes, actually) for each file when using the `-F` option, which is not very efficient. - The current code does not use `Filename.quote_command` and hence is vulnerable to various code injection shenanigans such as when the file is called `$(echo im_in_yo_shell)` (yes that is a valid file name). This patch changes it back to the old way using `Unix.stat`, but actually checks the inode number in addition to the device number. --- src/core/Definitions.ml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/Definitions.ml b/src/core/Definitions.ml index 7ca9e2d..279f81b 100644 --- a/src/core/Definitions.ml +++ b/src/core/Definitions.ml @@ -151,11 +151,12 @@ let mk_subdir self path : Subdir.t = let path = norm_path ~dir_vars:self.dir_vars ~cur_dir:self.cur_dir path in (* helper *) let is_parent (dir : string) (f : string) : bool = + let dir_st = Unix.(stat dir) in let same_file f = try - Sys.command (Fmt.sprintf "test $(realpath %S) -ef $(realpath %S)" dir f) - = 0 - with _ -> false + let f_st = Unix.(stat f) in + dir_st.st_ino = f_st.st_ino && dir_st.st_dev = f_st.st_dev + with Unix.Unix_error _ -> false in (* check f and its parents *) let rec check f =