@@ -347,9 +347,12 @@ public ZipEntry getEntry(String name) {
347347 ZipEntry entry = null ;
348348 synchronized (this ) {
349349 ensureOpen ();
350- int pos = res .zsrc .getEntryPos (name , true );
351- if (pos != -1 ) {
352- entry = getZipEntry (name , pos );
350+ // Look up the name and CEN header position of the entry.
351+ // The resolved name may include a trailing slash.
352+ // See Source::getEntryPos for details.
353+ EntryPos pos = res .zsrc .getEntryPos (name , true );
354+ if (pos != null ) {
355+ entry = getZipEntry (pos .name , pos .pos );
353356 }
354357 }
355358 return entry ;
@@ -387,7 +390,12 @@ public InputStream getInputStream(ZipEntry entry) throws IOException {
387390 if (Objects .equals (lastEntryName , entry .name )) {
388391 pos = lastEntryPos ;
389392 } else {
390- pos = zsrc .getEntryPos (entry .name , false );
393+ EntryPos entryPos = zsrc .getEntryPos (entry .name , false );
394+ if (entryPos != null ) {
395+ pos = entryPos .pos ;
396+ } else {
397+ pos = -1 ;
398+ }
391399 }
392400 if (pos == -1 ) {
393401 return null ;
@@ -540,7 +548,8 @@ public T next() {
540548 throw new NoSuchElementException ();
541549 }
542550 // each "entry" has 3 ints in table entries
543- return (T )getZipEntry (null , res .zsrc .getEntryPos (i ++ * 3 ));
551+ int pos = res .zsrc .getEntryPos (i ++ * 3 );
552+ return (T )getZipEntry (getEntryName (pos ), pos );
544553 }
545554 }
546555
@@ -612,7 +621,7 @@ public Stream<? extends ZipEntry> stream() {
612621 synchronized (this ) {
613622 ensureOpen ();
614623 return StreamSupport .stream (new EntrySpliterator <>(0 , res .zsrc .total ,
615- pos -> getZipEntry (null , pos )), false );
624+ pos -> getZipEntry (getEntryName ( pos ) , pos )), false );
616625 }
617626 }
618627
@@ -655,7 +664,7 @@ private Stream<JarEntry> jarStream() {
655664 synchronized (this ) {
656665 ensureOpen ();
657666 return StreamSupport .stream (new EntrySpliterator <>(0 , res .zsrc .total ,
658- pos -> (JarEntry )getZipEntry (null , pos )), false );
667+ pos -> (JarEntry )getZipEntry (getEntryName ( pos ) , pos )), false );
659668 }
660669 }
661670
@@ -665,30 +674,10 @@ private Stream<JarEntry> jarStream() {
665674 /* Check ensureOpen() before invoking this method */
666675 private ZipEntry getZipEntry (String name , int pos ) {
667676 byte [] cen = res .zsrc .cen ;
668- int nlen = CENNAM ( cen , pos );
669- int elen = CENEXT ( cen , pos );
670- int clen = CENCOM ( cen , pos );
677+ ZipEntry e = this instanceof JarFile jarFile
678+ ? Source . JUJA . entryFor ( jarFile , name )
679+ : new ZipEntry ( name );
671680
672- ZipCoder zc = res .zsrc .zipCoderForPos (pos );
673- if (name != null ) {
674- // only need to check for mismatch of trailing slash
675- if (nlen > 0 &&
676- !name .isEmpty () &&
677- zc .hasTrailingSlash (cen , pos + CENHDR + nlen ) &&
678- !name .endsWith ("/" ))
679- {
680- name += '/' ;
681- }
682- } else {
683- // invoked from iterator, use the entry name stored in cen
684- name = zc .toString (cen , pos + CENHDR , nlen );
685- }
686- ZipEntry e ;
687- if (this instanceof JarFile ) {
688- e = Source .JUJA .entryFor ((JarFile )this , name );
689- } else {
690- e = new ZipEntry (name );
691- }
692681 e .flag = CENFLG (cen , pos );
693682 e .xdostime = CENTIM (cen , pos );
694683 e .crc = CENCRC (cen , pos );
@@ -700,12 +689,17 @@ private ZipEntry getZipEntry(String name, int pos) {
700689 e .externalFileAttributes = CENATX_PERMS (cen , pos ) & 0xFFFF ;
701690 }
702691
692+ int nlen = CENNAM (cen , pos );
693+ int elen = CENEXT (cen , pos );
694+ int clen = CENCOM (cen , pos );
695+
703696 if (elen != 0 ) {
704697 int start = pos + CENHDR + nlen ;
705698 e .setExtra0 (Arrays .copyOfRange (cen , start , start + elen ), true , false );
706699 }
707700 if (clen != 0 ) {
708701 int start = pos + CENHDR + nlen + elen ;
702+ ZipCoder zc = res .zsrc .zipCoderForPos (pos );
709703 e .comment = zc .toString (cen , start , clen );
710704 }
711705 lastEntryName = e .name ;
@@ -1176,6 +1170,8 @@ public void setExternalFileAttributes(ZipEntry ze, int externalFileAttributes) {
11761170 }
11771171 );
11781172 }
1173+ // Represents the resolved name and position of a CEN record
1174+ static record EntryPos (String name , int pos ) {}
11791175
11801176 private static class Source {
11811177 // While this is only used from ZipFile, defining it there would cause
@@ -1849,12 +1845,12 @@ private static void zerror(String msg) throws ZipException {
18491845 }
18501846
18511847 /*
1852- * Returns the {@code pos} of the ZIP cen entry corresponding to the
1853- * specified entry name, or -1 if not found.
1848+ * Returns the resolved name and position of the ZIP cen entry corresponding
1849+ * to the specified entry name, or {@code null} if not found.
18541850 */
1855- private int getEntryPos (String name , boolean addSlash ) {
1851+ private EntryPos getEntryPos (String name , boolean addSlash ) {
18561852 if (total == 0 ) {
1857- return - 1 ;
1853+ return null ;
18581854 }
18591855
18601856 int hsh = ZipCoder .hash (name );
@@ -1877,7 +1873,7 @@ private int getEntryPos(String name, boolean addSlash) {
18771873 switch (zc .compare (name , cen , noff , nlen , addSlash )) {
18781874 case EXACT_MATCH :
18791875 // We found an exact match for "name"
1880- return pos ;
1876+ return new EntryPos ( name , pos ) ;
18811877 case DIRECTORY_MATCH :
18821878 // We found the directory "name/"
18831879 // Track its position, then continue the search for "name"
@@ -1892,10 +1888,10 @@ private int getEntryPos(String name, boolean addSlash) {
18921888 // Reaching this point means we did not find "name".
18931889 // Return the position of "name/" if we found it
18941890 if (dirPos != -1 ) {
1895- return dirPos ;
1891+ return new EntryPos ( name + "/" , dirPos ) ;
18961892 }
18971893 // No entry found
1898- return - 1 ;
1894+ return null ;
18991895 }
19001896
19011897 private ZipCoder zipCoderForPos (int pos ) {
0 commit comments