@@ -116,22 +116,33 @@ let count_to_sl_sl data =
116116 else
117117 None
118118
119- let sort_into_bags dir mine their m_nl t_nl str =
119+ let sort_into_bags ~ counter :( mine_len , their_len ) dir mine their m_nl t_nl str =
120120 if String. length str = 0 then
121+ failwith " invalid patch (empty line)"
122+ else if mine_len = 0 && their_len = 0 && String. get str 0 <> '\\' then
121123 None
122124 else match String. get str 0 , String. slice ~start: 1 str with
123125 | ' ' , data ->
124126 if m_nl || t_nl then
125127 failwith " \" no newline at the end of file\" is not at the end of the file" ;
126- Some (`Both , (data :: mine), (data :: their), m_nl, t_nl)
128+ if mine_len = 0 || their_len = 0 then
129+ failwith " invalid patch (both size exhausted)" ;
130+ let counter = (mine_len - 1 , their_len - 1 ) in
131+ Some (counter, `Both , (data :: mine), (data :: their), m_nl, t_nl)
127132 | '+' , data ->
128133 if t_nl then
129134 failwith " \" no newline at the end of file\" is not at the end of the file" ;
130- Some (`Their , mine, (data :: their), m_nl, t_nl)
135+ if their_len = 0 then
136+ failwith " invalid patch (+ size exhausted)" ;
137+ let counter = (mine_len, their_len - 1 ) in
138+ Some (counter, `Their , mine, (data :: their), m_nl, t_nl)
131139 | '-' , data ->
132140 if m_nl then
133141 failwith " \" no newline at the end of file\" is not at the end of the file" ;
134- Some (`Mine , (data :: mine), their, m_nl, t_nl)
142+ if mine_len = 0 then
143+ failwith " invalid patch (- size exhausted)" ;
144+ let counter = (mine_len - 1 , their_len) in
145+ Some (counter, `Mine , (data :: mine), their, m_nl, t_nl)
135146 | '\\' , _data ->
136147 (* NOTE: Any line starting with '\' is taken as if it was
137148 '\ No newline at end of file' by GNU patch so we do the same *)
@@ -143,20 +154,22 @@ let sort_into_bags dir mine their m_nl t_nl str =
143154 | `Mine -> true , t_nl
144155 | `Their -> m_nl, true
145156 in
146- Some (dir, mine, their, my_nl, their_nl)
147- | _ -> None
157+ let counter = (mine_len, their_len) in
158+ Some (counter, dir, mine, their, my_nl, their_nl)
159+ | _ -> failwith " invalid patch (unknown character)"
148160
149161let to_hunk count data mine_no_nl their_no_nl =
150162 match count_to_sl_sl count with
151163 | None -> None , mine_no_nl, their_no_nl, count :: data
152164 | Some ((mine_start , mine_len ), (their_start , their_len )) ->
153- let rec step dir mine their mine_no_nl their_no_nl = function
154- | [] -> (List. rev mine, List. rev their, mine_no_nl, their_no_nl, [] )
155- | x ::xs -> match sort_into_bags dir mine their mine_no_nl their_no_nl x with
156- | Some (dir , mine , their , mine_no_nl' , their_no_nl' ) -> step dir mine their mine_no_nl' their_no_nl' xs
165+ let counter = (mine_len, their_len) in
166+ let rec step ~counter dir mine their mine_no_nl their_no_nl = function
167+ | [] | [" " ] -> (List. rev mine, List. rev their, mine_no_nl, their_no_nl, [] )
168+ | x ::xs -> match sort_into_bags ~counter dir mine their mine_no_nl their_no_nl x with
169+ | Some (counter , dir , mine , their , mine_no_nl' , their_no_nl' ) -> step ~counter dir mine their mine_no_nl' their_no_nl' xs
157170 | None -> (List. rev mine, List. rev their, mine_no_nl, their_no_nl, x :: xs)
158171 in
159- let mine, their, mine_no_nl, their_no_nl, rest = step `Both [] [] mine_no_nl their_no_nl data in
172+ let mine, their, mine_no_nl, their_no_nl, rest = step ~counter `Both [] [] mine_no_nl their_no_nl data in
160173 (Some { mine_start ; mine_len ; mine ; their_start ; their_len ; their }, mine_no_nl, their_no_nl, rest)
161174
162175let rec to_hunks (mine_no_nl , their_no_nl , acc ) = function
0 commit comments