66
77use serde:: Serialize ;
88use std:: {
9- fs:: { self , metadata} ,
9+ fs:: { self , metadata, symlink_metadata } ,
1010 path:: { Path , PathBuf } ,
1111} ;
1212use tempfile:: { self , tempdir} ;
@@ -31,8 +31,36 @@ pub fn is_dir<P: AsRef<Path>>(path: P) -> crate::api::Result<bool> {
3131 metadata ( path) . map ( |md| md. is_dir ( ) ) . map_err ( Into :: into)
3232}
3333
34+ fn is_symlink < P : AsRef < Path > > ( path : P ) -> crate :: api:: Result < bool > {
35+ // TODO: remove the different implementation once we raise tauri's MSRV to at least 1.58
36+ #[ cfg( windows) ]
37+ let ret = symlink_metadata ( path)
38+ . map ( |md| md. is_symlink ( ) )
39+ . map_err ( Into :: into) ;
40+
41+ #[ cfg( not( windows) ) ]
42+ let ret = symlink_metadata ( path)
43+ . map ( |md| md. file_type ( ) . is_symlink ( ) )
44+ . map_err ( Into :: into) ;
45+
46+ ret
47+ }
48+
3449/// Reads a directory. Can perform recursive operations.
3550pub fn read_dir < P : AsRef < Path > > ( path : P , recursive : bool ) -> crate :: api:: Result < Vec < DiskEntry > > {
51+ read_dir_with_options ( path, recursive, ReadDirOptions { scope : None } )
52+ }
53+
54+ #[ derive( Clone , Copy ) ]
55+ pub ( crate ) struct ReadDirOptions < ' a > {
56+ pub scope : Option < & ' a crate :: FsScope > ,
57+ }
58+
59+ pub ( crate ) fn read_dir_with_options < P : AsRef < Path > > (
60+ path : P ,
61+ recursive : bool ,
62+ options : ReadDirOptions < ' _ > ,
63+ ) -> crate :: api:: Result < Vec < DiskEntry > > {
3664 let mut files_and_dirs: Vec < DiskEntry > = vec ! [ ] ;
3765 for entry in fs:: read_dir ( path) ? {
3866 let path = entry?. path ( ) ;
@@ -42,11 +70,16 @@ pub fn read_dir<P: AsRef<Path>>(path: P, recursive: bool) -> crate::api::Result<
4270 files_and_dirs. push ( DiskEntry {
4371 path : path. clone ( ) ,
4472 children : if flag {
45- Some ( if recursive {
46- read_dir ( & path_as_string, true ) ?
47- } else {
48- vec ! [ ]
49- } )
73+ Some (
74+ if recursive
75+ && ( !is_symlink ( & path_as_string) ?
76+ || options. scope . map ( |s| s. is_allowed ( & path) ) . unwrap_or ( true ) )
77+ {
78+ read_dir_with_options ( & path_as_string, true , options) ?
79+ } else {
80+ vec ! [ ]
81+ } ,
82+ )
5083 } else {
5184 None
5285 } ,
0 commit comments