Skip to content

Commit a6c1524

Browse files
committed
qcow-stream-tool: Use tail-recursive List.rev_map in read_headers
Otherwise we overflow the stack on large QCOW files: qcow-stream-tool: internal error, uncaught exception: Stack overflow Raised by primitive operation at Dune__exe__Qcow_stream_tool.Impl.read_headers.(fun) in file "ocaml/qcow-stream-tool/qcow_stream_tool.ml", line 23, characters 12-24 Called from Stdlib__List.map in file "list.ml", line 92, characters 32-39 Called from Stdlib__List.map in file "list.ml", line 92, characters 32-39 .... List.rev + List.rev_map is not terribly efficient, but more efficient than reverting back to handling the QCOW file as raw without knowing which clusters are allocated. Signed-off-by: Andrii Sultanov <[email protected]>
1 parent 1b75c36 commit a6c1524

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

ocaml/qcow-stream-tool/qcow_stream_tool.ml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@ module Impl = struct
1414
in
1515
let clusters = Qcow_types.Cluster.Map.bindings data_cluster_map in
1616
let clusters =
17-
List.map
18-
(fun (_, virt_address) ->
19-
let ( >> ) = Int64.shift_right_logical in
20-
let address =
21-
Int64.to_int (virt_address >> Int32.to_int cluster_bits)
22-
in
23-
`Int address
17+
List.rev
18+
(List.rev_map
19+
(fun (_, virt_address) ->
20+
let ( >> ) = Int64.shift_right_logical in
21+
let address =
22+
Int64.to_int (virt_address >> Int32.to_int cluster_bits)
23+
in
24+
`Int address
25+
)
26+
clusters
2427
)
25-
clusters
2628
in
2729
let json =
2830
`Assoc

0 commit comments

Comments
 (0)