@@ -52,6 +52,7 @@ import com.yubico.webauthn.extension.uvm.Generators.userVerificationMethod
52
52
import org .scalacheck .Arbitrary
53
53
import org .scalacheck .Arbitrary .arbitrary
54
54
import org .scalacheck .Gen
55
+ import org .scalacheck .Shrink
55
56
56
57
import java .net .URL
57
58
import java .security .interfaces .ECPublicKey
@@ -349,6 +350,35 @@ object Generators {
349
350
implicit val arbitraryByteArray : Arbitrary [ByteArray ] = Arbitrary (
350
351
arbitrary[Array [Byte ]].map(new ByteArray (_))
351
352
)
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
+
352
382
def byteArray (maxSize : Int ): Gen [ByteArray ] =
353
383
Gen .listOfN(maxSize, arbitrary[Byte ]).map(ba => new ByteArray (ba.toArray))
354
384
0 commit comments