Stack safety

This commit is contained in:
John Whitington 2020-03-04 10:50:32 -08:00
parent 7441608ee0
commit 86a46b4243
3 changed files with 46 additions and 44 deletions

48
cpdf.ml
View File

@ -1241,7 +1241,7 @@ let output_string_of_target pdf fastrefnums x =
let list_bookmarks encoding range pdf output = let list_bookmarks encoding range pdf output =
let process_stripped escaped = let process_stripped escaped =
let b = Buffer.create 200 in let b = Buffer.create 200 in
List.iter iter
(fun x -> (fun x ->
if x <= 127 then Buffer.add_char b (char_of_int x)) if x <= 127 then Buffer.add_char b (char_of_int x))
escaped; escaped;
@ -1371,7 +1371,7 @@ let output_page_info pdf range =
and rotation page = and rotation page =
Pdfpage.int_of_rotation page.Pdfpage.rotate Pdfpage.int_of_rotation page.Pdfpage.rotate
in in
List.iter iter
(fun pnum -> (fun pnum ->
let page = select pnum pages in let page = select pnum pages in
Printf.printf "Page %i:\n" pnum; Printf.printf "Page %i:\n" pnum;
@ -1687,8 +1687,8 @@ let remove_slash s =
| _ -> raise (Failure "remove_slash") | _ -> raise (Failure "remove_slash")
let extract_widths chars_and_widths = let extract_widths chars_and_widths =
let win_to_name = List.map (fun (x, y) -> (y, x)) Pdfglyphlist.name_to_win in let win_to_name = map (fun (x, y) -> (y, x)) Pdfglyphlist.name_to_win in
List.map map
(fun x -> (fun x ->
try try
let name = List.assoc x win_to_name in let name = List.assoc x win_to_name in
@ -2079,10 +2079,10 @@ let rec insert_after_many_changes isbefore padsize offset range = function
item::insert_after_many_changes isbefore padsize offset range t item::insert_after_many_changes isbefore padsize offset range t
let print_changes = let print_changes =
List.iter (fun (f, t) -> Printf.printf "%i --> %i\n" f t) iter (fun (f, t) -> Printf.printf "%i --> %i\n" f t)
let pad_with_pdf (range : int list) (pdf : Pdf.t) (isbefore : bool) (padfile : Pdf.t) = let pad_with_pdf (range : int list) (pdf : Pdf.t) (isbefore : bool) (padfile : Pdf.t) =
let range = List.sort compare (setify range) in let range = sort compare (setify range) in
let merged = let merged =
Pdfmerge.merge_pdfs Pdfmerge.merge_pdfs
false false ["a"; "b"] [pdf; padfile] [ilist 1 (Pdfpage.endpage pdf); ilist 1 (Pdfpage.endpage padfile)] false false ["a"; "b"] [pdf; padfile] [ilist 1 (Pdfpage.endpage pdf); ilist 1 (Pdfpage.endpage padfile)]
@ -2091,7 +2091,7 @@ let pad_with_pdf (range : int list) (pdf : Pdf.t) (isbefore : bool) (padfile : P
cleave (Pdfpage.pages_of_pagetree merged) (Pdfpage.endpage pdf) cleave (Pdfpage.pages_of_pagetree merged) (Pdfpage.endpage pdf)
in in
let newpages = let newpages =
List.map map
(fun (pagenum, page) -> (fun (pagenum, page) ->
if mem pagenum range then if mem pagenum range then
(if isbefore then padpages @ [page] else [page] @ padpages) (if isbefore then padpages @ [page] else [page] @ padpages)
@ -2121,7 +2121,7 @@ let pad padwith range pdf isbefore =
let pages' = insert_after_many pages (combine range blankpages) in let pages' = insert_after_many pages (combine range blankpages) in
let changes = let changes =
insert_after_many_changes insert_after_many_changes
isbefore 1 0 (List.map (fun x -> x + i) range) (ilist 1 (length pages)) isbefore 1 0 (map (fun x -> x + i) range) (ilist 1 (length pages))
in in
Pdfpage.change_pages ~changes true pdf pages' Pdfpage.change_pages ~changes true pdf pages'
@ -2287,7 +2287,7 @@ let transform_annotations pdf transform rest =
match Pdf.lookup_direct pdf "/Annots" rest with match Pdf.lookup_direct pdf "/Annots" rest with
| Some (Pdf.Array annots) -> | Some (Pdf.Array annots) ->
(* Always indirect references, so alter in place *) (* Always indirect references, so alter in place *)
List.iter iter
(function (function
| Pdf.Indirect i -> | Pdf.Indirect i ->
(*Printf.printf "Found an annotation to modify...\n";*) (*Printf.printf "Found an annotation to modify...\n";*)
@ -2524,12 +2524,12 @@ let stamp relative_to_cropbox position topline midline fast scale_to_fit isover
in in
let changed = let changed =
let changes = let changes =
List.map (fun x -> (x, x)) (ilist 1 (length new_pages)) map (fun x -> (x, x)) (ilist 1 (length new_pages))
in in
Pdfpage.change_pages ~changes true merged new_pages Pdfpage.change_pages ~changes true merged new_pages
in in
let new_refnumbers = Pdf.page_reference_numbers changed in let new_refnumbers = Pdf.page_reference_numbers changed in
let changetable = hashtable_of_dictionary (List.combine marks_refnumbers new_refnumbers) in let changetable = hashtable_of_dictionary (combine marks_refnumbers new_refnumbers) in
let new_marks = map (change_bookmark changetable) marks in let new_marks = map (change_bookmark changetable) marks in
Pdfmarks.add_bookmarks new_marks changed Pdfmarks.add_bookmarks new_marks changed
@ -2542,14 +2542,14 @@ let equalize_pages under over =
let length_over = Pdfpage.endpage over in let length_over = Pdfpage.endpage over in
if length_over > length_under then if length_over > length_under then
let changes = let changes =
List.map (fun x -> (x, x)) (ilist 1 length_under) map (fun x -> (x, x)) (ilist 1 length_under)
in in
(under, (under,
(Pdfpage.change_pages (Pdfpage.change_pages
~changes true over (take (Pdfpage.pages_of_pagetree over) length_under))) ~changes true over (take (Pdfpage.pages_of_pagetree over) length_under)))
else if length_under > length_over then else if length_under > length_over then
let changes = let changes =
List.map (fun x -> (x, x)) (ilist 1 length_over) map (fun x -> (x, x)) (ilist 1 length_over)
in in
(under, (under,
Pdfpage.change_pages Pdfpage.change_pages
@ -2591,7 +2591,7 @@ let combine_pages fast under over scaletofit swap equalize =
in in
(* Build the changes. 123456 -> 123123 *) (* Build the changes. 123456 -> 123123 *)
let changes = let changes =
let len = List.length new_pages in let len = length new_pages in
combine (ilist 1 (len * 2)) (let x = ilist 1 len in x @ x) combine (ilist 1 (len * 2)) (let x = ilist 1 len in x @ x)
in in
let changed = Pdfpage.change_pages ~changes true merged new_pages in let changed = Pdfpage.change_pages ~changes true merged new_pages in
@ -3058,7 +3058,7 @@ let rec renumber_in_dest table indest = function
Pdf.recurse_array (renumber_in_dest table indest) a Pdf.recurse_array (renumber_in_dest table indest) a
| Pdf.Dictionary d -> | Pdf.Dictionary d ->
Pdf.Dictionary Pdf.Dictionary
(List.map (map
(function (function
("/Dest", v) -> ("/Dest", renumber_in_dest table true v) ("/Dest", v) -> ("/Dest", renumber_in_dest table true v)
| (k, v) -> (k, renumber_in_dest table indest v)) | (k, v) -> (k, renumber_in_dest table indest v))
@ -3078,7 +3078,7 @@ let copy_annotations_page topdf frompdf frompage topage =
(Pdf.page_reference_numbers frompdf) (Pdf.page_reference_numbers frompdf)
(Pdf.page_reference_numbers topdf)) (Pdf.page_reference_numbers topdf))
in in
List.iter iter
(function (function
(* FIXME: We assume they are indirects. Must also do direct, though rare.*) (* FIXME: We assume they are indirects. Must also do direct, though rare.*)
Pdf.Indirect x -> Pdf.Indirect x ->
@ -3221,7 +3221,7 @@ let twoup_pages_inner isstack fast pdf = function
(* Change the pattern matrices before combining resources *) (* Change the pattern matrices before combining resources *)
let pages, h = let pages, h =
let r = let r =
List.map2 map2
(fun p t -> change_pattern_matrices_page pdf t p) (fun p t -> change_pattern_matrices_page pdf t p)
pages transforms pages transforms
in in
@ -3248,7 +3248,7 @@ let twoup_pages_inner isstack fast pdf = function
[Pdfops.stream_of_ops [Pdfops.stream_of_ops
([Pdfops.Op_q] @ [Pdfops.Op_cm transform] @ clipops @ ops @ [Pdfops.Op_Q])] ([Pdfops.Op_q] @ [Pdfops.Op_cm transform] @ clipops @ ops @ [Pdfops.Op_Q])]
in in
List.flatten flatten
(map2 (map2
(fun p t -> (fun p t ->
transform_annotations pdf t p.Pdfpage.rest; transform_annotations pdf t p.Pdfpage.rest;
@ -3281,7 +3281,7 @@ let f_twoup f_pages pdf =
let pagesets = splitinto 2 pages in let pagesets = splitinto 2 pages in
let renumbered = map (Pdfpage.renumber_pages pdf) pagesets in let renumbered = map (Pdfpage.renumber_pages pdf) pagesets in
let pages' = map (f_pages pdf) renumbered in let pages' = map (f_pages pdf) renumbered in
let changes = List.map (fun x -> (x, (x + 1) / 2)) pagenums in let changes = map (fun x -> (x, (x + 1) / 2)) pagenums in
(*print_changes changes;*) (*print_changes changes;*)
Pdfpage.change_pages ~changes true pdf pages' Pdfpage.change_pages ~changes true pdf pages'
@ -3477,7 +3477,7 @@ let get_xmp_info pdf name =
| Some metadata -> | Some metadata ->
try try
let _, tree = xmltree_of_bytes metadata in let _, tree = xmltree_of_bytes metadata in
let results = List.map (fun (kind, key) -> match get_data_for kind key tree with Some x -> x | None -> "") tocheck in let results = map (fun (kind, key) -> match get_data_for kind key tree with Some x -> x | None -> "") tocheck in
match lose (eq "") results with match lose (eq "") results with
x::_ -> x x::_ -> x
| [] -> "" | [] -> ""
@ -3489,7 +3489,7 @@ let rec set_xml_field kind fieldname value = function
D data -> D data D data -> D data
| E (((n, n'), m), _ (*[D _]*)) when n = kind && n' = fieldname -> (* Replace anything inside, including nothing i.e <tag/> *) | E (((n, n'), m), _ (*[D _]*)) when n = kind && n' = fieldname -> (* Replace anything inside, including nothing i.e <tag/> *)
E (((n, n'), m), [D value]) E (((n, n'), m), [D value])
| E (x, ts) -> E (x, List.map (set_xml_field kind fieldname value) ts) | E (x, ts) -> E (x, map (set_xml_field kind fieldname value) ts)
let set_pdf_info_xml kind fieldname value xmldata pdf = let set_pdf_info_xml kind fieldname value xmldata pdf =
let dtd, tree = xmltree_of_bytes xmldata in let dtd, tree = xmltree_of_bytes xmldata in
@ -3505,7 +3505,7 @@ let set_pdf_info_xml kind fieldname value xmldata pdf =
let set_pdf_info_xml_many changes value xmldata pdf = let set_pdf_info_xml_many changes value xmldata pdf =
let xmldata = ref xmldata in let xmldata = ref xmldata in
List.iter iter
(fun (kind, fieldname) -> (fun (kind, fieldname) ->
xmldata := set_pdf_info_xml kind fieldname value !xmldata pdf) xmldata := set_pdf_info_xml kind fieldname value !xmldata pdf)
changes; changes;
@ -3688,7 +3688,7 @@ let replacements pdf =
let create_metadata pdf = let create_metadata pdf =
let xmp = ref xmp_template in let xmp = ref xmp_template in
List.iter iter
(fun (s, r) -> xmp := string_replace_all s r !xmp) (fun (s, r) -> xmp := string_replace_all s r !xmp)
(replacements pdf); (replacements pdf);
set_metadata_from_bytes false (bytes_of_string !xmp) pdf set_metadata_from_bytes false (bytes_of_string !xmp) pdf
@ -4301,7 +4301,7 @@ let ocg_list pdf =
| Some ocpdict -> | Some ocpdict ->
match Pdf.lookup_direct pdf "/OCGs" ocpdict with match Pdf.lookup_direct pdf "/OCGs" ocpdict with
Some (Pdf.Array elts) -> Some (Pdf.Array elts) ->
List.iter iter
(function (function
Pdf.Indirect i -> Pdf.Indirect i ->
(match Pdf.lookup_direct pdf "/Name" (Pdf.lookup_obj pdf i) with (match Pdf.lookup_direct pdf "/Name" (Pdf.lookup_obj pdf i) with

View File

@ -11,7 +11,7 @@ open Pdfio
let tempfiles = ref [] let tempfiles = ref []
let exit n = let exit n =
begin try List.iter Sys.remove !tempfiles with _ -> exit n end; begin try iter Sys.remove !tempfiles with _ -> exit n end;
exit n exit n
let initial_file_size = ref 0 let initial_file_size = ref 0
@ -3450,7 +3450,7 @@ let add_bookmark_title filename use_title pdf =
let bookmarks_open_to_level n pdf = let bookmarks_open_to_level n pdf =
let marks = Pdfmarks.read_bookmarks pdf in let marks = Pdfmarks.read_bookmarks pdf in
let newmarks = let newmarks =
List.map map
(fun m -> {m with Pdfmarks.isopen = m.Pdfmarks.level < n}) (fun m -> {m with Pdfmarks.isopen = m.Pdfmarks.level < n})
marks marks
in in
@ -3651,9 +3651,9 @@ let go () =
else else
let pdfs = let pdfs =
if args.merge_add_bookmarks then if args.merge_add_bookmarks then
List.map2 map2
(fun filename pdf -> add_bookmark_title filename args.merge_add_bookmarks_use_titles pdf) (fun filename pdf -> add_bookmark_title filename args.merge_add_bookmarks_use_titles pdf)
(List.map (function InFile s -> s | StdIn -> "" | AlreadyInMemory _ -> "") names) (map (function InFile s -> s | StdIn -> "" | AlreadyInMemory _ -> "") names)
pdfs pdfs
else else
pdfs pdfs

View File

@ -1,3 +1,5 @@
open Pdfutil
module J = Tjjson module J = Tjjson
module P = Pdf module P = Pdf
module O = Pdfops module O = Pdfops
@ -14,15 +16,15 @@ let rec json_of_object pdf fcs no_stream_data = function
| P.Real r -> J.Number (sof r) | P.Real r -> J.Number (sof r)
| P.String s -> J.String s | P.String s -> J.String s
| P.Name n -> J.String n | P.Name n -> J.String n
| P.Array objs -> J.Array (List.map (json_of_object pdf fcs no_stream_data) objs) | P.Array objs -> J.Array (map (json_of_object pdf fcs no_stream_data) objs)
| P.Dictionary elts -> | P.Dictionary elts ->
List.iter iter
(function (function
("/Contents", P.Indirect i) -> fcs i ("/Contents", P.Indirect i) -> fcs i
| ("/Contents", P.Array elts) -> List.iter (function P.Indirect i -> fcs i | _ -> ()) elts | ("/Contents", P.Array elts) -> iter (function P.Indirect i -> fcs i | _ -> ()) elts
| _ -> ()) | _ -> ())
elts; elts;
J.Object (List.map (fun (k, v) -> (k, json_of_object pdf fcs no_stream_data v)) elts) J.Object (map (fun (k, v) -> (k, json_of_object pdf fcs no_stream_data v)) elts)
| P.Stream ({contents = (Pdf.Dictionary dict as d, stream)} as mut) as thestream -> | P.Stream ({contents = (Pdf.Dictionary dict as d, stream)} as mut) as thestream ->
Pdf.getstream thestream; Pdf.getstream thestream;
let str = let str =
@ -80,7 +82,7 @@ let json_of_op pdf no_stream_data = function
| O.Op_gs s -> J.Array [J.String s; J.String "gs"] | O.Op_gs s -> J.Array [J.String s; J.String "gs"]
| O.Op_Do s -> J.Array [J.String s; J.String "Do"] | O.Op_Do s -> J.Array [J.String s; J.String "Do"]
| O.Op_CS s -> J.Array [J.String s; J.String "CS"] | O.Op_CS s -> J.Array [J.String s; J.String "CS"]
| O.Op_SCN fs -> J.Array ((List.map (fun x -> J.Number (sof x)) fs) @ [J.String "SCN"]) | O.Op_SCN fs -> J.Array ((map (fun x -> J.Number (sof x)) fs) @ [J.String "SCN"])
| O.Op_j j -> J.Array [J.Number (soi j); J.String "j"] | O.Op_j j -> J.Array [J.Number (soi j); J.String "j"]
| O.Op_cm t -> | O.Op_cm t ->
J.Array J.Array
@ -92,7 +94,7 @@ let json_of_op pdf no_stream_data = function
J.Number (sof t.Pdftransform.f); J.Number (sof t.Pdftransform.f);
J.String "cm"] J.String "cm"]
| O.Op_d (fl, y) -> | O.Op_d (fl, y) ->
J.Array [J.Array (List.map (fun x -> J.Number (sof x)) fl); J.Number (sof y); J.String "d"] J.Array [J.Array (map (fun x -> J.Number (sof x)) fl); J.Number (sof y); J.String "d"]
| O.Op_w w -> J.Array [J.Number (sof w); J.String "w"] | O.Op_w w -> J.Array [J.Number (sof w); J.String "w"]
| O.Op_J j -> J.Array [J.Number (soi j); J.String "J"] | O.Op_J j -> J.Array [J.Number (soi j); J.String "J"]
| O.Op_M m -> J.Array [J.Number (sof m); J.String "M"] | O.Op_M m -> J.Array [J.Number (sof m); J.String "M"]
@ -138,9 +140,9 @@ let json_of_op pdf no_stream_data = function
[J.Number (sof a); J.Number (sof b); J.Number (sof c); [J.Number (sof a); J.Number (sof b); J.Number (sof c);
J.Number (sof d); J.Number (sof e); J.Number (sof k); J.String "d1"] J.Number (sof d); J.Number (sof e); J.Number (sof k); J.String "d1"]
| O.Op_cs s -> J.Array [J.String s; J.String "cs"] | O.Op_cs s -> J.Array [J.String s; J.String "cs"]
| O.Op_SC fs -> J.Array (List.map (fun x -> J.Number (sof x)) fs @ [J.String "SC"]) | O.Op_SC fs -> J.Array (map (fun x -> J.Number (sof x)) fs @ [J.String "SC"])
| O.Op_sc fs -> J.Array (List.map (fun x -> J.Number (sof x)) fs @ [J.String "sc"]) | O.Op_sc fs -> J.Array (map (fun x -> J.Number (sof x)) fs @ [J.String "sc"])
| O.Op_scn fs -> J.Array (List.map (fun x -> J.Number (sof x)) fs @ [J.String "scn"]) | O.Op_scn fs -> J.Array (map (fun x -> J.Number (sof x)) fs @ [J.String "scn"])
| O.Op_G k -> J.Array [J.Number (sof k); J.String "G"] | O.Op_G k -> J.Array [J.Number (sof k); J.String "G"]
| O.Op_g k -> J.Array [J.Number (sof k); J.String "g"] | O.Op_g k -> J.Array [J.Number (sof k); J.String "g"]
| O.Op_RG (r, g, b) -> J.Array [J.Number (sof r); J.Number (sof g); J.Number (sof b); J.String "RG"] | O.Op_RG (r, g, b) -> J.Array [J.Number (sof r); J.Number (sof g); J.Number (sof b); J.String "RG"]
@ -151,9 +153,9 @@ let json_of_op pdf no_stream_data = function
| O.Op_BMC s -> J.Array [J.String s; J.String "BMC"] | O.Op_BMC s -> J.Array [J.String s; J.String "BMC"]
| O.Op_Unknown _ -> J.Array [J.String "Unknown"] | O.Op_Unknown _ -> J.Array [J.String "Unknown"]
| O.Op_SCNName (s, fs) -> | O.Op_SCNName (s, fs) ->
J.Array (List.map (fun x -> J.Number (sof x)) fs @ [J.String s; J.String "SCNName"]) J.Array (map (fun x -> J.Number (sof x)) fs @ [J.String s; J.String "SCNName"])
| O.Op_scnName (s, fs) -> | O.Op_scnName (s, fs) ->
J.Array (List.map (fun x -> J.Number (sof x)) fs @ [J.String s; J.String "scnName"]) J.Array (map (fun x -> J.Number (sof x)) fs @ [J.String s; J.String "scnName"])
| O.InlineImage (dict, data) -> J.Array [json_of_object pdf (fun _ -> ()) no_stream_data dict; J.String (Pdfio.string_of_bytes data)] | O.InlineImage (dict, data) -> J.Array [json_of_object pdf (fun _ -> ()) no_stream_data dict; J.String (Pdfio.string_of_bytes data)]
| O.Op_DP (s, obj) -> J.Array [J.String s; json_of_object pdf (fun _ -> ()) no_stream_data obj; J.String "DP"] | O.Op_DP (s, obj) -> J.Array [J.String s; json_of_object pdf (fun _ -> ()) no_stream_data obj; J.String "DP"]
@ -163,7 +165,7 @@ let json_of_op pdf no_stream_data = function
* PDF standard. *) * PDF standard. *)
let parse_content_stream pdf resources bs = let parse_content_stream pdf resources bs =
let ops = Pdfops.parse_stream pdf resources [bs] in let ops = Pdfops.parse_stream pdf resources [bs] in
J.Array (List.map (json_of_op pdf false) ops) J.Array (map (json_of_op pdf false) ops)
let json_of_pdf parse_content no_stream_data pdf = let json_of_pdf parse_content no_stream_data pdf =
let trailerdict = (0, json_of_object pdf (fun x -> ()) no_stream_data pdf.Pdf.trailerdict) in let trailerdict = (0, json_of_object pdf (fun x -> ()) no_stream_data pdf.Pdf.trailerdict) in
@ -178,12 +180,12 @@ let json_of_pdf parse_content no_stream_data pdf =
trailerdict::!ps trailerdict::!ps
in in
if parse_content then if parse_content then
List.iter (fun n -> Pdfcodec.decode_pdfstream_until_unknown pdf (Pdf.lookup_obj pdf n)) !content_streams; iter (fun n -> Pdfcodec.decode_pdfstream_until_unknown pdf (Pdf.lookup_obj pdf n)) !content_streams;
let pairs_parsed = let pairs_parsed =
if not parse_content then pairs else if not parse_content then pairs else
List.map map
(fun (objnum, obj) -> (fun (objnum, obj) ->
if Pdfutil.mem objnum !content_streams then if mem objnum !content_streams then
begin match obj with begin match obj with
| J.Array [dict; J.String _] -> | J.Array [dict; J.String _] ->
(* FIXME Proper resources here for reasons explained above *) (* FIXME Proper resources here for reasons explained above *)
@ -200,7 +202,7 @@ let json_of_pdf parse_content no_stream_data pdf =
pairs pairs
in in
J.Array J.Array
(List.map (map
(fun (objnum, jsonobj) -> J.Array [J.Number (soi objnum); jsonobj]) (fun (objnum, jsonobj) -> J.Array [J.Number (soi objnum); jsonobj])
pairs_parsed) pairs_parsed)