Skip to content

Commit 3cd7da9

Browse files
authored
Merge pull request #4724 from rescript-lang/no_marshal
no unsafe Marshall in encoding/decoding .bsdeps
2 parents af09b16 + 2ef57a5 commit 3cd7da9

File tree

4 files changed

+165
-63
lines changed

4 files changed

+165
-63
lines changed

jscomp/bsb/bsb_ninja_check.ml

Lines changed: 80 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,69 @@
2222
* along with this program; if not, write to the Free Software
2323
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
2424

25+
[@@@warning "+9"]
2526

2627
type t =
2728
{
2829
dir_or_files : string array ;
2930
st_mtimes : float array;
3031
source_directory : string ;
3132
}
33+
(* float_of_string_opt *)
34+
external hexstring_of_float : float -> int -> char -> string
35+
= "caml_hexstring_of_float"
36+
37+
let hex_of_float f = hexstring_of_float f (-1) '-'
38+
39+
(* This should not lose any preicision *)
40+
(* let id (f : float) =
41+
float_of_string (hex_of_float f) = f
42+
*)
43+
44+
let encode ( {source_directory ; st_mtimes; dir_or_files} : t )
45+
(buf: Ext_buffer.t)=
46+
Ext_buffer.add_string_char buf Bs_version.version '\n';
47+
Ext_buffer.add_string_char buf source_directory '\n';
48+
let dir_or_files_len = Array.length dir_or_files in
49+
(if dir_or_files_len <> 0 then begin
50+
Ext_buffer.add_string buf dir_or_files.(0);
51+
for i = 1 to dir_or_files_len - 1 do
52+
Ext_buffer.add_char_string buf '\t' dir_or_files.(i)
53+
done
54+
end);
55+
Ext_buffer.add_char buf '\n';
56+
let st_mtimes_len = Array.length st_mtimes in
57+
(if st_mtimes_len <> 0 then begin
58+
Ext_buffer.add_string buf (hex_of_float st_mtimes.(0));
59+
for i = 1 to st_mtimes_len - 1 do
60+
Ext_buffer.add_char_string buf '\t' (hex_of_float st_mtimes.(i))
61+
done
62+
end);
63+
Ext_buffer.add_char buf '\n'
64+
65+
let decode_exn ic =
66+
let source_directory = input_line ic in
67+
let dir_or_files = input_line ic in
68+
let dir_or_files =
69+
Array.of_list
70+
(Ext_string.split dir_or_files '\t') in
71+
let st_mtimes_line =
72+
input_line ic in
73+
let st_mtimes =
74+
Ext_array.of_list_map
75+
(Ext_string.split st_mtimes_line '\t')
76+
(fun x -> float_of_string x) in
77+
close_in ic ;
78+
{dir_or_files; st_mtimes; source_directory}
3279

3380

34-
let magic_number = Bs_version.version
35-
3681
(* TODO: for such small data structure, maybe text format is better *)
3782

3883
let write (fname : string) (x : t) =
84+
let buf = Ext_buffer.create 1_000 in
85+
encode x buf;
3986
let oc = open_out_bin fname in
40-
output_string oc magic_number ;
41-
output_value oc x ;
87+
Ext_buffer.output_buffer oc buf ;
4288
close_out oc
4389

4490

@@ -47,6 +93,7 @@ let write (fname : string) (x : t) =
4793

4894
type check_result =
4995
| Good
96+
| Bsb_file_corrupted
5097
| Bsb_file_not_exist (** We assume that it is a clean repo *)
5198
| Bsb_source_directory_changed
5299
| Bsb_bsc_version_mismatch
@@ -56,6 +103,7 @@ type check_result =
56103
let pp_check_result fmt (check_resoult : check_result) =
57104
Format.pp_print_string fmt (match check_resoult with
58105
| Good -> "OK"
106+
| Bsb_file_corrupted -> "Stored data corrupted"
59107
| Bsb_file_not_exist -> "Dependencies information missing"
60108
| Bsb_source_directory_changed ->
61109
"Bsb source directory changed"
@@ -75,17 +123,10 @@ let rec check_aux cwd (xs : string array) (ys: float array) i finish =
75123
check_aux cwd xs ys (i + 1 ) finish
76124
else Other current_file
77125

126+
127+
128+
78129

79-
let read (fname : string) (cont : t -> check_result) =
80-
match open_in_bin fname with (* Windows binary mode*)
81-
| ic ->
82-
let buffer = really_input_string ic (String.length magic_number) in
83-
if (buffer <> magic_number) then Bsb_bsc_version_mismatch
84-
else
85-
let res : t = input_value ic in
86-
close_in ic ;
87-
cont res
88-
| exception _ -> Bsb_file_not_exist
89130

90131
let record ~per_proj_dir ~file (file_or_dirs : string list) : unit =
91132
let dir_or_files = Array.of_list file_or_dirs in
@@ -95,8 +136,9 @@ let record ~per_proj_dir ~file (file_or_dirs : string list) : unit =
95136
(Unix.stat (Filename.concat per_proj_dir x )).st_mtime
96137
)
97138
in
98-
write (file ^ "_js" )
99-
{ st_mtimes ;
139+
write file
140+
{
141+
st_mtimes ;
100142
dir_or_files;
101143
source_directory = per_proj_dir ;
102144
}
@@ -108,19 +150,26 @@ let record ~per_proj_dir ~file (file_or_dirs : string list) : unit =
108150
bit in case we found a different version of compiler
109151
*)
110152
let check ~(per_proj_dir:string) ~forced ~file : check_result =
111-
read ( file ^ "_js" ) (fun {
112-
dir_or_files ; source_directory; st_mtimes
113-
} ->
114-
if per_proj_dir <> source_directory then Bsb_source_directory_changed else
115-
if forced then Bsb_forced (* No need walk through *)
116-
else
117-
try
118-
check_aux per_proj_dir dir_or_files st_mtimes 0 (Array.length dir_or_files)
119-
with e ->
120-
begin
121-
Bsb_log.info
122-
"@{<info>Stat miss %s@}@."
123-
(Printexc.to_string e);
124-
Bsb_file_not_exist
125-
end)
153+
match open_in_bin file with (* Windows binary mode*)
154+
| exception _ -> Bsb_file_not_exist
155+
| ic ->
156+
if input_line ic <> Bs_version.version then Bsb_bsc_version_mismatch
157+
else
158+
match decode_exn ic with
159+
| exception _ -> Bsb_file_corrupted (* corrupted file *)
160+
| {
161+
dir_or_files ; source_directory; st_mtimes
162+
} ->
163+
if per_proj_dir <> source_directory then Bsb_source_directory_changed else
164+
if forced then Bsb_forced (* No need walk through *)
165+
else
166+
try
167+
check_aux per_proj_dir dir_or_files st_mtimes 0 (Array.length dir_or_files)
168+
with e ->
169+
begin
170+
Bsb_log.info
171+
"@{<info>Stat miss %s@}@."
172+
(Printexc.to_string e);
173+
Bsb_file_not_exist
174+
end
126175

jscomp/bsb/bsb_ninja_check.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
type check_result =
3838
| Good
39+
| Bsb_file_corrupted
3940
| Bsb_file_not_exist (** We assume that it is a clean repo *)
4041
| Bsb_source_directory_changed
4142
| Bsb_bsc_version_mismatch

jscomp/bsb/bsb_ninja_regen.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ let regenerate_ninja
4848
| Good ->
4949
None (* Fast path, no need regenerate ninja *)
5050
| Bsb_forced
51-
| Bsb_bsc_version_mismatch
51+
| Bsb_bsc_version_mismatch
52+
| Bsb_file_corrupted
5253
| Bsb_file_not_exist
5354
| Bsb_source_directory_changed
5455
| Other _ ->

lib/4.06.1/bsb.ml

Lines changed: 82 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12387,6 +12387,7 @@ module Bsb_ninja_check : sig
1238712387

1238812388
type check_result =
1238912389
| Good
12390+
| Bsb_file_corrupted
1239012391
| Bsb_file_not_exist (** We assume that it is a clean repo *)
1239112392
| Bsb_source_directory_changed
1239212393
| Bsb_bsc_version_mismatch
@@ -12449,23 +12450,69 @@ end = struct
1244912450
* along with this program; if not, write to the Free Software
1245012451
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
1245112452

12453+
[@@@warning "+9"]
1245212454

1245312455
type t =
1245412456
{
1245512457
dir_or_files : string array ;
1245612458
st_mtimes : float array;
1245712459
source_directory : string ;
1245812460
}
12461+
(* float_of_string_opt *)
12462+
external hexstring_of_float : float -> int -> char -> string
12463+
= "caml_hexstring_of_float"
12464+
12465+
let hex_of_float f = hexstring_of_float f (-1) '-'
1245912466

12467+
(* This should not lose any preicision *)
12468+
(* let id (f : float) =
12469+
float_of_string (hex_of_float f) = f
12470+
*)
12471+
12472+
let encode ( {source_directory ; st_mtimes; dir_or_files} : t )
12473+
(buf: Ext_buffer.t)=
12474+
Ext_buffer.add_string_char buf Bs_version.version '\n';
12475+
Ext_buffer.add_string_char buf source_directory '\n';
12476+
let dir_or_files_len = Array.length dir_or_files in
12477+
(if dir_or_files_len <> 0 then begin
12478+
Ext_buffer.add_string buf dir_or_files.(0);
12479+
for i = 1 to dir_or_files_len - 1 do
12480+
Ext_buffer.add_char_string buf '\t' dir_or_files.(i)
12481+
done
12482+
end);
12483+
Ext_buffer.add_char buf '\n';
12484+
let st_mtimes_len = Array.length st_mtimes in
12485+
(if st_mtimes_len <> 0 then begin
12486+
Ext_buffer.add_string buf (hex_of_float st_mtimes.(0));
12487+
for i = 1 to st_mtimes_len - 1 do
12488+
Ext_buffer.add_char_string buf '\t' (hex_of_float st_mtimes.(i))
12489+
done
12490+
end);
12491+
Ext_buffer.add_char buf '\n'
12492+
12493+
let decode_exn ic =
12494+
let source_directory = input_line ic in
12495+
let dir_or_files = input_line ic in
12496+
let dir_or_files =
12497+
Array.of_list
12498+
(Ext_string.split dir_or_files '\t') in
12499+
let st_mtimes_line =
12500+
input_line ic in
12501+
let st_mtimes =
12502+
Ext_array.of_list_map
12503+
(Ext_string.split st_mtimes_line '\t')
12504+
(fun x -> float_of_string x) in
12505+
close_in ic ;
12506+
{dir_or_files; st_mtimes; source_directory}
1246012507

12461-
let magic_number = Bs_version.version
1246212508

1246312509
(* TODO: for such small data structure, maybe text format is better *)
1246412510

1246512511
let write (fname : string) (x : t) =
12512+
let buf = Ext_buffer.create 1_000 in
12513+
encode x buf;
1246612514
let oc = open_out_bin fname in
12467-
output_string oc magic_number ;
12468-
output_value oc x ;
12515+
Ext_buffer.output_buffer oc buf ;
1246912516
close_out oc
1247012517

1247112518

@@ -12474,6 +12521,7 @@ let write (fname : string) (x : t) =
1247412521

1247512522
type check_result =
1247612523
| Good
12524+
| Bsb_file_corrupted
1247712525
| Bsb_file_not_exist (** We assume that it is a clean repo *)
1247812526
| Bsb_source_directory_changed
1247912527
| Bsb_bsc_version_mismatch
@@ -12483,6 +12531,7 @@ type check_result =
1248312531
let pp_check_result fmt (check_resoult : check_result) =
1248412532
Format.pp_print_string fmt (match check_resoult with
1248512533
| Good -> "OK"
12534+
| Bsb_file_corrupted -> "Stored data corrupted"
1248612535
| Bsb_file_not_exist -> "Dependencies information missing"
1248712536
| Bsb_source_directory_changed ->
1248812537
"Bsb source directory changed"
@@ -12502,17 +12551,10 @@ let rec check_aux cwd (xs : string array) (ys: float array) i finish =
1250212551
check_aux cwd xs ys (i + 1 ) finish
1250312552
else Other current_file
1250412553

12554+
12555+
12556+
1250512557

12506-
let read (fname : string) (cont : t -> check_result) =
12507-
match open_in_bin fname with (* Windows binary mode*)
12508-
| ic ->
12509-
let buffer = really_input_string ic (String.length magic_number) in
12510-
if (buffer <> magic_number) then Bsb_bsc_version_mismatch
12511-
else
12512-
let res : t = input_value ic in
12513-
close_in ic ;
12514-
cont res
12515-
| exception _ -> Bsb_file_not_exist
1251612558

1251712559
let record ~per_proj_dir ~file (file_or_dirs : string list) : unit =
1251812560
let dir_or_files = Array.of_list file_or_dirs in
@@ -12522,8 +12564,9 @@ let record ~per_proj_dir ~file (file_or_dirs : string list) : unit =
1252212564
(Unix.stat (Filename.concat per_proj_dir x )).st_mtime
1252312565
)
1252412566
in
12525-
write (file ^ "_js" )
12526-
{ st_mtimes ;
12567+
write file
12568+
{
12569+
st_mtimes ;
1252712570
dir_or_files;
1252812571
source_directory = per_proj_dir ;
1252912572
}
@@ -12535,21 +12578,28 @@ let record ~per_proj_dir ~file (file_or_dirs : string list) : unit =
1253512578
bit in case we found a different version of compiler
1253612579
*)
1253712580
let check ~(per_proj_dir:string) ~forced ~file : check_result =
12538-
read ( file ^ "_js" ) (fun {
12539-
dir_or_files ; source_directory; st_mtimes
12540-
} ->
12541-
if per_proj_dir <> source_directory then Bsb_source_directory_changed else
12542-
if forced then Bsb_forced (* No need walk through *)
12543-
else
12544-
try
12545-
check_aux per_proj_dir dir_or_files st_mtimes 0 (Array.length dir_or_files)
12546-
with e ->
12547-
begin
12548-
Bsb_log.info
12549-
"@{<info>Stat miss %s@}@."
12550-
(Printexc.to_string e);
12551-
Bsb_file_not_exist
12552-
end)
12581+
match open_in_bin file with (* Windows binary mode*)
12582+
| exception _ -> Bsb_file_not_exist
12583+
| ic ->
12584+
if input_line ic <> Bs_version.version then Bsb_bsc_version_mismatch
12585+
else
12586+
match decode_exn ic with
12587+
| exception _ -> Bsb_file_corrupted (* corrupted file *)
12588+
| {
12589+
dir_or_files ; source_directory; st_mtimes
12590+
} ->
12591+
if per_proj_dir <> source_directory then Bsb_source_directory_changed else
12592+
if forced then Bsb_forced (* No need walk through *)
12593+
else
12594+
try
12595+
check_aux per_proj_dir dir_or_files st_mtimes 0 (Array.length dir_or_files)
12596+
with e ->
12597+
begin
12598+
Bsb_log.info
12599+
"@{<info>Stat miss %s@}@."
12600+
(Printexc.to_string e);
12601+
Bsb_file_not_exist
12602+
end
1255312603

1255412604

1255512605
end
@@ -14490,7 +14540,8 @@ let regenerate_ninja
1449014540
| Good ->
1449114541
None (* Fast path, no need regenerate ninja *)
1449214542
| Bsb_forced
14493-
| Bsb_bsc_version_mismatch
14543+
| Bsb_bsc_version_mismatch
14544+
| Bsb_file_corrupted
1449414545
| Bsb_file_not_exist
1449514546
| Bsb_source_directory_changed
1449614547
| Other _ ->

0 commit comments

Comments
 (0)