(#) Outside Range !!! ERROR: Outside Range This is an error. Id : `Range` Summary : Outside Range Severity : Error Category : Correctness Platform : Any Vendor : Android Open Source Project Feedback : https://issuetracker.google.com/issues/new?component=192708 Since : 3.1.0 (March 2018) Affects : Kotlin and Java files Editing : This check runs on the fly in the IDE editor Implementation : [Source Code](https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/RangeDetector.kt) Tests : [Source Code](https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/RangeDetectorTest.kt) Some parameters are required to be in a particular numerical range; this check makes sure that arguments passed fall within the range. For arrays, Strings and collections this refers to the size or length. (##) Example Here is an example of lint warnings produced by this check: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~text src/test/pkg/RangeTest.java:32:Error: Expected length 5 (was 4) [Range] printExact("1234"); // ERROR ------ src/test/pkg/RangeTest.java:34:Error: Expected length 5 (was 6) [Range] printExact("123456"); // ERROR -------- src/test/pkg/RangeTest.java:36:Error: Expected length ≥ 5 (was 4) [Range] printMin("1234"); // ERROR ------ src/test/pkg/RangeTest.java:43:Error: Expected length ≤ 8 (was 9) [Range] printMax("123456789"); // ERROR ----------- src/test/pkg/RangeTest.java:45:Error: Expected length ≥ 4 (was 3) [Range] printRange("123"); // ERROR ----- src/test/pkg/RangeTest.java:49:Error: Expected length ≤ 6 (was 7) [Range] printRange("1234567"); // ERROR --------- src/test/pkg/RangeTest.java:53:Error: Expected size 5 (was 4) [Range] printExact(new int[]{1, 2, 3, 4}); // ERROR --------------------- src/test/pkg/RangeTest.java:55:Error: Expected size 5 (was 6) [Range] printExact(new int[]{1, 2, 3, 4, 5, 6}); // ERROR --------------------------- src/test/pkg/RangeTest.java:57:Error: Expected size ≥ 5 (was 4) [Range] printMin(new int[]{1, 2, 3, 4}); // ERROR --------------------- src/test/pkg/RangeTest.java:65:Error: Expected size ≤ 8 (was 9) [Range] printMax(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9}); // ERROR ------------------------------------ src/test/pkg/RangeTest.java:67:Error: Expected size ≥ 4 (was 3) [Range] printRange(new int[] {1,2,3}); // ERROR ----------------- src/test/pkg/RangeTest.java:71:Error: Expected size ≤ 6 (was 7) [Range] printRange(new int[] {1,2,3,4,5,6,7}); // ERROR ------------------------- src/test/pkg/RangeTest.java:74:Error: Expected size to be a multiple of 3 (was 4 and should be either 3 or 6) [Range] printMultiple(new int[] {1,2,3,4}); // ERROR ------------------- src/test/pkg/RangeTest.java:75:Error: Expected size to be a multiple of 3 (was 5 and should be either 3 or 6) [Range] printMultiple(new int[] {1,2,3,4,5}); // ERROR --------------------- src/test/pkg/RangeTest.java:77:Error: Expected size to be a multiple of 3 (was 7 and should be either 6 or 9) [Range] printMultiple(new int[] {1,2,3,4,5,6,7}); // ERROR ------------------------- src/test/pkg/RangeTest.java:80:Error: Expected size ≥ 4 (was 3) [Range] printMinMultiple(new int[]{1, 2, 3}); // ERROR ------------------ src/test/pkg/RangeTest.java:84:Error: Value must be ≥ 4 (was 3) [Range] printAtLeast(3); // ERROR - src/test/pkg/RangeTest.java:91:Error: Value must be ≤ 7 (was 8) [Range] printAtMost(8); // ERROR - src/test/pkg/RangeTest.java:93:Error: Value must be ≥ 4 (was 3) [Range] printBetween(3); // ERROR - src/test/pkg/RangeTest.java:98:Error: Value must be ≤ 7 (was 8) [Range] printBetween(8); // ERROR - src/test/pkg/RangeTest.java:102:Error: Value must be ≥ 2.5 (was 2.49) [Range] printAtLeastInclusive(2.49f); // ERROR ----- src/test/pkg/RangeTest.java:106:Error: Value must be > 2.5 (was 2.49) [Range] printAtLeastExclusive(2.49f); // ERROR ----- src/test/pkg/RangeTest.java:107:Error: Value must be > 2.5 (was 2.5) [Range] printAtLeastExclusive(2.5f); // ERROR ---- src/test/pkg/RangeTest.java:113:Error: Value must be ≤ 7.0 (was 7.1) [Range] printAtMostInclusive(7.1f); // ERROR ---- src/test/pkg/RangeTest.java:117:Error: Value must be < 7.0 (was 7.0) [Range] printAtMostExclusive(7.0f); // ERROR ---- src/test/pkg/RangeTest.java:118:Error: Value must be < 7.0 (was 7.1) [Range] printAtMostExclusive(7.1f); // ERROR ---- src/test/pkg/RangeTest.java:120:Error: Value must be ≥ 2.5 (was 2.4) [Range] printBetweenFromInclusiveToInclusive(2.4f); // ERROR ---- src/test/pkg/RangeTest.java:124:Error: Value must be ≤ 5.0 (was 5.1) [Range] printBetweenFromInclusiveToInclusive(5.1f); // ERROR ---- src/test/pkg/RangeTest.java:126:Error: Value must be > 2.5 (was 2.4) [Range] printBetweenFromExclusiveToInclusive(2.4f); // ERROR ---- src/test/pkg/RangeTest.java:127:Error: Value must be > 2.5 (was 2.5) [Range] printBetweenFromExclusiveToInclusive(2.5f); // ERROR ---- src/test/pkg/RangeTest.java:129:Error: Value must be ≤ 5.0 (was 5.1) [Range] printBetweenFromExclusiveToInclusive(5.1f); // ERROR ---- src/test/pkg/RangeTest.java:131:Error: Value must be ≥ 2.5 (was 2.4) [Range] printBetweenFromInclusiveToExclusive(2.4f); // ERROR ---- src/test/pkg/RangeTest.java:135:Error: Value must be < 5.0 (was 5.0) [Range] printBetweenFromInclusiveToExclusive(5.0f); // ERROR ---- src/test/pkg/RangeTest.java:137:Error: Value must be > 2.5 (was 2.4) [Range] printBetweenFromExclusiveToExclusive(2.4f); // ERROR ---- src/test/pkg/RangeTest.java:138:Error: Value must be > 2.5 (was 2.5) [Range] printBetweenFromExclusiveToExclusive(2.5f); // ERROR ---- src/test/pkg/RangeTest.java:141:Error: Value must be < 5.0 (was 5.0) [Range] printBetweenFromExclusiveToExclusive(5.0f); // ERROR ---- src/test/pkg/RangeTest.java:145:Error: Value must be ≥ 4 (was -7) [Range] printBetween(-7); // ERROR -- src/test/pkg/RangeTest.java:146:Error: Value must be > 2.5 (was -10.0) [Range] printAtLeastExclusive(-10.0f); // ERROR ------ src/test/pkg/RangeTest.java:156:Error: Value must be ≥ -1 (was -2) [Range] printIndirect(-2); // ERROR -- src/test/pkg/RangeTest.java:157:Error: Value must be ≤ 42 (was 43) [Range] printIndirect(43); // ERROR -- src/test/pkg/RangeTest.java:158:Error: Expected length 5 (was 7) [Range] printIndirectSize("1234567"); // ERROR --------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here is the source file referenced above: `src/test/pkg/RangeTest.java`: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~java linenumbers package test.pkg; import androidx.annotation.FloatRange; import androidx.annotation.IntRange; import androidx.annotation.Size; @SuppressWarnings({"UnusedDeclaration", "ClassNameDiffersFromFileName", "MethodMayBeStatic"}) public class RangeTest { public void printExact(@Size(5) String arg) { System.out.println(arg); } public void printMin(@Size(min=5) String arg) { } public void printMax(@Size(max=8) String arg) { } public void printRange(@Size(min=4,max=6) String arg) { } public void printExact(@Size(5) int[] arg) { } public void printMin(@Size(min=5) int[] arg) { } public void printMax(@Size(max=8) int[] arg) { } public void printRange(@Size(min=4,max=6) int[] arg) { } public void printMultiple(@Size(multiple=3) int[] arg) { } public void printMinMultiple(@Size(min=4,multiple=3) int[] arg) { } public void printAtLeast(@IntRange(from=4) int arg) { } public void printAtMost(@IntRange(to=7) int arg) { } public void printBetween(@IntRange(from=4,to=7) int arg) { } public void printAtLeastInclusive(@FloatRange(from=2.5) float arg) { } public void printAtLeastExclusive(@FloatRange(from=2.5,fromInclusive=false) float arg) { } public void printAtMostInclusive(@FloatRange(to=7) double arg) { } public void printAtMostExclusive(@FloatRange(to=7,toInclusive=false) double arg) { } public void printBetweenFromInclusiveToInclusive(@FloatRange(from=2.5,to=5.0) float arg) { } public void printBetweenFromExclusiveToInclusive(@FloatRange(from=2.5,to=5.0,fromInclusive=false) float arg) { } public void printBetweenFromInclusiveToExclusive(@FloatRange(from=2.5,to=5.0,toInclusive=false) float arg) { } public void printBetweenFromExclusiveToExclusive(@FloatRange(from=2.5,to=5.0,fromInclusive=false,toInclusive=false) float arg) { } public void testLength() { printExact("1234"); // ERROR printExact("12345"); // OK printExact("123456"); // ERROR printMin("1234"); // ERROR printMin("12345"); // OK printMin("123456"); // OK printMax("123456"); // OK printMax("1234567"); // OK printMax("12345678"); // OK printMax("123456789"); // ERROR printRange("123"); // ERROR printRange("1234"); // OK printRange("12345"); // OK printRange("123456"); // OK printRange("1234567"); // ERROR } public void testSize() { printExact(new int[]{1, 2, 3, 4}); // ERROR printExact(new int[]{1, 2, 3, 4, 5}); // OK printExact(new int[]{1, 2, 3, 4, 5, 6}); // ERROR printMin(new int[]{1, 2, 3, 4}); // ERROR printMin(new int[]{1, 2, 3, 4, 5}); // OK printMin(new int[]{1, 2, 3, 4, 5, 6}); // OK printMax(new int[]{1, 2, 3, 4, 5, 6}); // OK printMax(new int[]{1, 2, 3, 4, 5, 6, 7}); // OK printMax(new int[]{1, 2, 3, 4, 5, 6, 7, 8}); // OK printMax(new int[]{1, 2, 3, 4, 5, 6, 7, 8}); // OK printMax(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9}); // ERROR printRange(new int[] {1,2,3}); // ERROR printRange(new int[] {1,2,3,4}); // OK printRange(new int[] {1,2,3,4,5}); // OK printRange(new int[] {1,2,3,4,5,6}); // OK printRange(new int[] {1,2,3,4,5,6,7}); // ERROR printMultiple(new int[] {1,2,3}); // OK printMultiple(new int[] {1,2,3,4}); // ERROR printMultiple(new int[] {1,2,3,4,5}); // ERROR printMultiple(new int[] {1,2,3,4,5,6}); // OK printMultiple(new int[] {1,2,3,4,5,6,7}); // ERROR printMinMultiple(new int[] {1,2,3,4,5,6}); // OK printMinMultiple(new int[]{1, 2, 3}); // ERROR } public void testIntRange() { printAtLeast(3); // ERROR printAtLeast(4); // OK printAtLeast(5); // OK printAtMost(5); // OK printAtMost(6); // OK printAtMost(7); // OK printAtMost(8); // ERROR printBetween(3); // ERROR printBetween(4); // OK printBetween(5); // OK printBetween(6); // OK printBetween(7); // OK printBetween(8); // ERROR } public void testFloatRange() { printAtLeastInclusive(2.49f); // ERROR printAtLeastInclusive(2.5f); // OK printAtLeastInclusive(2.6f); // OK printAtLeastExclusive(2.49f); // ERROR printAtLeastExclusive(2.5f); // ERROR printAtLeastExclusive(2.501f); // OK printAtMostInclusive(6.8f); // OK printAtMostInclusive(6.9f); // OK printAtMostInclusive(7.0f); // OK printAtMostInclusive(7.1f); // ERROR printAtMostExclusive(6.9f); // OK printAtMostExclusive(6.99f); // OK printAtMostExclusive(7.0f); // ERROR printAtMostExclusive(7.1f); // ERROR printBetweenFromInclusiveToInclusive(2.4f); // ERROR printBetweenFromInclusiveToInclusive(2.5f); // OK printBetweenFromInclusiveToInclusive(3f); // OK printBetweenFromInclusiveToInclusive(5.0f); // OK printBetweenFromInclusiveToInclusive(5.1f); // ERROR printBetweenFromExclusiveToInclusive(2.4f); // ERROR printBetweenFromExclusiveToInclusive(2.5f); // ERROR printBetweenFromExclusiveToInclusive(5.0f); // OK printBetweenFromExclusiveToInclusive(5.1f); // ERROR printBetweenFromInclusiveToExclusive(2.4f); // ERROR printBetweenFromInclusiveToExclusive(2.5f); // OK printBetweenFromInclusiveToExclusive(3f); // OK printBetweenFromInclusiveToExclusive(4.99f); // OK printBetweenFromInclusiveToExclusive(5.0f); // ERROR printBetweenFromExclusiveToExclusive(2.4f); // ERROR printBetweenFromExclusiveToExclusive(2.5f); // ERROR printBetweenFromExclusiveToExclusive(2.51f); // OK printBetweenFromExclusiveToExclusive(4.99f); // OK printBetweenFromExclusiveToExclusive(5.0f); // ERROR } public void testNegative() { printBetween(-7); // ERROR printAtLeastExclusive(-10.0f); // ERROR } public static final int MINIMUM = -1; public static final int MAXIMUM = 42; public void printIndirect(@IntRange(from = MINIMUM, to = MAXIMUM) int arg) { } public static final int SIZE = 5; public static void printIndirectSize(@Size(SIZE) String foo) { } public void testIndirect() { printIndirect(-2); // ERROR printIndirect(43); // ERROR printIndirectSize("1234567"); // ERROR } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can also visit the [source code](https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/RangeDetectorTest.kt) for the unit tests for this check to see additional scenarios. The above example was automatically extracted from the first unit test found for this lint check, `RangeDetector.testRange`. To report a problem with this extracted sample, visit https://issuetracker.google.com/issues/new?component=192708. (##) Suppressing You can suppress false positives using one of the following mechanisms: * Using a suppression annotation like this on the enclosing element: ```kt // Kotlin @Suppress("Range") fun method() { problematicStatement() } ``` or ```java // Java @SuppressWarnings("Range") void method() { problematicStatement(); } ``` * Using a suppression comment like this on the line above: ```kt //noinspection Range problematicStatement() ``` * Using a special `lint.xml` file in the source tree which turns off the check in that folder and any sub folder. A simple file might look like this: ```xml <?xml version="1.0" encoding="UTF-8"?> <lint> <issue id="Range" severity="ignore" /> </lint> ``` Instead of `ignore` you can also change the severity here, for example from `error` to `warning`. You can find additional documentation on how to filter issues by path, regular expression and so on [here](https://googlesamples.github.io/android-custom-lint-rules/usage/lintxml.md.html). * In Gradle projects, using the DSL syntax to configure lint. For example, you can use something like ```gradle lintOptions { disable 'Range' } ``` In Android projects this should be nested inside an `android { }` block. * For manual invocations of `lint`, using the `--ignore` flag: ``` $ lint --ignore Range ...` ``` * Last, but not least, using baselines, as discussed [here](https://googlesamples.github.io/android-custom-lint-rules/usage/baselines.md.html).