OSDN Git Service

Treat larger than jint capacity in NewDirectByteBuffer as an error
authorBrian Carlstrom <bdc@google.com>
Wed, 25 Jun 2014 06:36:28 +0000 (23:36 -0700)
committerBrian Carlstrom <bdc@google.com>
Wed, 25 Jun 2014 08:44:33 +0000 (01:44 -0700)
Bug: 15854028
Change-Id: If78921f4ba2b38a9d0bb421acf9c8bca962ed42a

runtime/check_jni.cc
runtime/jni_internal.cc
runtime/jni_internal_test.cc

index a816489..fefb907 100644 (file)
@@ -1757,9 +1757,7 @@ PRIMITIVE_ARRAY_FUNCTIONS(jdouble, Double, 'D');
     CHECK_JNI_ENTRY(kFlag_Default, "EpJ", env, address, capacity);
     if (address == nullptr) {
       JniAbortF(__FUNCTION__, "non-nullable address is NULL");
-    }
-    if (capacity < 0) {
-      JniAbortF(__FUNCTION__, "capacity must be non-negative: %" PRId64, capacity);
+      return nullptr;
     }
     return CHECK_JNI_EXIT("L", baseEnv(env)->NewDirectByteBuffer(env, address, capacity));
   }
index 513b409..2fadfb0 100644 (file)
@@ -2447,13 +2447,18 @@ class JNI {
   static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
     if (capacity < 0) {
       JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64, capacity);
+      return nullptr;
     }
     if (address == nullptr && capacity != 0) {
       JniAbortF("NewDirectByteBuffer", "non-zero capacity for nullptr pointer: %" PRId64, capacity);
+      return nullptr;
     }
 
-    // At the moment, the capacity is limited to 32 bits.
-    CHECK_LE(capacity, 0xffffffff);
+    // At the moment, the capacity is limited to a jint (31 bits).
+    if (capacity > INT_MAX) {
+      JniAbortF("NewDirectByteBuffer", "buffer capacity greater than maximum jint: %" PRId64, capacity);
+      return nullptr;
+    }
     jlong address_arg = reinterpret_cast<jlong>(address);
     jint capacity_arg = static_cast<jint>(capacity);
 
index 5e46c57..218ae95 100644 (file)
@@ -1515,6 +1515,12 @@ TEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCa
   ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class));
   ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes);
   ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes)));
+
+  {
+    CheckJniAbortCatcher check_jni_abort_catcher;
+    env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) * 2);
+    check_jni_abort_catcher.Check("in call to NewDirectByteBuffer");
+  }
 }
 
 TEST_F(JniInternalTest, MonitorEnterExit) {
@@ -1568,7 +1574,6 @@ TEST_F(JniInternalTest, MonitorEnterExit) {
     CheckJniAbortCatcher check_jni_abort_catcher;
     env_->MonitorEnter(nullptr);
     check_jni_abort_catcher.Check("in call to MonitorEnter");
-
     env_->MonitorExit(nullptr);
     check_jni_abort_catcher.Check("in call to MonitorExit");
   }