Handle possible ArithmeticException when extending byte store for String#6670
Conversation
…h ArithmeticException and extend to Integer.MAX_VALUE if caught
|
Thanks for the PR! I will review. |
|
Looks good! I am playing with numbers around the threshold now and seeing the error exactly when the string size goes to Notice only the I think this is a case where we should also catch the Thank you! |
|
So step debugging through the The next step fails with the array-size heap error. It seems that the effective size of a Java byte[] is actually I will merge your PR and then open another to audit all places we allocate arrays in this way. |
|
I will merge this to master but then cherry-pick the change into 9.2 and do additional auditing and fixes there. We plan to maintain 9.2.x at least through the end of the year. |
|
Did you change the patch to be MAX_VALUE - 2? |
This also reduces the fallback maximum to Integer.MAX_VALUE - 2, which seems to be the actual effective size for allocating a new array. See jruby#6670.
|
@xaptronic I have started working on additional fixes, including the MAX - 2 change, in #6671. |
Based on explorations for jruby#6670 we found that the effective max array size is actually Integer.MAX_VALUE - 2, so this localizes the multiplication logic and uses that limit as the upper bound. $ jruby -w -e 'foo = "x" * 2147483645; p :ok' :ok $ jruby -w -e 'foo = "x" * 2147483646; p :ok' ArgumentError: argument too big * at org/jruby/RubyString.java:1197 <main> at -e:1
Based on explorations for jruby#6670 we found that the effective max array size is actually Integer.MAX_VALUE - 2, so this localizes the multiplication logic and uses that limit as the upper bound. $ jruby -w -e 'foo = "x" * 2147483645; p :ok' :ok $ jruby -w -e 'foo = "x" * 2147483646; p :ok' ArgumentError: argument too big * at org/jruby/RubyString.java:1197 <main> at -e:1

I have a JRuby application that writes data into a
StringIO. After a certain amount of data, the application throws a long winded exception with stack trace leading toByteList::ensurewith exceptionJava::JavaLang::NegativeArraySizeException.It appears that the code attempts to extend the byte arrray beyond
Integer.MAX_VALUElength which results in attempting to create abyte[]of negative length.Relevant portion of stacktrace:
This PR wraps the calculation in a try/catch and uses
Math.addExactto catch a potential ArithmeticException. In the even that is does, we set the new allocation size toInteger.MAX_VALUE.Retesting, I now get a more useful exception:
Java::JavaLang::OutOfMemoryError: Java heap space.