Skip to content

Commit 5146c6d

Browse files
author
Ravi Reddy
committed
8370995: Enhance ZipFile usage
Backport-of: 669ac17c54be6c16b859142ff4dcd063c3787a6e
1 parent 338b992 commit 5146c6d

2 files changed

Lines changed: 59 additions & 97 deletions

File tree

src/java.base/share/native/libzip/zip_util.c

Lines changed: 45 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1995, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1146,20 +1146,8 @@ ZIP_FreeEntry(jzfile *jz, jzentry *ze)
11461146
}
11471147
}
11481148

1149-
/*
1150-
* Returns the zip entry corresponding to the specified name, or
1151-
* NULL if not found.
1152-
*/
1153-
jzentry *
1154-
ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
1155-
{
1156-
if (ulen == 0) {
1157-
return ZIP_GetEntry2(zip, name, (jint)strlen(name), JNI_FALSE);
1158-
}
1159-
return ZIP_GetEntry2(zip, name, ulen, JNI_TRUE);
1160-
}
1161-
1162-
jboolean equals(char* name1, int len1, char* name2, int len2) {
1149+
static jboolean
1150+
equals(const char* name1, int len1, const char* name2, int len2) {
11631151
if (len1 != len2) {
11641152
return JNI_FALSE;
11651153
}
@@ -1171,16 +1159,12 @@ jboolean equals(char* name1, int len1, char* name2, int len2) {
11711159
return JNI_TRUE;
11721160
}
11731161

1174-
/*
1175-
* Returns the zip entry corresponding to the specified name, or
1176-
* NULL if not found.
1177-
* This method supports embedded null character in "name", use ulen
1178-
* for the length of "name".
1179-
*/
11801162
jzentry *
1181-
ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash)
1163+
ZIP_GetEntry(jzfile *zip, const char *name)
11821164
{
1183-
unsigned int hsh = hashN(name, ulen);
1165+
// length of the entry name being searched for
1166+
const jint name_len = (jint) strlen(name);
1167+
const unsigned int hsh = hashN(name, name_len);
11841168
jint idx;
11851169
jzentry *ze = 0;
11861170

@@ -1191,79 +1175,47 @@ ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash)
11911175

11921176
idx = zip->table[hsh % zip->tablelen];
11931177

1178+
/* Check the cached entry first */
1179+
ze = zip->cache;
1180+
if (ze && equals(ze->name, ze->nlen, name, name_len)) {
1181+
/* Cache hit! Remove and return the cached entry. */
1182+
zip->cache = 0;
1183+
ZIP_Unlock(zip);
1184+
return ze;
1185+
}
1186+
ze = 0;
1187+
11941188
/*
1195-
* This while loop is an optimization where a double lookup
1196-
* for name and name+/ is being performed. The name char
1197-
* array has enough room at the end to try again with a
1198-
* slash appended if the first table lookup does not succeed.
1189+
* Search down the target hash chain for a cell whose
1190+
* 32 bit hash matches the hashed name.
11991191
*/
1200-
while(1) {
1201-
1202-
/* Check the cached entry first */
1203-
ze = zip->cache;
1204-
if (ze && equals(ze->name, ze->nlen, name, ulen)) {
1205-
/* Cache hit! Remove and return the cached entry. */
1206-
zip->cache = 0;
1207-
ZIP_Unlock(zip);
1208-
return ze;
1209-
}
1210-
ze = 0;
1211-
1212-
/*
1213-
* Search down the target hash chain for a cell whose
1214-
* 32 bit hash matches the hashed name.
1215-
*/
1216-
while (idx != ZIP_ENDCHAIN) {
1217-
jzcell *zc = &zip->entries[idx];
1218-
1219-
if (zc->hash == hsh) {
1220-
/*
1221-
* OK, we've found a ZIP entry whose 32 bit hashcode
1222-
* matches the name we're looking for. Try to read
1223-
* its entry information from the CEN. If the CEN
1224-
* name matches the name we're looking for, we're
1225-
* done.
1226-
* If the names don't match (which should be very rare)
1227-
* we keep searching.
1228-
*/
1229-
ze = newEntry(zip, zc, ACCESS_RANDOM);
1230-
if (ze && equals(ze->name, ze->nlen, name, ulen)) {
1231-
break;
1232-
}
1233-
if (ze != 0) {
1234-
/* We need to release the lock across the free call */
1235-
ZIP_Unlock(zip);
1236-
ZIP_FreeEntry(zip, ze);
1237-
ZIP_Lock(zip);
1238-
}
1239-
ze = 0;
1192+
while (idx != ZIP_ENDCHAIN) {
1193+
jzcell *zc = &zip->entries[idx];
1194+
1195+
if (zc->hash == hsh) {
1196+
/*
1197+
* OK, we've found a ZIP entry whose 32 bit hashcode
1198+
* matches the name we're looking for. Try to read
1199+
* its entry information from the CEN. If the CEN
1200+
* name matches the name we're looking for, we're
1201+
* done.
1202+
* If the names don't match (which should be very rare)
1203+
* we keep searching.
1204+
*/
1205+
ze = newEntry(zip, zc, ACCESS_RANDOM);
1206+
if (ze && equals(ze->name, ze->nlen, name, name_len)) {
1207+
break;
12401208
}
1241-
idx = zc->next;
1242-
}
1243-
1244-
/* Entry found, return it */
1245-
if (ze != 0) {
1246-
break;
1247-
}
1248-
1249-
/* If no need to try appending slash, we are done */
1250-
if (!addSlash) {
1251-
break;
1252-
}
1253-
1254-
/* Slash is already there? */
1255-
if (ulen > 0 && name[ulen - 1] == '/') {
1256-
break;
1209+
if (ze != 0) {
1210+
/* We need to release the lock across the free call */
1211+
ZIP_Unlock(zip);
1212+
ZIP_FreeEntry(zip, ze);
1213+
ZIP_Lock(zip);
1214+
}
1215+
ze = 0;
12571216
}
1258-
1259-
/* Add slash and try once more */
1260-
name[ulen++] = '/';
1261-
name[ulen] = '\0';
1262-
hsh = hash_append(hsh, '/');
1263-
idx = zip->table[hsh % zip->tablelen];
1264-
addSlash = JNI_FALSE;
1217+
idx = zc->next;
12651218
}
1266-
12671219
Finally:
12681220
ZIP_Unlock(zip);
12691221
return ze;
@@ -1475,9 +1427,9 @@ InflateFully(jzfile *zip, jzentry *entry, void *buf, char **msg)
14751427
* has the size bigger than 2**32 bytes in ONE invocation.
14761428
*/
14771429
JNIEXPORT jzentry *
1478-
ZIP_FindEntry(jzfile *zip, char *name, jint *sizeP, jint *nameLenP)
1430+
ZIP_FindEntry(jzfile *zip, const char *name, jint *sizeP, jint *nameLenP)
14791431
{
1480-
jzentry *entry = ZIP_GetEntry(zip, name, 0);
1432+
jzentry *entry = ZIP_GetEntry(zip, name);
14811433
if (entry) {
14821434
*sizeP = (jint)entry->size;
14831435
*nameLenP = (jint)strlen(entry->name);

src/java.base/share/native/libzip/zip_util.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1995, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -241,8 +241,15 @@ typedef struct jzfile { /* Zip file */
241241
*/
242242
#define ZIP_ENDCHAIN ((jint)-1)
243243

244+
/*
245+
* Returns the ZIP entry corresponding to the given (NULL terminated)
246+
* entry name. Returns NULL if no entry is found by that name.
247+
* If the entry is found, then the value of the given sizeP will be
248+
* updated to the ZIP entry's size and the value of nameLenP will be
249+
* updated to the ZIP entry name's length.
250+
*/
244251
JNIEXPORT jzentry *
245-
ZIP_FindEntry(jzfile *zip, char *name, jint *sizeP, jint *nameLenP);
252+
ZIP_FindEntry(jzfile *zip, const char *name, jint *sizeP, jint *nameLenP);
246253

247254
JNIEXPORT jboolean
248255
ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entrynm);
@@ -268,8 +275,12 @@ ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified,
268275
JNIEXPORT void
269276
ZIP_Close(jzfile *zip);
270277

278+
/*
279+
* Returns the ZIP entry corresponding to the given (NULL terminated)
280+
* entry name. Returns NULL if no entry is found by that name.
281+
*/
271282
jzentry *
272-
ZIP_GetEntry(jzfile *zip, char *name, jint ulen);
283+
ZIP_GetEntry(jzfile *zip, const char *name);
273284
void
274285
ZIP_Lock(jzfile *zip);
275286
void
@@ -279,7 +290,6 @@ ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len);
279290
JNIEXPORT void
280291
ZIP_FreeEntry(jzfile *zip, jzentry *ze);
281292
jlong ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry);
282-
jzentry * ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash);
283293

284294
JNIEXPORT jboolean
285295
ZIP_InflateFully(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);

0 commit comments

Comments
 (0)