提交 539567c2 编写于 作者: S sherman

8048026: Ensure cache consistency

Summary: To support zip entry with null character(s) embedded
Reviewed-by: alanb, weijun
上级 eb5b5af0
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -172,11 +172,7 @@ Java_java_util_zip_ZipFile_getEntry(JNIEnv *env, jclass cls, jlong zfile,
}
(*env)->GetByteArrayRegion(env, name, 0, ulen, (jbyte *)path);
path[ulen] = '\0';
if (addSlash == JNI_FALSE) {
ze = ZIP_GetEntry(zip, path, 0);
} else {
ze = ZIP_GetEntry(zip, path, (jint)ulen);
}
ze = ZIP_GetEntry2(zip, path, (jint)ulen, addSlash);
if (path != buf) {
free(path);
}
......@@ -269,7 +265,7 @@ Java_java_util_zip_ZipFile_getEntryBytes(JNIEnv *env,
switch (type) {
case java_util_zip_ZipFile_JZENTRY_NAME:
if (ze->name != 0) {
len = (int)strlen(ze->name);
len = (int)ze->nlen;
if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
break;
(*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name);
......
......@@ -1021,6 +1021,7 @@ newEntry(jzfile *zip, jzcell *zc, AccessHint accessHint)
if ((ze->name = malloc(nlen + 1)) == NULL) goto Catch;
memcpy(ze->name, cen + CENHDR, nlen);
ze->name[nlen] = '\0';
ze->nlen = nlen;
if (elen > 0) {
char *extra = cen + CENHDR + nlen;
......@@ -1118,7 +1119,34 @@ ZIP_FreeEntry(jzfile *jz, jzentry *ze)
jzentry *
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;
jzentry *ze = 0;
......@@ -1139,7 +1167,7 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
/* Check the cached entry first */
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. */
zip->cache = 0;
ZIP_Unlock(zip);
......@@ -1165,7 +1193,7 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
* we keep searching.
*/
ze = newEntry(zip, zc, ACCESS_RANDOM);
if (ze && strcmp(ze->name, name)==0) {
if (ze && equals(ze->name, ze->nlen, name, ulen)) {
break;
}
if (ze != 0) {
......@@ -1184,8 +1212,8 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
break;
}
/* If no real length was passed in, we are done */
if (ulen == 0) {
/* If no need to try appending slash, we are done */
if (!addSlash) {
break;
}
......@@ -1195,11 +1223,11 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
}
/* Add slash and try once more */
name[ulen] = '/';
name[ulen+1] = '\0';
name[ulen++] = '/';
name[ulen] = '\0';
hsh = hash_append(hsh, '/');
idx = zip->table[hsh % zip->tablelen];
ulen = 0;
addSlash = JNI_FALSE;
}
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 data.
* 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 */
......@@ -166,6 +167,7 @@ typedef struct jzentry { /* Zip file entry */
jbyte *extra; /* optional extra data */
jlong pos; /* position of LOC header or entry data */
jint flag; /* general purpose flag */
jint nlen; /* length of the entry name */
} jzentry;
/*
......@@ -269,5 +271,5 @@ void ZIP_Unlock(jzfile *zip);
jint ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len);
void ZIP_FreeEntry(jzfile *zip, jzentry *ze);
jlong ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry);
jzentry * ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash);
#endif /* !_ZIP_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册