3535import java .util .function .IntPredicate ;
3636import java .util .regex .Pattern ;
3737import java .util .stream .Collectors ;
38- import java .util .stream .IntStream ;
3938
4039/**
4140 * <p>Package-URL (aka purl) is a "mostly universal" URL to describe a package. A purl is a URL composed of seven components:</p>
@@ -477,14 +476,18 @@ private static String uriEncode(String source, Charset charset) {
477476 }
478477
479478 byte [] bytes = source .getBytes (charset );
479+ int length = bytes .length ;
480+ int pos = indexOfFirstUnreservedChar (bytes );
480481
481- if (IntStream . range ( 0 , bytes . length ). allMatch ( i -> isUnreserved ( bytes [ i ])) ) {
482+ if (pos == - 1 ) {
482483 return source ;
483484 }
484485
485- StringBuilder builder = new StringBuilder (source .length ());
486+ StringBuilder builder = new StringBuilder (source .substring (0 , pos ));
487+
488+ for (int i = pos ; i < length ; i ++) {
489+ byte b = bytes [i ];
486490
487- for (byte b : bytes ) {
488491 if (isUnreserved (b )) {
489492 builder .append ((char ) b );
490493 } else {
@@ -497,6 +500,20 @@ private static String uriEncode(String source, Charset charset) {
497500 return builder .toString ();
498501 }
499502
503+ private static int indexOfFirstUnreservedChar (final byte [] bytes ) {
504+ final int length = bytes .length ;
505+ int pos = -1 ;
506+
507+ for (int i = 0 ; i < length ; i ++) {
508+ if (!isUnreserved (bytes [i ])) {
509+ pos = i ;
510+ break ;
511+ }
512+ }
513+
514+ return pos ;
515+ }
516+
500517 private static boolean isUnreserved (int c ) {
501518 return (isValidCharForKey (c ) || c == '~' );
502519 }
0 commit comments