2023-05-03 11:06:20 +02:00
== Why is this an issue?
2023-07-14 14:37:59 +02:00
There are various `String` operations that take one or more character indexes as arguments and return a portion of the original string.
Indexing in this context is zero-based, meaning that the first character's index is `0`.
As a result, given a string `myString`, its last character is at index `myString.length() - 1`.
2021-04-28 16:49:39 +02:00
2023-07-14 14:37:59 +02:00
The `String` operation methods throw a `StringIndexOutOfBoundsException` when one of their index argument is smaller than 0 (E.G.: -1).
`String::substring` also throws this exception when the `beginIndex` or `endIndex` argument is larger than `myString.length()`, and
`String::charAt` when the `index` argument is larger than `myString.length() - 1`
For instance, it is not possible to use `String::charAt` to retrieve a value before the start or after the end of a string.
Furthermore, it is not possible to use `String::substring` with `beginIndex > endIndex` to reverse the order of characters in a string.
2021-04-28 16:49:39 +02:00
2023-07-14 14:37:59 +02:00
This rule raises an issue when a negative literal or an index that is too large is passed as an argument to the `String::substring`, `String::charAt`, and related methods.
It also raises an issue when the start index passed to `String::substring` is larger than the end index.
2021-04-28 16:49:39 +02:00
2021-04-28 18:08:03 +02:00
2023-07-14 14:37:59 +02:00
== How to fix it
2021-04-28 16:49:39 +02:00
2023-07-14 14:37:59 +02:00
Use non-negative indexes that are smaller than or equal to the length of the string in question with `String::substring` and strictly smaller with `String::charAt`.
=== Code examples
==== Noncompliant code example
[source,java,diff-id=1,diff-type=noncompliant]
2021-04-28 16:49:39 +02:00
----
2023-07-14 14:37:59 +02:00
String speech = "Lorem ipsum dolor sit amet";
2021-04-28 16:49:39 +02:00
2023-07-14 14:37:59 +02:00
String substr1 = speech.substring(-1, speech.length()); // Noncompliant, -1 is out of bounds
String substr2 = speech.substring(speech.length(), 0); // Noncompliant, the beginIndex must be smaller than or equal to the endIndex
char ch = speech.charAt(speech.length()); // Noncompliant, speech.length() is out of bounds
2021-04-28 16:49:39 +02:00
----
2021-04-28 18:08:03 +02:00
2023-07-14 14:37:59 +02:00
==== Compliant solution
2021-04-28 16:49:39 +02:00
2023-07-14 14:37:59 +02:00
[source,java,diff-id=1,diff-type=compliant]
2021-04-28 16:49:39 +02:00
----
2023-07-14 14:37:59 +02:00
String speech = "Lorem ipsum dolor sit amet";
2021-04-28 16:49:39 +02:00
2023-07-14 14:37:59 +02:00
String substr1 = speech; // Compliant, no string operation used
String substr2 = new StringBuilder(speech).reverse().toString(); // Compliant, the string can be reversed using StringBuilder::reverse()
char ch = speech.charAt(speech.length() - 1); // Compliant, speech.length() - 1 is in bounds.
2021-04-28 16:49:39 +02:00
----
2021-04-28 18:08:03 +02:00
2021-06-02 20:44:38 +02:00
2021-06-03 09:05:38 +02:00
ifdef::env-github,rspecator-view[]
2021-09-20 15:38:42 +02:00
'''
== Implementation Specification
(visible only on this page)
2023-05-25 14:18:12 +02:00
=== Message
Refactor this "[substring|charAt]" call; it will result in an "StringIndexOutOfBounds" exception at runtime.
2021-09-20 15:38:42 +02:00
2021-06-08 15:52:13 +02:00
'''
2021-06-02 20:44:38 +02:00
== Comments And Links
(visible only on this page)
2023-05-25 14:18:12 +02:00
=== relates to: S2121
2021-06-03 09:05:38 +02:00
endif::env-github,rspecator-view[]