From 0adb7b318dd5d67559d5b31b1ef3280dd72e1f5f Mon Sep 17 00:00:00 2001
From: Elliott Hughes <enh@google.com>
Date: Fri, 16 Jul 2010 19:32:11 -0700
Subject: Fix a long-latent bug in the zip code, exposed by
 -Xjniopts:forcecopy.

We were using ScopedByteArrayRO to access a byte[] read-write, and accidentally
relying on the fact that normally the VM will give us a pointer to the actual
array. A C-style cast that cast away const hid this obvious bug from the
compiler, so this patch also removes all the other C-style casts from the zip
code.

Change-Id: I15b2175af7d089ddc86448f54219abef2a9ef8cd
---
 luni/src/main/native/java_util_zip_Adler32.cpp  |  4 ++--
 luni/src/main/native/java_util_zip_CRC32.cpp    |  4 ++--
 luni/src/main/native/java_util_zip_Deflater.cpp |  6 +++---
 luni/src/main/native/java_util_zip_Inflater.cpp |  4 ++--
 luni/src/main/native/zip.h                      | 15 ++++++++-------
 5 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/luni/src/main/native/java_util_zip_Adler32.cpp b/luni/src/main/native/java_util_zip_Adler32.cpp
index 60eef54..9873c8b 100644
--- a/luni/src/main/native/java_util_zip_Adler32.cpp
+++ b/luni/src/main/native/java_util_zip_Adler32.cpp
@@ -27,12 +27,12 @@ static jlong Adler32_updateImpl(JNIEnv* env, jobject, jbyteArray byteArray, int
     if (bytes.get() == NULL) {
         return 0;
     }
-    return adler32((uLong) crc, (Bytef *) (bytes.get() + off), (uInt) len);
+    return adler32(crc, reinterpret_cast<const Bytef*>(bytes.get() + off), len);
 }
 
 static jlong Adler32_updateByteImpl(JNIEnv*, jobject, jint val, jlong crc) {
     Bytef bytefVal = val;
-    return adler32((uLong) crc, (Bytef *) (&bytefVal), 1);
+    return adler32(crc, reinterpret_cast<const Bytef*>(&bytefVal), 1);
 }
 
 static JNINativeMethod gMethods[] = {
diff --git a/luni/src/main/native/java_util_zip_CRC32.cpp b/luni/src/main/native/java_util_zip_CRC32.cpp
index 197165e..b419188 100644
--- a/luni/src/main/native/java_util_zip_CRC32.cpp
+++ b/luni/src/main/native/java_util_zip_CRC32.cpp
@@ -27,12 +27,12 @@ static jlong CRC32_updateImpl(JNIEnv* env, jobject, jbyteArray byteArray, int of
     if (bytes.get() == NULL) {
         return 0;
     }
-    jlong result = crc32((uLong) crc, (Bytef *) (bytes.get() + off), (uInt) len);
+    jlong result = crc32(crc, reinterpret_cast<const Bytef*>(bytes.get() + off), len);
     return result;
 }
 
 static jlong CRC32_updateByteImpl(JNIEnv*, jobject, jbyte val, jlong crc) {
-    return crc32((uLong) crc, (Bytef *) (&val), 1);
+    return crc32(crc, reinterpret_cast<const Bytef*>(&val), 1);
 }
 
 static JNINativeMethod gMethods[] = {
diff --git a/luni/src/main/native/java_util_zip_Deflater.cpp b/luni/src/main/native/java_util_zip_Deflater.cpp
index 7255bcd..6d68bf1 100644
--- a/luni/src/main/native/java_util_zip_Deflater.cpp
+++ b/luni/src/main/native/java_util_zip_Deflater.cpp
@@ -80,11 +80,11 @@ static jint Deflater_deflateImpl(JNIEnv* env, jobject recv, jbyteArray buf, int
     stream->stream.avail_out = len;
     jint sin = stream->stream.total_in;
     jint sout = stream->stream.total_out;
-    ScopedByteArrayRO out(env, buf);
+    ScopedByteArrayRW out(env, buf);
     if (out.get() == NULL) {
         return -1;
     }
-    stream->stream.next_out = (Bytef *) out.get() + off;
+    stream->stream.next_out = reinterpret_cast<Bytef*>(out.get() + off);
     int err = deflate(&stream->stream, flushParm);
     if (err != Z_OK) {
         if (err == Z_MEM_ERROR) {
@@ -124,7 +124,7 @@ static void Deflater_setLevelsImpl(JNIEnv* env, jobject, int level, int strategy
     }
     NativeZipStream* stream = toNativeZipStream(handle);
     jbyte b = 0;
-    stream->stream.next_out = (Bytef*) &b;
+    stream->stream.next_out = reinterpret_cast<Bytef*>(&b);
     int err = deflateParams(&stream->stream, level, strategy);
     if (err != Z_OK) {
         throwExceptionForZlibError(env, "java/lang/IllegalStateException", err);
diff --git a/luni/src/main/native/java_util_zip_Inflater.cpp b/luni/src/main/native/java_util_zip_Inflater.cpp
index 29afbbb..ddf494e 100644
--- a/luni/src/main/native/java_util_zip_Inflater.cpp
+++ b/luni/src/main/native/java_util_zip_Inflater.cpp
@@ -105,11 +105,11 @@ static jint Inflater_inflateImpl(JNIEnv* env, jobject recv, jbyteArray buf, int
     stream->stream.avail_out = len;
     jint sin = stream->stream.total_in;
     jint sout = stream->stream.total_out;
-    ScopedByteArrayRO out(env, buf);
+    ScopedByteArrayRW out(env, buf);
     if (out.get() == NULL) {
         return -1;
     }
-    stream->stream.next_out = (Bytef *) out.get() + off;
+    stream->stream.next_out = reinterpret_cast<Bytef*>(out.get() + off);
     int err = inflate(&stream->stream, Z_SYNC_FLUSH);
     if (err != Z_OK) {
         if (err == Z_STREAM_ERROR) {
diff --git a/luni/src/main/native/zip.h b/luni/src/main/native/zip.h
index 634e7ed..9909d44 100644
--- a/luni/src/main/native/zip.h
+++ b/luni/src/main/native/zip.h
@@ -48,24 +48,25 @@ public:
     ~NativeZipStream() {
     }
 
-    void setDictionary(JNIEnv* env, jbyteArray dict, int off, int len, bool inflate) {
-        UniquePtr<jbyte[]> dBytes(new jbyte[len]);
-        if (dBytes.get() == NULL) {
+    void setDictionary(JNIEnv* env, jbyteArray javaDictionary, int off, int len, bool inflate) {
+        UniquePtr<jbyte[]> dictionaryBytes(new jbyte[len]);
+        if (dictionaryBytes.get() == NULL) {
             jniThrowOutOfMemoryError(env, NULL);
             return;
         }
-        env->GetByteArrayRegion(dict, off, len, &dBytes[0]);
+        env->GetByteArrayRegion(javaDictionary, off, len, &dictionaryBytes[0]);
+        const Bytef* dictionary = reinterpret_cast<const Bytef*>(&dictionaryBytes[0]);
         int err;
         if (inflate) {
-            err = inflateSetDictionary(&stream, (Bytef *) &dBytes[0], len);
+            err = inflateSetDictionary(&stream, dictionary, len);
         } else {
-            err = deflateSetDictionary(&stream, (Bytef *) &dBytes[0], len);
+            err = deflateSetDictionary(&stream, dictionary, len);
         }
         if (err != Z_OK) {
             throwExceptionForZlibError(env, "java/lang/IllegalArgumentException", err);
             return;
         }
-        mDict.reset(dBytes.release());
+        mDict.reset(dictionaryBytes.release());
     }
 
     void setInput(JNIEnv* env, jbyteArray buf, jint off, jint len) {
-- 
cgit v1.1