Projects
openEuler:24.03:SP1:Everything
openjdk-1.8.0
_service:tar_scm:support-KAE-zip.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:support-KAE-zip.patch of Package openjdk-1.8.0
Subject: [PATCH] [Huawei]support KAE-zip --- jdk/make/CompileLaunchers.gmk | 34 ++++--- jdk/make/lib/CoreLibraries.gmk | 71 ++++++++++++++ jdk/make/mapfiles/libzip/mapfile-vers | 3 + .../share/classes/java/util/zip/Deflater.java | 10 +- .../java/util/zip/GZIPInputStream.java | 14 +++ .../java/util/zip/GZIPOutputStream.java | 20 ++++ .../share/classes/java/util/zip/Inflater.java | 14 ++- .../java/util/zip/InflaterOutputStream.java | 24 ++--- jdk/src/share/lib/security/java.policy | 2 + jdk/src/share/native/java/util/zip/Deflater.c | 37 +++++++ jdk/src/share/native/java/util/zip/Inflater.c | 98 +++++++++++++++++++ .../java/util/zip/DeflateIn_InflateOut.java | 74 +++++++++++++- 12 files changed, 367 insertions(+), 34 deletions(-) diff --git a/jdk/make/CompileLaunchers.gmk b/jdk/make/CompileLaunchers.gmk index de1ea9f4b..513e2ee1b 100644 --- a/jdk/make/CompileLaunchers.gmk +++ b/jdk/make/CompileLaunchers.gmk @@ -474,17 +474,29 @@ ifeq ($(USE_EXTERNAL_LIBZ), true) UNPACKEXE_ZIPOBJS := -lz else UNPACKEXE_CFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib - UNPACKEXE_ZIPOBJS := $(JDK_OUTPUTDIR)/objs/libzip/zcrc32$(OBJ_SUFFIX) \ - $(JDK_OUTPUTDIR)/objs/libzip/deflate$(OBJ_SUFFIX) \ - $(JDK_OUTPUTDIR)/objs/libzip/trees$(OBJ_SUFFIX) \ - $(JDK_OUTPUTDIR)/objs/libzip/zadler32$(OBJ_SUFFIX) \ - $(JDK_OUTPUTDIR)/objs/libzip/compress$(OBJ_SUFFIX) \ - $(JDK_OUTPUTDIR)/objs/libzip/zutil$(OBJ_SUFFIX) \ - $(JDK_OUTPUTDIR)/objs/libzip/inflate$(OBJ_SUFFIX) \ - $(JDK_OUTPUTDIR)/objs/libzip/infback$(OBJ_SUFFIX) \ - $(JDK_OUTPUTDIR)/objs/libzip/inftrees$(OBJ_SUFFIX) \ - $(JDK_OUTPUTDIR)/objs/libzip/inffast$(OBJ_SUFFIX) - + ifeq ($(OPENJDK_TARGET_OS), windows) + UNPACKEXE_ZIPOBJS := $(JDK_OUTPUTDIR)/objs/libzip/zcrc32$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libzip/deflate$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libzip/trees$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libzip/zadler32$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libzip/compress$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libzip/zutil$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libzip/inflate$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libzip/infback$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libzip/inftrees$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libzip/inffast$(OBJ_SUFFIX) + else + UNPACKEXE_ZIPOBJS := $(JDK_OUTPUTDIR)/objs/libz/zcrc32$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libz/deflate$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libz/trees$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libz/zadler32$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libz/compress$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libz/zutil$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libz/inflate$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libz/infback$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libz/inftrees$(OBJ_SUFFIX) \ + $(JDK_OUTPUTDIR)/objs/libz/inffast$(OBJ_SUFFIX) + endif endif UNPACKEXE_LANG := C diff --git a/jdk/make/lib/CoreLibraries.gmk b/jdk/make/lib/CoreLibraries.gmk index d1cd1d3de..1af991693 100644 --- a/jdk/make/lib/CoreLibraries.gmk +++ b/jdk/make/lib/CoreLibraries.gmk @@ -261,11 +261,76 @@ $(BUILD_LIBJAVA): $(BUILD_LIBFDLIBM) ########################################################################################## +ifneq ($(USE_EXTERNAL_LIBZ), true) + ifneq ($(OPENJDK_TARGET_OS), windows) + BUILD_LIBZ_EXCLUDES := + + ZLIB_CPPFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib + ifeq ($(OPENJDK_TARGET_OS), macosx) + ZLIB_CPPFLAGS += -DHAVE_UNISTD_H + endif + + BUILD_LIBZ_REORDER := + ifeq ($(OPENJDK_TARGET_OS), solaris) + ifneq ($(OPENJDK_TARGET_CPU), x86_64) + BUILD_LIBZ_REORDER := $(JDK_TOPDIR)/make/mapfiles/libzip/reorder-$(OPENJDK_TARGET_CPU) + endif + endif + + ifeq ($(LIBZ_CAN_USE_MMAP), true) + BUILD_LIBZ_MMAP := -DUSE_MMAP + endif + + $(eval $(call SetupNativeCompilation,BUILD_LIBZ, \ + LIBRARY := z, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + LANG := C, \ + OPTIMIZATION := LOW, \ + SRC := $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib, \ + EXCLUDES := $(LIBZ_EXCLUDES), \ + CFLAGS := $(CFLAGS_JDKLIB) \ + $(ZLIB_CPPFLAGS) \ + -I$(JDK_TOPDIR)/src/share/native/java/io \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/io, \ + CFLAGS_posix := $(BUILD_LIBZ_MMAP) -UDEBUG, \ + MAPFILE := , \ + REORDER := $(BUILD_LIBZ_REORDER), \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN) \ + $(EXPORT_Z_FUNCS), \ + LDFLAGS_windows := jvm.lib \ + $(WIN_JAVA_LIB), \ + LDFLAGS_SUFFIX_linux := , \ + LDFLAGS_SUFFIX_solaris := , \ + LDFLAGS_SUFFIX_aix := ,\ + LDFLAGS_SUFFIX_macosx := , \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=z.dll" \ + -D "JDK_INTERNAL_NAME=z" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libz, \ + DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) + + + $(BUILD_LIBZ): $(BUILD_LIBJAVA) + + BUILD_LIBRARIES += $(BUILD_LIBZ) + endif +endif + +########################################################################################## + BUILD_LIBZIP_EXCLUDES := ifeq ($(USE_EXTERNAL_LIBZ), true) + BUILD_LIBZIP_SRC := LIBZ := -lz LIBZIP_EXCLUDES += zlib else + ifneq ($(OPENJDK_TARGET_OS), windows) + BUILD_LIBZIP_SRC := Adler32.c CRC32.c Deflater.c Inflater.c zip_util.c ZipFile.c + LIBZ := -lz + endif ZLIB_CPPFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib ifeq ($(OPENJDK_TARGET_OS), macosx) ZLIB_CPPFLAGS += -DHAVE_UNISTD_H @@ -289,6 +354,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \ LANG := C, \ OPTIMIZATION := LOW, \ SRC := $(JDK_TOPDIR)/src/share/native/java/util/zip, \ + INCLUDE_FILES := $(BUILD_LIBZIP_SRC), \ EXCLUDES := $(LIBZIP_EXCLUDES), \ CFLAGS := $(CFLAGS_JDKLIB) \ $(ZLIB_CPPFLAGS) \ @@ -315,9 +381,14 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \ OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libzip, \ DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) +ifneq ($(USE_EXTERNAL_LIBZ), true) + LIBZ := +endif $(BUILD_LIBZIP): $(BUILD_LIBJAVA) +$(BUILD_LIBZIP): $(BUILD_LIBZ) + BUILD_LIBRARIES += $(BUILD_LIBZIP) ########################################################################################## diff --git a/jdk/make/mapfiles/libzip/mapfile-vers b/jdk/make/mapfiles/libzip/mapfile-vers index 5d33990c3..5c6d27d0d 100644 --- a/jdk/make/mapfiles/libzip/mapfile-vers +++ b/jdk/make/mapfiles/libzip/mapfile-vers @@ -38,13 +38,16 @@ SUNWprivate_1.1 { Java_java_util_zip_Deflater_end; Java_java_util_zip_Deflater_getAdler; Java_java_util_zip_Deflater_init; + Java_java_util_zip_Deflater_initKae; Java_java_util_zip_Deflater_initIDs; Java_java_util_zip_Deflater_reset; Java_java_util_zip_Deflater_setDictionary; Java_java_util_zip_Inflater_end; Java_java_util_zip_Inflater_getAdler; Java_java_util_zip_Inflater_inflateBytes; + Java_java_util_zip_Inflater_inflateBytesKAE; Java_java_util_zip_Inflater_init; + Java_java_util_zip_Inflater_initKae; Java_java_util_zip_Inflater_initIDs; Java_java_util_zip_Inflater_reset; Java_java_util_zip_Inflater_setDictionary; diff --git a/jdk/src/share/classes/java/util/zip/Deflater.java b/jdk/src/share/classes/java/util/zip/Deflater.java index bffa397d9..a4ea40cf8 100644 --- a/jdk/src/share/classes/java/util/zip/Deflater.java +++ b/jdk/src/share/classes/java/util/zip/Deflater.java @@ -81,6 +81,7 @@ class Deflater { private boolean finish, finished; private long bytesRead; private long bytesWritten; + private boolean defalterUseKae; /** * Compression method for the deflate algorithm (the only one currently @@ -168,7 +169,13 @@ class Deflater { public Deflater(int level, boolean nowrap) { this.level = level; this.strategy = DEFAULT_STRATEGY; - this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap)); + if (("true".equals(System.getProperty("GZIP_USE_KAE", "false"))) && + ("aarch64".equals(System.getProperty("os.arch")))) { + this.defalterUseKae = true; + } + this.zsRef = defalterUseKae ? + new ZStreamRef(initKae(level, DEFAULT_STRATEGY)) : + new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap)); } /** @@ -571,6 +578,7 @@ class Deflater { private static native void initIDs(); private native static long init(int level, int strategy, boolean nowrap); + private native static long initKae(int level, int strategy); private native static void setDictionary(long addr, byte[] b, int off, int len); private native int deflateBytes(long addr, byte[] b, int off, int len, int flush); diff --git a/jdk/src/share/classes/java/util/zip/GZIPInputStream.java b/jdk/src/share/classes/java/util/zip/GZIPInputStream.java index 0d57e8ab3..7fb753729 100644 --- a/jdk/src/share/classes/java/util/zip/GZIPInputStream.java +++ b/jdk/src/share/classes/java/util/zip/GZIPInputStream.java @@ -54,6 +54,11 @@ class GZIPInputStream extends InflaterInputStream { private boolean closed = false; + /* + * GZIP use KAE. + */ + private boolean gzipUseKae = false; + /** * Check to make sure that this stream has not been closed */ @@ -76,6 +81,12 @@ class GZIPInputStream extends InflaterInputStream { public GZIPInputStream(InputStream in, int size) throws IOException { super(in, new Inflater(true), size); usesDefaultInflater = true; + if (("true".equals(System.getProperty("GZIP_USE_KAE", "false"))) && + ("aarch64".equals(System.getProperty("os.arch")))) { + gzipUseKae = true; + } + // file header will be readed by kae zlib when use kae + if (gzipUseKae) return; readHeader(in); } @@ -209,6 +220,9 @@ class GZIPInputStream extends InflaterInputStream { * data set) */ private boolean readTrailer() throws IOException { + // file trailer will be readed by kae zlib when use kae + if (gzipUseKae) return true; + InputStream in = this.in; int n = inf.getRemaining(); if (n > 0) { diff --git a/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java b/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java index 1c3f8592e..0f0be98bb 100644 --- a/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java +++ b/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java @@ -52,6 +52,11 @@ class GZIPOutputStream extends DeflaterOutputStream { */ private final static int TRAILER_SIZE = 8; + /* + * GZIP use KAE. + */ + private boolean gzipUseKae = false; + /** * Creates a new output stream with the specified buffer size. * @@ -91,6 +96,12 @@ class GZIPOutputStream extends DeflaterOutputStream { size, syncFlush); usesDefaultDeflater = true; + if (("true".equals(System.getProperty("GZIP_USE_KAE", "false"))) && + ("aarch64".equals(System.getProperty("os.arch")))) { + gzipUseKae = true; + } + // file header will be writed by kae zlib when use kae + if (gzipUseKae) return; writeHeader(); crc.reset(); } @@ -160,6 +171,11 @@ class GZIPOutputStream extends DeflaterOutputStream { int len = def.deflate(buf, 0, buf.length); if (def.finished() && len <= buf.length - TRAILER_SIZE) { // last deflater buffer. Fit trailer at the end + // file trailer will be writed by kae zlib when use kae + if (gzipUseKae) { + out.write(buf, 0, len); + return; + } writeTrailer(buf, len); len = len + TRAILER_SIZE; out.write(buf, 0, len); @@ -168,6 +184,10 @@ class GZIPOutputStream extends DeflaterOutputStream { if (len > 0) out.write(buf, 0, len); } + // file trailer will be writed by kae zlib when use kae + if (gzipUseKae) { + return; + } // if we can't fit the trailer at the end of the last // deflater buffer, we write it separately byte[] trailer = new byte[TRAILER_SIZE]; diff --git a/jdk/src/share/classes/java/util/zip/Inflater.java b/jdk/src/share/classes/java/util/zip/Inflater.java index c1eefe122..42e90f525 100644 --- a/jdk/src/share/classes/java/util/zip/Inflater.java +++ b/jdk/src/share/classes/java/util/zip/Inflater.java @@ -80,6 +80,7 @@ class Inflater { private boolean needDict; private long bytesRead; private long bytesWritten; + private boolean inflaterUseKae; private static final byte[] defaultBuf = new byte[0]; @@ -100,7 +101,11 @@ class Inflater { * @param nowrap if true then support GZIP compatible compression */ public Inflater(boolean nowrap) { - zsRef = new ZStreamRef(init(nowrap)); + if (("true".equals(System.getProperty("GZIP_USE_KAE", "false"))) && + ("aarch64".equals(System.getProperty("os.arch")))) { + inflaterUseKae = true; + } + zsRef = inflaterUseKae ? new ZStreamRef(initKae()): new ZStreamRef(init(nowrap)); } /** @@ -256,7 +261,9 @@ class Inflater { synchronized (zsRef) { ensureOpen(); int thisLen = this.len; - int n = inflateBytes(zsRef.address(), b, off, len); + int n = this.inflaterUseKae ? + inflateBytesKAE(zsRef.address(), b, off, len) : + inflateBytes(zsRef.address(), b, off, len); bytesWritten += n; bytesRead += (thisLen - this.len); return n; @@ -397,10 +404,13 @@ class Inflater { private native static void initIDs(); private native static long init(boolean nowrap); + private native static long initKae(); private native static void setDictionary(long addr, byte[] b, int off, int len); private native int inflateBytes(long addr, byte[] b, int off, int len) throws DataFormatException; + private native int inflateBytesKAE(long addr, byte[] b, int off, int len) + throws DataFormatException; private native static int getAdler(long addr); private native static void reset(long addr); private native static void end(long addr); diff --git a/jdk/src/share/classes/java/util/zip/InflaterOutputStream.java b/jdk/src/share/classes/java/util/zip/InflaterOutputStream.java index 02900c741..62c6bb153 100644 --- a/jdk/src/share/classes/java/util/zip/InflaterOutputStream.java +++ b/jdk/src/share/classes/java/util/zip/InflaterOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2020, 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 @@ -236,16 +236,9 @@ public class InflaterOutputStream extends FilterOutputStream { // Fill the decompressor buffer with output data if (inf.needsInput()) { - int part; - - if (len < 1) { - break; - } - - part = (len < 512 ? len : 512); - inf.setInput(b, off, part); - off += part; - len -= part; + inf.setInput(b, off, len); + // Only use input buffer once. + len = 0; } // Decompress and write blocks of output data @@ -256,13 +249,14 @@ public class InflaterOutputStream extends FilterOutputStream { } } while (n > 0); - // Check the decompressor - if (inf.finished()) { - break; - } + // Check for missing dictionary first if (inf.needsDictionary()) { throw new ZipException("ZLIB dictionary missing"); } + // Check the decompressor + if (inf.finished() || (len == 0) /* no more input */ ) { + break; + } } } catch (DataFormatException ex) { // Improperly formatted compressed (ZIP) data diff --git a/jdk/src/share/lib/security/java.policy b/jdk/src/share/lib/security/java.policy index 8b6289720..baec2ea15 100644 --- a/jdk/src/share/lib/security/java.policy +++ b/jdk/src/share/lib/security/java.policy @@ -48,5 +48,7 @@ grant { permission java.util.PropertyPermission "java.vm.name", "read"; permission java.util.PropertyPermission "sun.security.pkcs11.disableKeyExtraction", "read"; + + permission java.util.PropertyPermission "GZIP_USE_KAE", "read"; }; diff --git a/jdk/src/share/native/java/util/zip/Deflater.c b/jdk/src/share/native/java/util/zip/Deflater.c index c1bd34667..1b048e4f5 100644 --- a/jdk/src/share/native/java/util/zip/Deflater.c +++ b/jdk/src/share/native/java/util/zip/Deflater.c @@ -37,6 +37,7 @@ #include "java_util_zip_Deflater.h" #define DEF_MEM_LEVEL 8 +#define KAE_DEFLATER_WindowBit 31 static jfieldID levelID; static jfieldID strategyID; @@ -104,6 +105,42 @@ Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level, } } +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_initKae(JNIEnv *env, jclass cls, jint level, + jint strategy) +{ + z_stream *strm = calloc(1, sizeof(z_stream)); + + if (strm == 0) { + JNU_ThrowOutOfMemoryError(env, 0); + return jlong_zero; + } else { + const char *msg; + int ret = deflateInit2(strm, level, Z_DEFLATED, KAE_DEFLATER_WindowBit, DEF_MEM_LEVEL, strategy); + switch (ret) { + case Z_OK: + return ptr_to_jlong(strm); + case Z_MEM_ERROR: + free(strm); + JNU_ThrowOutOfMemoryError(env, 0); + return jlong_zero; + case Z_STREAM_ERROR: + free(strm); + JNU_ThrowIllegalArgumentException(env, 0); + return jlong_zero; + default: + msg = ((strm->msg != NULL) ? strm->msg : + (ret == Z_VERSION_ERROR) ? + "zlib returned Z_VERSION_ERROR: " + "compile time and runtime zlib implementations differ" : + "unknown error initializing zlib library"); + free(strm); + JNU_ThrowInternalError(env, msg); + return jlong_zero; + } + } +} + JNIEXPORT void JNICALL Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, jarray b, jint off, jint len) diff --git a/jdk/src/share/native/java/util/zip/Inflater.c b/jdk/src/share/native/java/util/zip/Inflater.c index 79bcdd5b6..fca207215 100644 --- a/jdk/src/share/native/java/util/zip/Inflater.c +++ b/jdk/src/share/native/java/util/zip/Inflater.c @@ -41,6 +41,7 @@ #define ThrowDataFormatException(env, msg) \ JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg) +#define KAE_INFLATER_WindowBit 31 static jfieldID needDictID; static jfieldID finishedID; @@ -94,6 +95,39 @@ Java_java_util_zip_Inflater_init(JNIEnv *env, jclass cls, jboolean nowrap) } } +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_initKae(JNIEnv *env, jclass cls) +{ + z_stream *strm = calloc(1, sizeof(z_stream)); + + if (strm == NULL) { + JNU_ThrowOutOfMemoryError(env, 0); + return jlong_zero; + } else { + const char *msg; + int ret = inflateInit2(strm, KAE_INFLATER_WindowBit); + switch (ret) { + case Z_OK: + return ptr_to_jlong(strm); + case Z_MEM_ERROR: + free(strm); + JNU_ThrowOutOfMemoryError(env, 0); + return jlong_zero; + default: + msg = ((strm->msg != NULL) ? strm->msg : + (ret == Z_VERSION_ERROR) ? + "zlib returned Z_VERSION_ERROR: " + "compile time and runtime zlib implementations differ" : + (ret == Z_STREAM_ERROR) ? + "inflateInit2 returned Z_STREAM_ERROR" : + "unknown error initializing zlib library"); + free(strm); + JNU_ThrowInternalError(env, msg); + return jlong_zero; + } + } +} + JNIEXPORT void JNICALL Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, jarray b, jint off, jint len) @@ -181,6 +215,70 @@ Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr, } } +JNIEXPORT jint JNICALL +Java_java_util_zip_Inflater_inflateBytesKAE(JNIEnv *env, jobject this, jlong addr, + jarray b, jint off, jint len) +{ + z_stream *strm = jlong_to_ptr(addr); + jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID); + jint this_off = (*env)->GetIntField(env, this, offID); + jint this_len = (*env)->GetIntField(env, this, lenID); + + jbyte *in_buf; + jbyte *out_buf; + int ret; + + in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); + if (in_buf == NULL) { + if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0; + } + out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); + if (out_buf == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + if (len != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0; + } + strm->next_in = (Bytef *) (in_buf + this_off); + strm->next_out = (Bytef *) (out_buf + off); + strm->avail_in = this_len; + strm->avail_out = len; + ret = inflate(strm, Z_SYNC_FLUSH); + (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); + (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + + switch (ret) { + case Z_STREAM_END: + (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); + /* fall through */ + case Z_OK: + this_off += this_len - strm->avail_in; + (*env)->SetIntField(env, this, offID, this_off); + (*env)->SetIntField(env, this, lenID, strm->avail_in); + return (jint) (len - strm->avail_out); + case Z_NEED_DICT: + (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE); + /* Might have consumed some input here! */ + this_off += this_len - strm->avail_in; + (*env)->SetIntField(env, this, offID, this_off); + (*env)->SetIntField(env, this, lenID, strm->avail_in); + return 0; + case Z_BUF_ERROR: + return 0; + case Z_DATA_ERROR: + ThrowDataFormatException(env, strm->msg); + return 0; + case Z_MEM_ERROR: + JNU_ThrowOutOfMemoryError(env, 0); + return 0; + default: + JNU_ThrowInternalError(env, strm->msg); + return 0; + } +} + JNIEXPORT jint JNICALL Java_java_util_zip_Inflater_getAdler(JNIEnv *env, jclass cls, jlong addr) { diff --git a/jdk/test/java/util/zip/DeflateIn_InflateOut.java b/jdk/test/java/util/zip/DeflateIn_InflateOut.java index dd69a7773..048d8e34c 100644 --- a/jdk/test/java/util/zip/DeflateIn_InflateOut.java +++ b/jdk/test/java/util/zip/DeflateIn_InflateOut.java @@ -41,14 +41,31 @@ public class DeflateIn_InflateOut { private static ByteArrayOutputStream baos; private static InflaterOutputStream ios; - private static void reset() { + private static Inflater reset(byte[] dict) { new Random(new Date().getTime()).nextBytes(data); bais = new ByteArrayInputStream(data); - dis = new DeflaterInputStream(bais); + if (dict == null) { + dis = new DeflaterInputStream(bais); + } else { + Deflater def = new Deflater(); + def.setDictionary(dict); + dis = new DeflaterInputStream(bais, def); + } baos = new ByteArrayOutputStream(); - ios = new InflaterOutputStream(baos); + if (dict == null) { + ios = new InflaterOutputStream(baos); + return null; + } else { + Inflater inf = new Inflater(); + ios = new InflaterOutputStream(baos, inf); + return inf; + } + } + + private static void reset() { + reset(null); } /** Check byte arrays read/write. */ @@ -216,6 +233,44 @@ public class DeflateIn_InflateOut { check(numNotSkipped + numSkipBytes == numReadable); } + /** Check "needsDictionary()". */ + private static void NeedsDictionary() throws Throwable { + byte[] dict = {1, 2, 3, 4}; + Adler32 adler32 = new Adler32(); + adler32.update(dict); + long checksum = adler32.getValue(); + byte[] buf = new byte[512]; + + Inflater inf = reset(dict); + check(dis.available() == 1); + boolean dictSet = false; + for (;;) { + int len = dis.read(buf, 0, buf.length); + if (len < 0) { + break; + } else { + try { + ios.write(buf, 0, len); + if (dictSet == false) { + check(false, "Must throw ZipException without dictionary"); + return; + } + } catch (ZipException ze) { + check(dictSet == false, "Dictonary must be set only once"); + check(checksum == inf.getAdler(), "Incorrect dictionary"); + inf.setDictionary(dict); + // After setting the dictionary, we have to flush the + // InflaterOutputStream now in order to consume all the + // pending input data from the last, failed call to "write()". + ios.flush(); + dictSet = true; + } + } + } + check(dis.available() == 0); + ios.close(); + check(Arrays.equals(data, baos.toByteArray())); + } public static void realMain(String[] args) throws Throwable { ArrayReadWrite(); @@ -227,15 +282,24 @@ public class DeflateIn_InflateOut { ByteReadByteWrite(); SkipBytes(); + + NeedsDictionary(); } //--------------------- Infrastructure --------------------------- static volatile int passed = 0, failed = 0; static void pass() {passed++;} - static void fail() {failed++; Thread.dumpStack();} - static void fail(String msg) {System.out.println(msg); fail();} + static void fail() { fail(null); } + static void fail(String msg) { + failed++; + if (msg != null) { + System.err.println(msg); + } + Thread.dumpStack(); + } static void unexpected(Throwable t) {failed++; t.printStackTrace();} static void check(boolean cond) {if (cond) pass(); else fail();} + static void check(boolean cond, String msg) {if (cond) pass(); else fail(msg);} static void equal(Object x, Object y) { if (x == null ? y == null : x.equals(y)) pass(); else fail(x + " not equal to " + y);} -- 2.23.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2