ocaml.lang.portability.crlf-support.prefer-read-in-binary-mode

profile photo of semgrepsemgrep
Author
109
Download Count*

'open_in' behaves differently on Windows and on Unix-like systems with respect to line endings. To get the same behavior everywhere, use 'open_in_bin' or 'open_in_gen [Open_binary]'. If you really want CRLF-to-LF translations to take place when running on Windows, use 'open_in_gen [Open_text]'.

Run Locally

Run in CI

Defintion

rules:
  - id: prefer-read-in-binary-mode
    pattern: open_in
    fix: open_in_bin
    message: "'open_in' behaves differently on Windows and on Unix-like systems with
      respect to line endings. To get the same behavior everywhere, use
      'open_in_bin' or 'open_in_gen [Open_binary]'. If you really want
      CRLF-to-LF translations to take place when running on Windows, use
      'open_in_gen [Open_text]'."
    languages:
      - ocaml
    severity: WARNING
    metadata:
      category: portability
      technology:
        - ocaml
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]

Examples

crlf-support.ml

let get_line ic =
  try
    (* ruleid:broken-input-line *)
    Some (input_line ic)
  with
    End_of_file -> None

let with_in_file path f =
  (* ruleid:prefer-read-in-binary-mode *)
  let ic = open_in path in
  Fun.protect
    ~finally:(fun () -> close_in_noerr ic)
    (fun () -> f ic)

let with_in_file path f =
  (* ruleid:prefer-write-in-binary-mode *)
  let oc = open_out path in
  Fun.protect
    ~finally:(fun () -> close_out_noerr oc)
    (fun () -> f oc)

(* Force text mode without triggering alert *)
let with_in_text path f =
  let ic = open_in_gen [Open_text] 0o000 path in
  Fun.protect
    ~finally:(fun () -> close_in_noerr ic)
    (fun () -> f ic)

(* Force text mode without triggering alert *)
let with_out_text path f =
  let oc = open_out_gen [Open_text] 0o666 path in
  Fun.protect
    ~finally:(fun () -> close_out_noerr oc)
    (fun () -> f oc)