Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java byte array max size check before copying long-sized data from jni bridge #3849

Closed
azagrebin opened this issue May 14, 2018 · 5 comments
Closed
Assignees
Labels

Comments

@azagrebin
Copy link
Contributor

azagrebin commented May 14, 2018

This issue partially addresses #2383.

When user merges a lot of data into one value, its size might grow indefinitely.
When user gets the value as byte[] in java client, its actual merged size might exceed the JVM limitation for returned java array size.

Currently size of java array is calculated just by explicit cast of underlying size_t of value:

const jsize jlen = static_cast<jsize>(bytes.size());

The problem is that if bytes.size() exceeds java 32b int, it leads to overflow of jlen which might be even negative. The result can be an unclear NegativeArraySizeException/ArrayIndexOutOfBoundsException at the user side.

The suggestion is to check the size overflow and throw more clear RocksDBException with problem description:

static jbyteArray createJavaByteArrayWithSizeCheck(JNIEnv* env, const char* bytes, const size_t size) {
      // Limitation for array size is vm specific
      // Current HotSpot VM limitation for array size is Integer.MAX_VALUE - 5 (2^31 - 1 - 5)
      // Integer.MAX_VALUE - 8 should be safe enough
      static const size_t MAX_JARRAY_SIZE = ((static_cast<size_t>(1)) << 31) - 9;
      if (size > MAX_JARRAY_SIZE) {
        rocksdb::RocksDBExceptionJni::ThrowNew(env, "Requested array size exceeds VM limit");
        return nullptr;
      }
      // return normal result
}
@adamretter
Copy link
Collaborator

I agree that the error should be as clear as possible, but I wonder if if is not more appropriate to throw a ArrayIndexOutOfBoundsException with your error message, rather than a RocksDBException? The problem is really a bounds issue IMHO.

@azagrebin
Copy link
Contributor Author

azagrebin commented May 15, 2018

thanks @adamretter, I can change PR to use ArrayIndexOutOfBoundsException. There are just some thoughts behind current PR I wanted to share.

My thinking was inspired by java OutOfMemoryError which could be also an option:

public class Foo {
   public static void main(String[] args) {
     byte[] array = new byte[Integer.MAX_VALUE];
   }
 }
$ javac Foo.java ; java Foo
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
	at Foo.main(Foo.java:3)

I used RocksDBException because the check and error come from RocksDB jni API but not from JVM.

@adamretter
Copy link
Collaborator

@azagrebin Okay I can understand your thinking. A couple of further comments:

  1. I don't think that using OutOfMemoryError here would be appropriate. We have not in-fact run out of memory, quite the opposite, we are protecting against it.

  2. After further consideration, I think I am inclined to agree that a RocksDBException is more appropriate. As the arguments provided to the various functions that use copyBytes are in fact themselves valid. Rather it is a limitation of RocksJava that we cannot access keys or values of a size more than 32bits.

facebook-github-bot pushed a commit that referenced this issue Jun 29, 2018
…ni (#3850)

Summary:
to address issue #3849
Closes #3850

Differential Revision: D8695487

Pulled By: sagar0

fbshipit-source-id: 04baeb2127663934ed1321fe6d9a9ec23c86e16b
sagar0 pushed a commit that referenced this issue Jun 30, 2018
…ni (#3850)

Summary:
to address issue #3849
Closes #3850

Differential Revision: D8695487

Pulled By: sagar0

fbshipit-source-id: 04baeb2127663934ed1321fe6d9a9ec23c86e16b
@azagrebin
Copy link
Contributor Author

@adamretter
I think last PR addressed the issue. I guess we can close the issue?

@adamretter
Copy link
Collaborator

Closed by #3850

rcane pushed a commit to rcane/rocksdb that referenced this issue Sep 13, 2018
…ni (facebook#3850)

Summary:
to address issue facebook#3849
Closes facebook#3850

Differential Revision: D8695487

Pulled By: sagar0

fbshipit-source-id: 04baeb2127663934ed1321fe6d9a9ec23c86e16b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants