Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/java/util/zip/ZipFile.c
38830 views
1
/*
2
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
/*
27
* Native method support for java.util.zip.ZipFile
28
*/
29
30
#include <stdio.h>
31
#include <stdlib.h>
32
#include <string.h>
33
#include <errno.h>
34
#include <ctype.h>
35
#include <assert.h>
36
#include "jlong.h"
37
#include "jvm.h"
38
#include "jni.h"
39
#include "jni_util.h"
40
#include "zip_util.h"
41
#ifdef WIN32
42
#include "io_util_md.h"
43
#else
44
#include "io_util.h"
45
#endif
46
47
#include "java_util_zip_ZipFile.h"
48
#include "java_util_jar_JarFile.h"
49
50
#define DEFLATED 8
51
#define STORED 0
52
53
static jfieldID jzfileID;
54
55
static int OPEN_READ = java_util_zip_ZipFile_OPEN_READ;
56
static int OPEN_DELETE = java_util_zip_ZipFile_OPEN_DELETE;
57
58
JNIEXPORT void JNICALL
59
Java_java_util_zip_ZipFile_initIDs(JNIEnv *env, jclass cls)
60
{
61
jzfileID = (*env)->GetFieldID(env, cls, "jzfile", "J");
62
assert(jzfileID != 0);
63
}
64
65
static void
66
ThrowZipException(JNIEnv *env, const char *msg)
67
{
68
jstring s = NULL;
69
jobject x;
70
71
if (msg != NULL) {
72
s = JNU_NewStringPlatform(env, msg);
73
}
74
if (s != NULL) {
75
x = JNU_NewObjectByName(env,
76
"java/util/zip/ZipException",
77
"(Ljava/lang/String;)V", s);
78
if (x != NULL) {
79
(*env)->Throw(env, x);
80
}
81
}
82
}
83
84
JNIEXPORT jlong JNICALL
85
Java_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name,
86
jint mode, jlong lastModified,
87
jboolean usemmap)
88
{
89
const char *path = JNU_GetStringPlatformChars(env, name, 0);
90
char *msg = 0;
91
jlong result = 0;
92
int flag = 0;
93
jzfile *zip = 0;
94
95
if (mode & OPEN_READ) flag |= O_RDONLY;
96
if (mode & OPEN_DELETE) flag |= JVM_O_DELETE;
97
98
if (path != 0) {
99
zip = ZIP_Get_From_Cache(path, &msg, lastModified);
100
if (zip == 0 && msg == 0) {
101
ZFILE zfd = 0;
102
#ifdef WIN32
103
zfd = winFileHandleOpen(env, name, flag);
104
if (zfd == -1) {
105
/* Exception already pending. */
106
goto finally;
107
}
108
#else
109
zfd = JVM_Open(path, flag, 0);
110
if (zfd < 0) {
111
throwFileNotFoundException(env, name);
112
goto finally;
113
}
114
#endif
115
zip = ZIP_Put_In_Cache0(path, zfd, &msg, lastModified, usemmap);
116
}
117
118
if (zip != 0) {
119
result = ptr_to_jlong(zip);
120
} else if (msg != 0) {
121
ThrowZipException(env, msg);
122
free(msg);
123
} else if (errno == ENOMEM) {
124
JNU_ThrowOutOfMemoryError(env, 0);
125
} else {
126
ThrowZipException(env, "error in opening zip file");
127
}
128
finally:
129
JNU_ReleaseStringPlatformChars(env, name, path);
130
}
131
return result;
132
}
133
134
JNIEXPORT jint JNICALL
135
Java_java_util_zip_ZipFile_getTotal(JNIEnv *env, jclass cls, jlong zfile)
136
{
137
jzfile *zip = jlong_to_ptr(zfile);
138
139
return zip->total;
140
}
141
142
JNIEXPORT jboolean JNICALL
143
Java_java_util_zip_ZipFile_startsWithLOC(JNIEnv *env, jclass cls, jlong zfile)
144
{
145
jzfile *zip = jlong_to_ptr(zfile);
146
147
return zip->locsig;
148
}
149
150
JNIEXPORT void JNICALL
151
Java_java_util_zip_ZipFile_close(JNIEnv *env, jclass cls, jlong zfile)
152
{
153
ZIP_Close(jlong_to_ptr(zfile));
154
}
155
156
JNIEXPORT jlong JNICALL
157
Java_java_util_zip_ZipFile_getEntry(JNIEnv *env, jclass cls, jlong zfile,
158
jbyteArray name, jboolean addSlash)
159
{
160
#define MAXNAME 1024
161
jzfile *zip = jlong_to_ptr(zfile);
162
jsize ulen = (*env)->GetArrayLength(env, name);
163
char buf[MAXNAME+2], *path;
164
jzentry *ze;
165
166
if (ulen > MAXNAME) {
167
path = malloc(ulen + 2);
168
if (path == 0) {
169
JNU_ThrowOutOfMemoryError(env, 0);
170
return 0;
171
}
172
} else {
173
path = buf;
174
}
175
(*env)->GetByteArrayRegion(env, name, 0, ulen, (jbyte *)path);
176
path[ulen] = '\0';
177
ze = ZIP_GetEntry2(zip, path, (jint)ulen, addSlash);
178
if (path != buf) {
179
free(path);
180
}
181
return ptr_to_jlong(ze);
182
}
183
184
JNIEXPORT void JNICALL
185
Java_java_util_zip_ZipFile_freeEntry(JNIEnv *env, jclass cls, jlong zfile,
186
jlong zentry)
187
{
188
jzfile *zip = jlong_to_ptr(zfile);
189
jzentry *ze = jlong_to_ptr(zentry);
190
ZIP_FreeEntry(zip, ze);
191
}
192
193
JNIEXPORT jlong JNICALL
194
Java_java_util_zip_ZipFile_getNextEntry(JNIEnv *env, jclass cls, jlong zfile,
195
jint n)
196
{
197
jzentry *ze = ZIP_GetNextEntry(jlong_to_ptr(zfile), n);
198
return ptr_to_jlong(ze);
199
}
200
201
JNIEXPORT jint JNICALL
202
Java_java_util_zip_ZipFile_getEntryMethod(JNIEnv *env, jclass cls, jlong zentry)
203
{
204
jzentry *ze = jlong_to_ptr(zentry);
205
return ze->csize != 0 ? DEFLATED : STORED;
206
}
207
208
JNIEXPORT jint JNICALL
209
Java_java_util_zip_ZipFile_getEntryFlag(JNIEnv *env, jclass cls, jlong zentry)
210
{
211
jzentry *ze = jlong_to_ptr(zentry);
212
return ze->flag;
213
}
214
215
JNIEXPORT jlong JNICALL
216
Java_java_util_zip_ZipFile_getEntryCSize(JNIEnv *env, jclass cls, jlong zentry)
217
{
218
jzentry *ze = jlong_to_ptr(zentry);
219
return ze->csize != 0 ? ze->csize : ze->size;
220
}
221
222
JNIEXPORT jlong JNICALL
223
Java_java_util_zip_ZipFile_getEntrySize(JNIEnv *env, jclass cls, jlong zentry)
224
{
225
jzentry *ze = jlong_to_ptr(zentry);
226
return ze->size;
227
}
228
229
JNIEXPORT jlong JNICALL
230
Java_java_util_zip_ZipFile_getEntryTime(JNIEnv *env, jclass cls, jlong zentry)
231
{
232
jzentry *ze = jlong_to_ptr(zentry);
233
return (jlong)ze->time & 0xffffffffUL;
234
}
235
236
JNIEXPORT jlong JNICALL
237
Java_java_util_zip_ZipFile_getEntryCrc(JNIEnv *env, jclass cls, jlong zentry)
238
{
239
jzentry *ze = jlong_to_ptr(zentry);
240
return (jlong)ze->crc & 0xffffffffUL;
241
}
242
243
JNIEXPORT jbyteArray JNICALL
244
Java_java_util_zip_ZipFile_getCommentBytes(JNIEnv *env,
245
jclass cls,
246
jlong zfile)
247
{
248
jzfile *zip = jlong_to_ptr(zfile);
249
jbyteArray jba = NULL;
250
251
if (zip->comment != NULL) {
252
if ((jba = (*env)->NewByteArray(env, zip->clen)) == NULL)
253
return NULL;
254
(*env)->SetByteArrayRegion(env, jba, 0, zip->clen, (jbyte*)zip->comment);
255
}
256
return jba;
257
}
258
259
JNIEXPORT jbyteArray JNICALL
260
Java_java_util_zip_ZipFile_getEntryBytes(JNIEnv *env,
261
jclass cls,
262
jlong zentry, jint type)
263
{
264
jzentry *ze = jlong_to_ptr(zentry);
265
int len = 0;
266
jbyteArray jba = NULL;
267
switch (type) {
268
case java_util_zip_ZipFile_JZENTRY_NAME:
269
if (ze->name != 0) {
270
len = (int)ze->nlen;
271
if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
272
break;
273
(*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name);
274
}
275
break;
276
case java_util_zip_ZipFile_JZENTRY_EXTRA:
277
if (ze->extra != 0) {
278
unsigned char *bp = (unsigned char *)&ze->extra[0];
279
len = (bp[0] | (bp[1] << 8));
280
if (len <= 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
281
break;
282
(*env)->SetByteArrayRegion(env, jba, 0, len, &ze->extra[2]);
283
}
284
break;
285
case java_util_zip_ZipFile_JZENTRY_COMMENT:
286
if (ze->comment != 0) {
287
len = (int)strlen(ze->comment);
288
if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
289
break;
290
(*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte*)ze->comment);
291
}
292
break;
293
}
294
return jba;
295
}
296
297
JNIEXPORT jint JNICALL
298
Java_java_util_zip_ZipFile_read(JNIEnv *env, jclass cls, jlong zfile,
299
jlong zentry, jlong pos, jbyteArray bytes,
300
jint off, jint len)
301
{
302
jzfile *zip = jlong_to_ptr(zfile);
303
char *msg;
304
305
#define BUFSIZE 8192
306
/* copy via tmp stack buffer: */
307
jbyte buf[BUFSIZE];
308
309
if (len > BUFSIZE) {
310
len = BUFSIZE;
311
}
312
313
ZIP_Lock(zip);
314
len = ZIP_Read(zip, jlong_to_ptr(zentry), pos, buf, len);
315
msg = zip->msg;
316
ZIP_Unlock(zip);
317
if (len != -1) {
318
(*env)->SetByteArrayRegion(env, bytes, off, len, buf);
319
}
320
321
if (len == -1) {
322
if (msg != 0) {
323
ThrowZipException(env, msg);
324
} else {
325
char errmsg[128];
326
sprintf(errmsg, "errno: %d, error: %s\n",
327
errno, "Error reading ZIP file");
328
JNU_ThrowIOExceptionWithLastError(env, errmsg);
329
}
330
}
331
332
return len;
333
}
334
335
/*
336
* Returns an array of strings representing the names of all entries
337
* that begin with "META-INF/" (case ignored). This native method is
338
* used in JarFile as an optimization when looking up manifest and
339
* signature file entries. Returns null if no entries were found.
340
*/
341
JNIEXPORT jobjectArray JNICALL
342
Java_java_util_jar_JarFile_getMetaInfEntryNames(JNIEnv *env, jobject obj)
343
{
344
jlong zfile = (*env)->GetLongField(env, obj, jzfileID);
345
jzfile *zip;
346
int i, count;
347
jobjectArray result = 0;
348
349
if (zfile == 0) {
350
JNU_ThrowByName(env,
351
"java/lang/IllegalStateException", "zip file closed");
352
return NULL;
353
}
354
zip = jlong_to_ptr(zfile);
355
356
/* count the number of valid ZIP metanames */
357
count = 0;
358
if (zip->metanames != 0) {
359
for (i = 0; i < zip->metacount; i++) {
360
if (zip->metanames[i] != 0) {
361
count++;
362
}
363
}
364
}
365
366
/* If some names were found then build array of java strings */
367
if (count > 0) {
368
jclass cls = JNU_ClassString(env);
369
CHECK_NULL_RETURN(cls, NULL);
370
result = (*env)->NewObjectArray(env, count, cls, 0);
371
CHECK_NULL_RETURN(result, NULL);
372
if (result != 0) {
373
for (i = 0; i < count; i++) {
374
jstring str = (*env)->NewStringUTF(env, zip->metanames[i]);
375
if (str == 0) {
376
break;
377
}
378
(*env)->SetObjectArrayElement(env, result, i, str);
379
(*env)->DeleteLocalRef(env, str);
380
}
381
}
382
}
383
return result;
384
}
385
386
JNIEXPORT jstring JNICALL
387
Java_java_util_zip_ZipFile_getZipMessage(JNIEnv *env, jclass cls, jlong zfile)
388
{
389
jzfile *zip = jlong_to_ptr(zfile);
390
char *msg = zip->msg;
391
if (msg == NULL) {
392
return NULL;
393
}
394
return JNU_NewStringPlatform(env, msg);
395
}
396
397