8048025: Ensure cache consistency
To support zip entry with null character(s) embedded Reviewed-by: alanb, weijun
This commit is contained in:
parent
47d69e2546
commit
5ef6775117
@ -174,11 +174,7 @@ Java_java_util_zip_ZipFile_getEntry(JNIEnv *env, jclass cls, jlong zfile,
|
|||||||
}
|
}
|
||||||
(*env)->GetByteArrayRegion(env, name, 0, ulen, (jbyte *)path);
|
(*env)->GetByteArrayRegion(env, name, 0, ulen, (jbyte *)path);
|
||||||
path[ulen] = '\0';
|
path[ulen] = '\0';
|
||||||
if (addSlash == JNI_FALSE) {
|
ze = ZIP_GetEntry2(zip, path, (jint)ulen, addSlash);
|
||||||
ze = ZIP_GetEntry(zip, path, 0);
|
|
||||||
} else {
|
|
||||||
ze = ZIP_GetEntry(zip, path, (jint)ulen);
|
|
||||||
}
|
|
||||||
if (path != buf) {
|
if (path != buf) {
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
@ -271,7 +267,7 @@ Java_java_util_zip_ZipFile_getEntryBytes(JNIEnv *env,
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case java_util_zip_ZipFile_JZENTRY_NAME:
|
case java_util_zip_ZipFile_JZENTRY_NAME:
|
||||||
if (ze->name != 0) {
|
if (ze->name != 0) {
|
||||||
len = (int)strlen(ze->name);
|
len = (int)ze->nlen;
|
||||||
// Unlike for extra and comment, we never return null for
|
// Unlike for extra and comment, we never return null for
|
||||||
// an (extremely rarely seen) empty name
|
// an (extremely rarely seen) empty name
|
||||||
if ((jba = (*env)->NewByteArray(env, len)) == NULL)
|
if ((jba = (*env)->NewByteArray(env, len)) == NULL)
|
||||||
|
@ -1021,6 +1021,7 @@ newEntry(jzfile *zip, jzcell *zc, AccessHint accessHint)
|
|||||||
if ((ze->name = malloc(nlen + 1)) == NULL) goto Catch;
|
if ((ze->name = malloc(nlen + 1)) == NULL) goto Catch;
|
||||||
memcpy(ze->name, cen + CENHDR, nlen);
|
memcpy(ze->name, cen + CENHDR, nlen);
|
||||||
ze->name[nlen] = '\0';
|
ze->name[nlen] = '\0';
|
||||||
|
ze->nlen = nlen;
|
||||||
if (elen > 0) {
|
if (elen > 0) {
|
||||||
char *extra = cen + CENHDR + nlen;
|
char *extra = cen + CENHDR + nlen;
|
||||||
|
|
||||||
@ -1118,7 +1119,34 @@ ZIP_FreeEntry(jzfile *jz, jzentry *ze)
|
|||||||
jzentry *
|
jzentry *
|
||||||
ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
|
ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
|
||||||
{
|
{
|
||||||
unsigned int hsh = hash(name);
|
if (ulen == 0) {
|
||||||
|
return ZIP_GetEntry2(zip, name, strlen(name), JNI_FALSE);
|
||||||
|
}
|
||||||
|
return ZIP_GetEntry2(zip, name, ulen, JNI_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
jboolean equals(char* name1, int len1, char* name2, int len2) {
|
||||||
|
if (len1 != len2) {
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
while (len1-- > 0) {
|
||||||
|
if (*name1++ != *name2++) {
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return JNI_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the zip entry corresponding to the specified name, or
|
||||||
|
* NULL if not found.
|
||||||
|
* This method supports embedded null character in "name", use ulen
|
||||||
|
* for the length of "name".
|
||||||
|
*/
|
||||||
|
jzentry *
|
||||||
|
ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash)
|
||||||
|
{
|
||||||
|
unsigned int hsh = hashN(name, ulen);
|
||||||
jint idx;
|
jint idx;
|
||||||
jzentry *ze = 0;
|
jzentry *ze = 0;
|
||||||
|
|
||||||
@ -1139,7 +1167,7 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
|
|||||||
|
|
||||||
/* Check the cached entry first */
|
/* Check the cached entry first */
|
||||||
ze = zip->cache;
|
ze = zip->cache;
|
||||||
if (ze && strcmp(ze->name,name) == 0) {
|
if (ze && equals(ze->name, ze->nlen, name, ulen)) {
|
||||||
/* Cache hit! Remove and return the cached entry. */
|
/* Cache hit! Remove and return the cached entry. */
|
||||||
zip->cache = 0;
|
zip->cache = 0;
|
||||||
ZIP_Unlock(zip);
|
ZIP_Unlock(zip);
|
||||||
@ -1165,7 +1193,7 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
|
|||||||
* we keep searching.
|
* we keep searching.
|
||||||
*/
|
*/
|
||||||
ze = newEntry(zip, zc, ACCESS_RANDOM);
|
ze = newEntry(zip, zc, ACCESS_RANDOM);
|
||||||
if (ze && strcmp(ze->name, name)==0) {
|
if (ze && equals(ze->name, ze->nlen, name, ulen)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ze != 0) {
|
if (ze != 0) {
|
||||||
@ -1184,8 +1212,8 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If no real length was passed in, we are done */
|
/* If no need to try appending slash, we are done */
|
||||||
if (ulen == 0) {
|
if (!addSlash) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1195,11 +1223,11 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add slash and try once more */
|
/* Add slash and try once more */
|
||||||
name[ulen] = '/';
|
name[ulen++] = '/';
|
||||||
name[ulen+1] = '\0';
|
name[ulen] = '\0';
|
||||||
hsh = hash_append(hsh, '/');
|
hsh = hash_append(hsh, '/');
|
||||||
idx = zip->table[hsh % zip->tablelen];
|
idx = zip->table[hsh % zip->tablelen];
|
||||||
ulen = 0;
|
addSlash = JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Finally:
|
Finally:
|
||||||
|
@ -154,6 +154,7 @@
|
|||||||
* - If pos <= 0 then it is the position of entry LOC header.
|
* - If pos <= 0 then it is the position of entry LOC header.
|
||||||
* If pos > 0 then it is the position of entry data.
|
* If pos > 0 then it is the position of entry data.
|
||||||
* pos should not be accessed directly, but only by ZIP_GetEntryDataOffset.
|
* pos should not be accessed directly, but only by ZIP_GetEntryDataOffset.
|
||||||
|
* - entry name may include embedded null character, use nlen for length
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct jzentry { /* Zip file entry */
|
typedef struct jzentry { /* Zip file entry */
|
||||||
@ -166,6 +167,7 @@ typedef struct jzentry { /* Zip file entry */
|
|||||||
jbyte *extra; /* optional extra data */
|
jbyte *extra; /* optional extra data */
|
||||||
jlong pos; /* position of LOC header or entry data */
|
jlong pos; /* position of LOC header or entry data */
|
||||||
jint flag; /* general purpose flag */
|
jint flag; /* general purpose flag */
|
||||||
|
jint nlen; /* length of the entry name */
|
||||||
} jzentry;
|
} jzentry;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -269,5 +271,5 @@ void ZIP_Unlock(jzfile *zip);
|
|||||||
jint ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len);
|
jint ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len);
|
||||||
void ZIP_FreeEntry(jzfile *zip, jzentry *ze);
|
void ZIP_FreeEntry(jzfile *zip, jzentry *ze);
|
||||||
jlong ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry);
|
jlong ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry);
|
||||||
|
jzentry * ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash);
|
||||||
#endif /* !_ZIP_H_ */
|
#endif /* !_ZIP_H_ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user