Skip to content

Commit 10577ca

Browse files
Aleksei VoitylovRealCLanger
authored andcommitted
8370995: Enhance ZipFile usage
Reviewed-by: abakhtin Backport-of: 5f944aa25471a713b510573775ed893c063056cb
1 parent 1836962 commit 10577ca

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, 2023, 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
@@ -1149,20 +1149,8 @@ ZIP_FreeEntry(jzfile *jz, jzentry *ze)
11491149
}
11501150
}
11511151

1152-
/*
1153-
* Returns the zip entry corresponding to the specified name, or
1154-
* NULL if not found.
1155-
*/
1156-
jzentry *
1157-
ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
1158-
{
1159-
if (ulen == 0) {
1160-
return ZIP_GetEntry2(zip, name, (jint)strlen(name), JNI_FALSE);
1161-
}
1162-
return ZIP_GetEntry2(zip, name, ulen, JNI_TRUE);
1163-
}
1164-
1165-
jboolean equals(char* name1, int len1, char* name2, int len2) {
1152+
static jboolean
1153+
equals(const char* name1, int len1, const char* name2, int len2) {
11661154
if (len1 != len2) {
11671155
return JNI_FALSE;
11681156
}
@@ -1174,16 +1162,12 @@ jboolean equals(char* name1, int len1, char* name2, int len2) {
11741162
return JNI_TRUE;
11751163
}
11761164

1177-
/*
1178-
* Returns the zip entry corresponding to the specified name, or
1179-
* NULL if not found.
1180-
* This method supports embedded null character in "name", use ulen
1181-
* for the length of "name".
1182-
*/
11831165
jzentry *
1184-
ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash)
1166+
ZIP_GetEntry(jzfile *zip, const char *name)
11851167
{
1186-
unsigned int hsh = hashN(name, ulen);
1168+
// length of the entry name being searched for
1169+
const jint name_len = (jint) strlen(name);
1170+
const unsigned int hsh = hashN(name, name_len);
11871171
jint idx;
11881172
jzentry *ze = 0;
11891173

@@ -1194,79 +1178,47 @@ ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash)
11941178

11951179
idx = zip->table[hsh % zip->tablelen];
11961180

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