Validate object ids before reading

Commit
6a277dcebfe0df59d515dbd49b028da3a236893d
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
lib/resolvers.ml
index d3826860..6dc4ff21 100644..100644
@@ -4,6 +4,17 @@
4 4 open Lwt_result.Syntax
5 5 open Config
6 6
7 Added: let is_hex_digit = function
8 Added: | '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' -> true
9 Added: | _ -> false
10 Added:
11 Added: let is_valid_hash_hex hash =
12 Added: String.length hash = Store.Hash.length * 2 && String.for_all is_hex_digit hash
13 Added:
14 Added: let hash_of_hex hash =
15 Added: if is_valid_hash_hex hash then Lwt_result.return (Store.Hash.of_hex hash)
16 Added: else Lwt_result.fail (`Msg ("invalid object id " ^ hash))
17 Added:
7 18 let is_valid_repo_name repo =
8 19 let invalid_char = function '/' | '\\' | '\x00' -> true | _ -> false in
9 20 repo <> "" && repo <> "." && repo <> ".."
@@ -48,7 +59,7 @@
48 59
49 60 let of_id repo id =
50 61 let* store = store repo in
51 Removed: let hash = Store.Hash.of_hex id in
62 Added: let* hash = hash_of_hex id in
52 63 Lwt_result.bind (Store.read store hash) @@ function
53 64 | Git.Value.Commit commit -> Lwt_result.return (to_t commit)
54 65 | _ -> Lwt_result.fail @@ `Msg ("no commit matches id " ^ id)
@@ -163,7 +174,7 @@
163 174
164 175 let of_id repo id =
165 176 let* store = store repo in
166 Removed: let hash = Store.Hash.of_hex id in
177 Added: let* hash = hash_of_hex id in
167 178 Lwt_result.bind (Store.read store hash) @@ function
168 179 | Git.Value.Tree tree -> Lwt_result.return (to_t tree)
169 180 | _ -> Lwt_result.fail @@ `Msg ("no tree matches id " ^ id)
@@ -185,7 +196,7 @@
185 196
186 197 let of_id repo id =
187 198 let* store = store repo in
188 Removed: let hash = Store.Hash.of_hex id in
199 Added: let* hash = hash_of_hex id in
189 200 Lwt_result.bind (Store.read store hash) @@ function
190 201 | Git.Value.Blob blob -> Lwt_result.return (to_t blob)
191 202 | _ -> Lwt_result.fail @@ `Msg ("no blob matches id " ^ id)
@@ -193,7 +204,7 @@
193 204
194 205 let blob_or_tree repo id =
195 206 let* store = store repo in
196 Removed: let hash = Store.Hash.of_hex id in
207 Added: let* hash = hash_of_hex id in
197 208 Lwt_result.bind (Store.read store hash) @@ function
198 209 | Git.Value.Tree tree -> Lwt_result.return @@ `Tree (Tree.to_t tree)
199 210 | Git.Value.Blob blob -> Lwt_result.return @@ `Blob (Blob.to_t blob)
@@ -210,7 +221,7 @@
210 221 | None -> Lwt_result.return None
211 222 | Some readme -> (
212 223 let* store = store repo in
213 Removed: let hash = Store.Hash.of_hex readme.hash in
224 Added: let* hash = hash_of_hex readme.hash in
214 225 Lwt_result.bind (Store.read store hash) @@ function
215 226 | Git.Value.Blob blob -> Lwt_result.return @@ Some (Blob.to_t blob)
216 227 | _ -> Lwt_result.fail @@ `Msg ("couldn't read file " ^ readme.name))
test/test_ogit.ml
index 9f26a436..227d571a 100644..100644
@@ -35,6 +35,11 @@
35 35 assert (not (Ogit.Resolvers.is_valid_repo_name "nested/repo"));
36 36 assert (not (Ogit.Resolvers.is_valid_repo_name "nested\\repo"));
37 37 assert (not (Ogit.Resolvers.is_valid_repo_name "bad\x00repo"));
38 Added: assert (Ogit.Resolvers.is_valid_hash_hex (String.make 40 'a'));
39 Added: assert (Ogit.Resolvers.is_valid_hash_hex (String.make 40 'A'));
40 Added: assert (not (Ogit.Resolvers.is_valid_hash_hex (String.make 39 'a')));
41 Added: assert (not (Ogit.Resolvers.is_valid_hash_hex (String.make 41 'a')));
42 Added: assert (not (Ogit.Resolvers.is_valid_hash_hex (String.make 39 'a' ^ "x")));
38 43 assert (
39 44 Ogit.Resolvers.Reference.branch_name "refs/heads/main" = Some "main");
40 45 assert (