JDK-8221307 : String.substring() OOB exception on start index reports improper information
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 8,11,12,13
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2019-03-21
  • Updated: 2020-02-13
  • Resolved: 2019-08-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 14
14 b11Fixed
Related Reports
Duplicate :  
Description
A DESCRIPTION OF THE PROBLEM :
This is an intentional duplicate of https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8151242 whose purpose is to object to the resolution.

For one, "String index out of range (-2)" is a difficult to decipher error message - when you do `y.substring(x)`, if x > y.length() one would expect the error message to resolve to "String index out of range (x)", not "String index out of range (-x + y.length())". Additionally, it is inconsistent with, e.g., y.charAt(x), which would give you "String index out of range (x)". 

There is no indication that the substring error message is reporting the length of the substring, as the comment in the resolution implies; thus, any developer would expect the error message to report one of the indices supplied to the substring method directly as the problematic index. Additionally, if one is substituting a more difficult expression than just a number for x, it becomes much more difficult to use the error message to debug.

Another issue is, if you take an example like `"foo".substring(4)`, you get "String index out of bounds (-1)", which is indistinguishable from, e.g., `"foo".substring("foo".indexOf("bar"))`.

The resolution to this problem is very simple as well: you should be able to just pass the `beginIndex` into the exception. If you wish to continue reporting the negative numbers, there should be some sort of explanation in the exception, otherwise no one who encounters this exception would understand why they're getting an exception with an index number less than -1 (or equal to -1 when their substring isn't passing in -1). At the very least, there should be some indication in the javadoc; users should not have to find the afore-linked bug report to understand what their StringIndexOutOfBounds exception is doing.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the following in any main method:

System.out.println("foo".substring(4));

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
	at java.lang.String.substring(String.java:1931)
ACTUAL -
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
	at java.lang.String.substring(String.java:1931)

---------- BEGIN SOURCE ----------
public class test {
  public static void main(String[] args) {
    System.out.println("foo".substring(4));
  }
}
---------- END SOURCE ----------

FREQUENCY : always



Comments
URL: https://hg.openjdk.java.net/jdk/jdk/rev/a0257f1458aa User: igerasim Date: 2019-08-16 18:36:12 +0000
16-08-2019

I agree that the error message should be improved. For reference, if "foo".substring(4,5) is invoked, the error message looks more meaningful: java.lang.StringIndexOutOfBoundsException: begin 4, end 5, length 3
27-06-2019