8
8
using System . Linq ;
9
9
using System . Runtime . InteropServices ;
10
10
using System . Text ;
11
+ using Validation ;
11
12
12
13
namespace Nerdbank . GitVersioning . ManagedGit
13
14
{
@@ -384,25 +385,29 @@ public GitCommit GetCommit(GitObjectId sha, bool readAuthor = false)
384
385
objectish += "0" ;
385
386
}
386
387
387
- if ( TryConvertHexStringToByteArray ( objectish , out var hex ) )
388
+ if ( objectish . Length <= 40 && objectish . Length % 2 == 0 )
388
389
{
389
- foreach ( var pack in this . packs . Value . Span )
390
+ Span < byte > decodedHex = stackalloc byte [ objectish . Length / 2 ] ;
391
+ if ( TryConvertHexStringToByteArray ( objectish , decodedHex ) )
390
392
{
391
- var objectId = pack . Lookup ( hex , endsWithHalfByte ) ;
392
-
393
- // It's possible for the same object to be present in both the object database and the pack files,
394
- // or in multiple pack files.
395
- if ( objectId != null && ! possibleObjectIds . Contains ( objectId . Value ) )
393
+ foreach ( var pack in this . packs . Value . Span )
396
394
{
397
- if ( possibleObjectIds . Count > 0 )
398
- {
399
- // If objectish already resolved to at least one object which is different from the current
400
- // object id, objectish is not well-defined; so stop resolving and return null instead.
401
- return null ;
402
- }
403
- else
395
+ var objectId = pack . Lookup ( decodedHex , endsWithHalfByte ) ;
396
+
397
+ // It's possible for the same object to be present in both the object database and the pack files,
398
+ // or in multiple pack files.
399
+ if ( objectId != null && ! possibleObjectIds . Contains ( objectId . Value ) )
404
400
{
405
- possibleObjectIds . Add ( objectId . Value ) ;
401
+ if ( possibleObjectIds . Count > 0 )
402
+ {
403
+ // If objectish already resolved to at least one object which is different from the current
404
+ // object id, objectish is not well-defined; so stop resolving and return null instead.
405
+ return null ;
406
+ }
407
+ else
408
+ {
409
+ possibleObjectIds . Add ( objectId . Value ) ;
410
+ }
406
411
}
407
412
}
408
413
}
@@ -673,7 +678,7 @@ private static string TrimEndingDirectorySeparator(string path)
673
678
#endif
674
679
}
675
680
676
- private static bool TryConvertHexStringToByteArray ( string hexString , out byte [ ] ? data )
681
+ private static bool TryConvertHexStringToByteArray ( string hexString , Span < byte > data )
677
682
{
678
683
// https://stackoverflow.com/questions/321370/how-can-i-convert-a-hex-string-to-a-byte-array
679
684
if ( hexString . Length % 2 != 0 )
@@ -682,15 +687,22 @@ private static bool TryConvertHexStringToByteArray(string hexString, out byte[]?
682
687
return false ;
683
688
}
684
689
685
- data = new byte [ hexString . Length / 2 ] ;
690
+ Requires . Argument ( data . Length == hexString . Length / 2 , nameof ( data ) , "Length must be exactly half that of " + nameof ( hexString ) + "." ) ;
686
691
for ( int index = 0 ; index < data . Length ; index ++ )
687
692
{
693
+ #if NETCOREAPP3_1_OR_GREATER
694
+ ReadOnlySpan < char > byteValue = hexString . AsSpan ( index * 2 , 2 ) ;
695
+ if ( ! byte . TryParse ( byteValue , NumberStyles . HexNumber , CultureInfo . InvariantCulture , out data [ index ] ) )
696
+ {
697
+ return false ;
698
+ }
699
+ #else
688
700
string byteValue = hexString . Substring ( index * 2 , 2 ) ;
689
701
if ( ! byte . TryParse ( byteValue , NumberStyles . HexNumber , CultureInfo . InvariantCulture , out data [ index ] ) )
690
702
{
691
- data = null ;
692
703
return false ;
693
704
}
705
+ #endif
694
706
}
695
707
696
708
return true ;
0 commit comments