88using System . Linq ;
99using System . Runtime . InteropServices ;
1010using System . Text ;
11+ using Validation ;
1112
1213namespace Nerdbank . GitVersioning . ManagedGit
1314{
@@ -384,25 +385,29 @@ public GitCommit GetCommit(GitObjectId sha, bool readAuthor = false)
384385 objectish += "0" ;
385386 }
386387
387- if ( TryConvertHexStringToByteArray ( objectish , out var hex ) )
388+ if ( objectish . Length <= 40 && objectish . Length % 2 == 0 )
388389 {
389- foreach ( var pack in this . packs . Value . Span )
390+ Span < byte > decodedHex = stackalloc byte [ objectish . Length / 2 ] ;
391+ if ( TryConvertHexStringToByteArray ( objectish , decodedHex ) )
390392 {
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 )
396394 {
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 ) )
404400 {
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+ }
406411 }
407412 }
408413 }
@@ -673,7 +678,7 @@ private static string TrimEndingDirectorySeparator(string path)
673678#endif
674679 }
675680
676- private static bool TryConvertHexStringToByteArray ( string hexString , out byte [ ] ? data )
681+ private static bool TryConvertHexStringToByteArray ( string hexString , Span < byte > data )
677682 {
678683 // https://stackoverflow.com/questions/321370/how-can-i-convert-a-hex-string-to-a-byte-array
679684 if ( hexString . Length % 2 != 0 )
@@ -682,15 +687,22 @@ private static bool TryConvertHexStringToByteArray(string hexString, out byte[]?
682687 return false ;
683688 }
684689
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 ) + "." ) ;
686691 for ( int index = 0 ; index < data . Length ; index ++ )
687692 {
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
688700 string byteValue = hexString . Substring ( index * 2 , 2 ) ;
689701 if ( ! byte . TryParse ( byteValue , NumberStyles . HexNumber , CultureInfo . InvariantCulture , out data [ index ] ) )
690702 {
691- data = null ;
692703 return false ;
693704 }
705+ #endif
694706 }
695707
696708 return true ;
0 commit comments