@@ -30,29 +30,35 @@ pub(crate) enum State {
3030
3131/// Lifecycle
3232impl < ' a > CommitRefIter < ' a > {
33- /// Create a commit iterator from data.
34- pub fn from_bytes ( data : & ' a [ u8 ] ) -> CommitRefIter < ' a > {
33+ /// Create a commit iterator from the given `data`, using `hash_kind` to know
34+ /// what kind of hash to expect for validation.
35+ pub fn from_bytes ( data : & ' a [ u8 ] , hash_kind : gix_hash:: Kind ) -> CommitRefIter < ' a > {
3536 CommitRefIter {
3637 data,
3738 state : State :: default ( ) ,
39+ hash_kind,
3840 }
3941 }
4042}
4143
4244/// Access
4345impl < ' a > CommitRefIter < ' a > {
4446 /// Parse `data` as commit and return its PGP signature, along with *all non-signature* data as [`SignedData`], or `None`
45- /// if the commit isn't signed.
47+ /// if the commit isn't signed. All hashes in `data` are parsed as `hash_kind`.
4648 ///
4749 /// This allows the caller to validate the signature by passing the signed data along with the signature back to the program
4850 /// that created it.
49- pub fn signature ( data : & ' a [ u8 ] ) -> Result < Option < ( Cow < ' a , BStr > , SignedData < ' a > ) > , crate :: decode:: Error > {
51+ pub fn signature (
52+ data : & ' a [ u8 ] ,
53+ hash_kind : gix_hash:: Kind ,
54+ ) -> Result < Option < ( Cow < ' a , BStr > , SignedData < ' a > ) > , crate :: decode:: Error > {
5055 let mut signature_and_range = None ;
5156
5257 let raw_tokens = CommitRefIterRaw {
5358 data,
5459 state : State :: default ( ) ,
5560 offset : 0 ,
61+ hash_kind,
5662 } ;
5763 for token in raw_tokens {
5864 let token = token?;
@@ -146,35 +152,43 @@ fn missing_field() -> crate::decode::Error {
146152
147153impl < ' a > CommitRefIter < ' a > {
148154 #[ inline]
149- fn next_inner ( mut i : & ' a [ u8 ] , state : & mut State ) -> Result < ( & ' a [ u8 ] , Token < ' a > ) , crate :: decode:: Error > {
155+ fn next_inner (
156+ mut i : & ' a [ u8 ] ,
157+ state : & mut State ,
158+ hash_kind : gix_hash:: Kind ,
159+ ) -> Result < ( & ' a [ u8 ] , Token < ' a > ) , crate :: decode:: Error > {
150160 let input = & mut i;
151- match Self :: next_inner_ ( input, state) {
161+ match Self :: next_inner_ ( input, state, hash_kind ) {
152162 Ok ( token) => Ok ( ( * input, token) ) ,
153163 Err ( err) => Err ( err) ,
154164 }
155165 }
156166
157- fn next_inner_ ( input : & mut & ' a [ u8 ] , state : & mut State ) -> Result < Token < ' a > , crate :: decode:: Error > {
167+ fn next_inner_ (
168+ input : & mut & ' a [ u8 ] ,
169+ state : & mut State ,
170+ hash_kind : gix_hash:: Kind ,
171+ ) -> Result < Token < ' a > , crate :: decode:: Error > {
158172 use State :: * ;
159173 Ok ( match state {
160174 Tree => {
161- let tree = parse:: header_field ( input, b"tree" , parse:: hex_hash) ?;
175+ let tree = parse:: header_field ( input, b"tree" , |value| parse:: hex_hash ( value , hash_kind ) ) ?;
162176 * state = State :: Parents ;
163177 Token :: Tree {
164178 id : ObjectId :: from_hex ( tree) . expect ( "parsing validation" ) ,
165179 }
166180 }
167181 Parents => {
168182 if input. starts_with ( b"parent " ) {
169- let parent = parse:: header_field ( input, b"parent" , parse:: hex_hash) ?;
183+ let parent = parse:: header_field ( input, b"parent" , |value| parse:: hex_hash ( value , hash_kind ) ) ?;
170184 Token :: Parent {
171185 id : ObjectId :: from_hex ( parent) . expect ( "parsing validation" ) ,
172186 }
173187 } else {
174188 * state = State :: Signature {
175189 of : SignatureKind :: Author ,
176190 } ;
177- Self :: next_inner_ ( input, state) ?
191+ Self :: next_inner_ ( input, state, hash_kind ) ?
178192 }
179193 }
180194 Signature { ref mut of } => {
@@ -201,13 +215,13 @@ impl<'a> CommitRefIter<'a> {
201215 let encoding = parse:: header_field ( input, b"encoding" , Ok ) ?;
202216 Token :: Encoding ( encoding. as_bstr ( ) )
203217 } else {
204- Self :: next_inner_ ( input, state) ?
218+ Self :: next_inner_ ( input, state, hash_kind ) ?
205219 }
206220 }
207221 ExtraHeaders => {
208222 if input. starts_with ( b"\n " ) {
209223 * state = State :: Message ;
210- Self :: next_inner_ ( input, state) ?
224+ Self :: next_inner_ ( input, state, hash_kind ) ?
211225 } else {
212226 let before = * input;
213227 match parse:: any_header_field_multi_line ( input)
@@ -240,7 +254,7 @@ impl<'a> Iterator for CommitRefIter<'a> {
240254 if self . data . is_empty ( ) {
241255 return None ;
242256 }
243- match Self :: next_inner ( self . data , & mut self . state ) {
257+ match Self :: next_inner ( self . data , & mut self . state , self . hash_kind ) {
244258 Ok ( ( data, token) ) => {
245259 self . data = data;
246260 Some ( Ok ( token) )
@@ -258,6 +272,7 @@ struct CommitRefIterRaw<'a> {
258272 data : & ' a [ u8 ] ,
259273 state : State ,
260274 offset : usize ,
275+ hash_kind : gix_hash:: Kind ,
261276}
262277
263278impl < ' a > Iterator for CommitRefIterRaw < ' a > {
@@ -267,7 +282,7 @@ impl<'a> Iterator for CommitRefIterRaw<'a> {
267282 if self . data . is_empty ( ) {
268283 return None ;
269284 }
270- match CommitRefIter :: next_inner ( self . data , & mut self . state ) {
285+ match CommitRefIter :: next_inner ( self . data , & mut self . state , self . hash_kind ) {
271286 Ok ( ( remaining, token) ) => {
272287 let consumed = self . data . len ( ) - remaining. len ( ) ;
273288 let start = self . offset ;
0 commit comments