@@ -52,6 +52,7 @@ import com.yubico.webauthn.extension.uvm.Generators.userVerificationMethod
5252import org .scalacheck .Arbitrary
5353import org .scalacheck .Arbitrary .arbitrary
5454import org .scalacheck .Gen
55+ import org .scalacheck .Shrink
5556
5657import java .net .URL
5758import java .security .interfaces .ECPublicKey
@@ -349,6 +350,35 @@ object Generators {
349350 implicit val arbitraryByteArray : Arbitrary [ByteArray ] = Arbitrary (
350351 arbitrary[Array [Byte ]].map(new ByteArray (_))
351352 )
353+ implicit val shrinkByteArray : Shrink [ByteArray ] = Shrink ({ b =>
354+ // Attempt to remove as much as possible at a time: first the back half, then the back 1/4, then the back 1/8, etc.
355+ val prefixes = Stream .unfold(0 ) { len =>
356+ val nextLen = (len + b.size()) / 2
357+ if (nextLen == len || nextLen == b.size()) {
358+ None
359+ } else {
360+ Some ((new ByteArray (b.getBytes.slice(0 , nextLen)), nextLen))
361+ }
362+ }
363+
364+ // Same but removing from the front instead.
365+ val suffixes = Stream .unfold(0 ) { len =>
366+ val nextLen = (len + b.size()) / 2
367+ if (nextLen == len || nextLen == b.size()) {
368+ None
369+ } else {
370+ Some (
371+ (
372+ new ByteArray (b.getBytes.slice(b.size() - nextLen, b.size())),
373+ nextLen,
374+ )
375+ )
376+ }
377+ }
378+
379+ prefixes concat suffixes
380+ })
381+
352382 def byteArray (maxSize : Int ): Gen [ByteArray ] =
353383 Gen .listOfN(maxSize, arbitrary[Byte ]).map(ba => new ByteArray (ba.toArray))
354384
0 commit comments