@@ -5,6 +5,8 @@ use std::path::PathBuf;
5
5
use std:: rc:: Rc ;
6
6
use std:: sync:: Arc ;
7
7
8
+ use anyhow:: anyhow;
9
+ use base_rt:: RuntimeState ;
8
10
use deno_fs:: AccessCheckCb ;
9
11
use deno_fs:: FsDirEntry ;
10
12
use deno_fs:: FsFileType ;
@@ -21,6 +23,8 @@ pub struct PrefixFs<FileSystem> {
21
23
tmp_dir : Option < PathBuf > ,
22
24
fs : Arc < FileSystem > ,
23
25
base_fs : Option < Arc < dyn deno_fs:: FileSystem > > ,
26
+ runtime_state : Option < Arc < RuntimeState > > ,
27
+ check_sync_api : bool ,
24
28
}
25
29
26
30
impl < FileSystem > PrefixFs < FileSystem >
41
45
tmp_dir : None ,
42
46
fs : Arc :: new ( fs) ,
43
47
base_fs,
48
+ runtime_state : None ,
49
+ check_sync_api : false ,
44
50
}
45
51
}
46
52
75
81
self . tmp_dir = Some ( v. as_ref ( ) . to_path_buf ( ) ) ;
76
82
self
77
83
}
84
+
85
+ pub fn set_runtime_state ( & mut self , v : & Arc < RuntimeState > ) -> & mut Self {
86
+ self . runtime_state = Some ( v. clone ( ) ) ;
87
+ self
88
+ }
89
+
90
+ pub fn set_check_sync_api ( & mut self , v : bool ) -> & mut Self {
91
+ self . check_sync_api = v;
92
+ self
93
+ }
78
94
}
79
95
80
96
impl < FileSystem > PrefixFs < FileSystem >
95
111
fs : Arc :: new ( fs) ,
96
112
cwd : self . cwd . take ( ) ,
97
113
tmp_dir : self . tmp_dir . take ( ) ,
114
+ runtime_state : self . runtime_state . clone ( ) ,
115
+ check_sync_api : self . check_sync_api ,
98
116
base_fs : Some ( Arc :: new ( self ) ) ,
99
117
}
100
118
}
@@ -149,6 +167,7 @@ where
149
167
options : OpenOptions ,
150
168
access_check : Option < AccessCheckCb > ,
151
169
) -> FsResult < Rc < dyn File > > {
170
+ self . check_sync_api_allowed ( "open_sync" ) ?;
152
171
if path. starts_with ( & self . prefix ) {
153
172
self . fs . open_sync (
154
173
path. strip_prefix ( & self . prefix ) . unwrap ( ) ,
@@ -194,6 +213,7 @@ where
194
213
recursive : bool ,
195
214
mode : Option < u32 > ,
196
215
) -> FsResult < ( ) > {
216
+ self . check_sync_api_allowed ( "mkdir_sync" ) ?;
197
217
if path. starts_with ( & self . prefix ) {
198
218
self . fs . mkdir_sync (
199
219
path. strip_prefix ( & self . prefix ) . unwrap ( ) ,
@@ -232,6 +252,7 @@ where
232
252
}
233
253
234
254
fn chmod_sync ( & self , path : & Path , mode : u32 ) -> FsResult < ( ) > {
255
+ self . check_sync_api_allowed ( "chmod_sync" ) ?;
235
256
if path. starts_with ( & self . prefix ) {
236
257
self
237
258
. fs
@@ -264,6 +285,7 @@ where
264
285
uid : Option < u32 > ,
265
286
gid : Option < u32 > ,
266
287
) -> FsResult < ( ) > {
288
+ self . check_sync_api_allowed ( "chown_sync" ) ?;
267
289
if path. starts_with ( & self . prefix ) {
268
290
self
269
291
. fs
@@ -305,6 +327,7 @@ where
305
327
uid : Option < u32 > ,
306
328
gid : Option < u32 > ,
307
329
) -> FsResult < ( ) > {
330
+ self . check_sync_api_allowed ( "lchown_sync" ) ?;
308
331
if path. starts_with ( & self . prefix ) {
309
332
self
310
333
. fs
@@ -341,6 +364,7 @@ where
341
364
}
342
365
343
366
fn remove_sync ( & self , path : & Path , recursive : bool ) -> FsResult < ( ) > {
367
+ self . check_sync_api_allowed ( "remove_sync" ) ?;
344
368
if path. starts_with ( & self . prefix ) {
345
369
self
346
370
. fs
@@ -371,6 +395,8 @@ where
371
395
}
372
396
373
397
fn copy_file_sync ( & self , oldpath : & Path , newpath : & Path ) -> FsResult < ( ) > {
398
+ self . check_sync_api_allowed ( "copy_file_sync" ) ?;
399
+
374
400
let oldpath_matches = oldpath. starts_with ( & self . prefix ) ;
375
401
let newpath_matches = newpath. starts_with ( & self . prefix ) ;
376
402
if oldpath_matches || newpath_matches {
@@ -426,6 +452,8 @@ where
426
452
}
427
453
428
454
fn cp_sync ( & self , path : & Path , new_path : & Path ) -> FsResult < ( ) > {
455
+ self . check_sync_api_allowed ( "cp_sync" ) ?;
456
+
429
457
let path_matches = path. starts_with ( & self . prefix ) ;
430
458
let new_path_matches = new_path. starts_with ( & self . prefix ) ;
431
459
if path_matches || new_path_matches {
@@ -477,6 +505,7 @@ where
477
505
}
478
506
479
507
fn stat_sync ( & self , path : & Path ) -> FsResult < FsStat > {
508
+ self . check_sync_api_allowed ( "stat_sync" ) ?;
480
509
if path. starts_with ( & self . prefix ) {
481
510
self . fs . stat_sync ( path. strip_prefix ( & self . prefix ) . unwrap ( ) )
482
511
} else {
@@ -502,6 +531,7 @@ where
502
531
}
503
532
504
533
fn lstat_sync ( & self , path : & Path ) -> FsResult < FsStat > {
534
+ self . check_sync_api_allowed ( "lstat_sync" ) ?;
505
535
if path. starts_with ( & self . prefix ) {
506
536
self . fs . lstat_sync ( path. strip_prefix ( & self . prefix ) . unwrap ( ) )
507
537
} else {
@@ -527,6 +557,7 @@ where
527
557
}
528
558
529
559
fn realpath_sync ( & self , path : & Path ) -> FsResult < PathBuf > {
560
+ self . check_sync_api_allowed ( "realpath_sync" ) ?;
530
561
if path. starts_with ( & self . prefix ) {
531
562
self
532
563
. fs
@@ -554,6 +585,7 @@ where
554
585
}
555
586
556
587
fn read_dir_sync ( & self , path : & Path ) -> FsResult < Vec < FsDirEntry > > {
588
+ self . check_sync_api_allowed ( "read_dir_sync" ) ?;
557
589
if path. starts_with ( & self . prefix ) {
558
590
self
559
591
. fs
@@ -581,6 +613,8 @@ where
581
613
}
582
614
583
615
fn rename_sync ( & self , oldpath : & Path , newpath : & Path ) -> FsResult < ( ) > {
616
+ self . check_sync_api_allowed ( "rename_sync" ) ?;
617
+
584
618
let oldpath_matches = oldpath. starts_with ( & self . prefix ) ;
585
619
let newpath_matches = newpath. starts_with ( & self . prefix ) ;
586
620
if oldpath_matches || newpath_matches {
@@ -636,6 +670,8 @@ where
636
670
}
637
671
638
672
fn link_sync ( & self , oldpath : & Path , newpath : & Path ) -> FsResult < ( ) > {
673
+ self . check_sync_api_allowed ( "link_sync" ) ?;
674
+
639
675
let oldpath_matches = oldpath. starts_with ( & self . prefix ) ;
640
676
let newpath_matches = newpath. starts_with ( & self . prefix ) ;
641
677
if oldpath_matches || newpath_matches {
@@ -696,6 +732,8 @@ where
696
732
newpath : & Path ,
697
733
file_type : Option < FsFileType > ,
698
734
) -> FsResult < ( ) > {
735
+ self . check_sync_api_allowed ( "symlink_sync" ) ?;
736
+
699
737
let oldpath_matches = oldpath. starts_with ( & self . prefix ) ;
700
738
let newpath_matches = newpath. starts_with ( & self . prefix ) ;
701
739
if oldpath_matches || newpath_matches {
@@ -754,6 +792,7 @@ where
754
792
}
755
793
756
794
fn read_link_sync ( & self , path : & Path ) -> FsResult < PathBuf > {
795
+ self . check_sync_api_allowed ( "read_link_sync" ) ?;
757
796
if path. starts_with ( & self . prefix ) {
758
797
self
759
798
. fs
@@ -781,6 +820,7 @@ where
781
820
}
782
821
783
822
fn truncate_sync ( & self , path : & Path , len : u64 ) -> FsResult < ( ) > {
823
+ self . check_sync_api_allowed ( "truncate_sync" ) ?;
784
824
if path. starts_with ( & self . prefix ) {
785
825
self
786
826
. fs
@@ -818,6 +858,7 @@ where
818
858
mtime_secs : i64 ,
819
859
mtime_nanos : u32 ,
820
860
) -> FsResult < ( ) > {
861
+ self . check_sync_api_allowed ( "utime_sync" ) ?;
821
862
if path. starts_with ( & self . prefix ) {
822
863
self . fs . utime_sync (
823
864
path. strip_prefix ( & self . prefix ) . unwrap ( ) ,
@@ -872,6 +913,7 @@ where
872
913
mtime_secs : i64 ,
873
914
mtime_nanos : u32 ,
874
915
) -> FsResult < ( ) > {
916
+ self . check_sync_api_allowed ( "lutime_sync" ) ?;
875
917
if path. starts_with ( & self . prefix ) {
876
918
self . fs . lutime_sync (
877
919
path. strip_prefix ( & self . prefix ) . unwrap ( ) ,
@@ -925,6 +967,7 @@ where
925
967
access_check : Option < AccessCheckCb > ,
926
968
data : & [ u8 ] ,
927
969
) -> FsResult < ( ) > {
970
+ self . check_sync_api_allowed ( "write_file_sync" ) ?;
928
971
if path. starts_with ( & self . prefix ) {
929
972
self . fs . write_file_sync (
930
973
path. strip_prefix ( & self . prefix ) . unwrap ( ) ,
@@ -970,6 +1013,7 @@ where
970
1013
path : & Path ,
971
1014
access_check : Option < AccessCheckCb > ,
972
1015
) -> FsResult < Cow < ' static , [ u8 ] > > {
1016
+ self . check_sync_api_allowed ( "read_file_sync" ) ?;
973
1017
if path. starts_with ( & self . prefix ) {
974
1018
self
975
1019
. fs
@@ -1004,6 +1048,9 @@ where
1004
1048
}
1005
1049
1006
1050
fn is_file_sync ( & self , path : & Path ) -> bool {
1051
+ if self . check_sync_api_allowed ( "is_file_sync" ) . is_err ( ) {
1052
+ return false ;
1053
+ }
1007
1054
if path. starts_with ( & self . prefix ) {
1008
1055
self
1009
1056
. fs
@@ -1018,6 +1065,9 @@ where
1018
1065
}
1019
1066
1020
1067
fn is_dir_sync ( & self , path : & Path ) -> bool {
1068
+ if self . check_sync_api_allowed ( "is_dir_sync" ) . is_err ( ) {
1069
+ return false ;
1070
+ }
1021
1071
if path. starts_with ( & self . prefix ) {
1022
1072
self
1023
1073
. fs
@@ -1032,6 +1082,9 @@ where
1032
1082
}
1033
1083
1034
1084
fn exists_sync ( & self , path : & Path ) -> bool {
1085
+ if self . check_sync_api_allowed ( "exists_sync" ) . is_err ( ) {
1086
+ return false ;
1087
+ }
1035
1088
if path. starts_with ( & self . prefix ) {
1036
1089
self
1037
1090
. fs
@@ -1050,6 +1103,7 @@ where
1050
1103
path : & Path ,
1051
1104
access_check : Option < AccessCheckCb > ,
1052
1105
) -> FsResult < Cow < ' static , str > > {
1106
+ self . check_sync_api_allowed ( "read_text_file_lossy_sync" ) ?;
1053
1107
if path. starts_with ( & self . prefix ) {
1054
1108
self . fs . read_text_file_lossy_sync (
1055
1109
path. strip_prefix ( & self . prefix ) . unwrap ( ) ,
@@ -1084,3 +1138,22 @@ where
1084
1138
}
1085
1139
}
1086
1140
}
1141
+
1142
+ impl < FileSystem > PrefixFs < FileSystem > {
1143
+ fn check_sync_api_allowed ( & self , name : & ' static str ) -> FsResult < ( ) > {
1144
+ if !self . check_sync_api {
1145
+ return Ok ( ( ) ) ;
1146
+ }
1147
+ let Some ( state) = self . runtime_state . as_ref ( ) else {
1148
+ return Ok ( ( ) ) ;
1149
+ } ;
1150
+
1151
+ if state. is_init ( ) {
1152
+ Ok ( ( ) )
1153
+ } else {
1154
+ Err ( FsError :: Io ( io:: Error :: other ( anyhow ! ( format!(
1155
+ "invoking {name} is not allowed in the current context"
1156
+ ) ) ) ) )
1157
+ }
1158
+ }
1159
+ }
0 commit comments