From 27bcbcc728434ffb2c45e81c0e75e6a3d6da3441 Mon Sep 17 00:00:00 2001 From: Sebastian Bazley Date: Sat, 9 Jun 2012 14:58:34 +0000 Subject: [PATCH] LANG-805 RandomStringUtils.random(count, 0, 0, false, false, universe, random) always throws java.lang.ArrayIndexOutOfBoundsException git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1348422 13f79535-47bb-0310-9956-ffa450edef68 --- src/changes/changes.xml | 1 + .../commons/lang3/RandomStringUtils.java | 29 ++++++++++++------- .../commons/lang3/RandomStringUtilsTest.java | 22 +++++++++++--- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index da5cd18fe..1aae92a6e 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -22,6 +22,7 @@ + RandomStringUtils.random(count, 0, 0, false, false, universe, random) always throws java.lang.ArrayIndexOutOfBoundsException LocaleUtils - unnecessary recursive call in SyncAvoid class. Javadoc bug in DateUtils#ceiling for Calendar and Object versions. Use generics in SerializationUtils diff --git a/src/main/java/org/apache/commons/lang3/RandomStringUtils.java b/src/main/java/org/apache/commons/lang3/RandomStringUtils.java index bded1540f..a79905754 100644 --- a/src/main/java/org/apache/commons/lang3/RandomStringUtils.java +++ b/src/main/java/org/apache/commons/lang3/RandomStringUtils.java @@ -211,13 +211,13 @@ public class RandomStringUtils { * @param end the position in set of chars to end before * @param letters only allow letters? * @param numbers only allow numbers? - * @param chars the set of chars to choose randoms from. + * @param chars the set of chars to choose randoms from, must not be empty. * If {@code null}, then it will use the set of all chars. * @param random a source of randomness. * @return the random string * @throws ArrayIndexOutOfBoundsException if there are not * {@code (end - start) + 1} characters in the set array. - * @throws IllegalArgumentException if {@code count} < 0. + * @throws IllegalArgumentException if {@code count} < 0 or the provided chars array is empty. * @since 2.0 */ public static String random(int count, int start, int end, boolean letters, boolean numbers, @@ -227,12 +227,20 @@ public class RandomStringUtils { } else if (count < 0) { throw new IllegalArgumentException("Requested random string length " + count + " is less than 0."); } + if (chars != null && chars.length == 0) { + throw new IllegalArgumentException("The chars array must not be empty"); + } + if (start == 0 && end == 0) { - end = 'z' + 1; - start = ' '; - if (!letters && !numbers) { - start = 0; - end = Integer.MAX_VALUE; + if (chars != null) { + end = chars.length; + } else { + if (!letters && !numbers) { + end = Integer.MAX_VALUE; + } else { + end = 'z' + 1; + start = ' '; + } } } @@ -285,13 +293,14 @@ public class RandomStringUtils { * specified.

* *

Characters will be chosen from the set of characters - * specified.

+ * specified by the string, must not be empty. + * If null, the set of all characters is used.

* * @param count the length of random string to create * @param chars the String containing the set of characters to use, - * may be null + * may be null, but must not be empty * @return the random string - * @throws IllegalArgumentException if {@code count} < 0. + * @throws IllegalArgumentException if {@code count} < 0 or the string is empty. */ public static String random(int count, String chars) { if (chars == null) { diff --git a/src/test/java/org/apache/commons/lang3/RandomStringUtilsTest.java b/src/test/java/org/apache/commons/lang3/RandomStringUtilsTest.java index 55ce99add..6c7b0c16d 100644 --- a/src/test/java/org/apache/commons/lang3/RandomStringUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/RandomStringUtilsTest.java @@ -123,9 +123,15 @@ public class RandomStringUtilsTest extends junit.framework.TestCase { r1 = RandomStringUtils.random(0); assertEquals("random(0).equals(\"\")", "", r1); - } + + public void testLANG805() { + long seed = System.currentTimeMillis(); + assertEquals("aaa", RandomStringUtils.random(3,0,0,false,false,new char[]{'a'},new Random(seed))); + } + public void testExceptions() { + final char[] DUMMY = new char[]{'a'}; // valid char array try { RandomStringUtils.random(-1); fail(); @@ -135,23 +141,31 @@ public class RandomStringUtilsTest extends junit.framework.TestCase { fail(); } catch (IllegalArgumentException ex) {} try { - RandomStringUtils.random(-1, new char[0]); + RandomStringUtils.random(-1, DUMMY); + fail(); + } catch (IllegalArgumentException ex) {} + try { + RandomStringUtils.random(1, new char[0]); // must not provide empty array => IAE fail(); } catch (IllegalArgumentException ex) {} try { RandomStringUtils.random(-1, ""); fail(); } catch (IllegalArgumentException ex) {} + try { + RandomStringUtils.random(-1, (String)null); + fail(); + } catch (IllegalArgumentException ex) {} try { RandomStringUtils.random(-1, 'a', 'z', false, false); fail(); } catch (IllegalArgumentException ex) {} try { - RandomStringUtils.random(-1, 'a', 'z', false, false, new char[0]); + RandomStringUtils.random(-1, 'a', 'z', false, false, DUMMY); fail(); } catch (IllegalArgumentException ex) {} try { - RandomStringUtils.random(-1, 'a', 'z', false, false, new char[0], new Random()); + RandomStringUtils.random(-1, 'a', 'z', false, false, DUMMY, new Random()); fail(); } catch (IllegalArgumentException ex) {} }