提交 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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, ...@@ -172,11 +172,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);
} }
...@@ -269,7 +265,7 @@ Java_java_util_zip_ZipFile_getEntryBytes(JNIEnv *env, ...@@ -269,7 +265,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;
if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL) if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
break; break;
(*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name); (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name);
......
...@@ -1021,6 +1021,7 @@ newEntry(jzfile *zip, jzcell *zc, AccessHint accessHint) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 @@ ...@@ -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 */ ...@@ -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); ...@@ -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_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册