Return-Path: X-Original-To: apmail-commons-issues-archive@minotaur.apache.org Delivered-To: apmail-commons-issues-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id DE2F897E6 for ; Wed, 11 Jul 2012 09:50:36 +0000 (UTC) Received: (qmail 91639 invoked by uid 500); 11 Jul 2012 09:50:36 -0000 Delivered-To: apmail-commons-issues-archive@commons.apache.org Received: (qmail 91267 invoked by uid 500); 11 Jul 2012 09:50:36 -0000 Mailing-List: contact issues-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: issues@commons.apache.org Delivered-To: mailing list issues@commons.apache.org Received: (qmail 91213 invoked by uid 99); 11 Jul 2012 09:50:35 -0000 Received: from issues-vm.apache.org (HELO issues-vm) (140.211.11.160) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 11 Jul 2012 09:50:35 +0000 Received: from isssues-vm.apache.org (localhost [127.0.0.1]) by issues-vm (Postfix) with ESMTP id EFC00142856 for ; Wed, 11 Jul 2012 09:50:34 +0000 (UTC) Date: Wed, 11 Jul 2012 09:50:34 +0000 (UTC) From: "Krzysztof Nazarewski (JIRA)" To: issues@commons.apache.org Message-ID: <1703632520.34429.1342000234984.JavaMail.jiratomcat@issues-vm> In-Reply-To: <1293948079.17813.1341626794829.JavaMail.jiratomcat@issues-vm> Subject: [jira] [Comment Edited] (LANG-810) StringUtils.join() endIndex, bugged for loop MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 [ https://issues.apache.org/jira/browse/LANG-810?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13411325#comment-13411325 ] Krzysztof Nazarewski edited comment on LANG-810 at 7/11/12 9:49 AM: -------------------------------------------------------------------- Basically {{endIndex}} takes values from 1 to array.length instead of from 0 to {{(array.length - 1)}} In current state {{endIndex}} is "1-based index", not "0-based index" while Java language uses 0-based indexes, also previous argument {{startIndex}} is 0-based. If you put valid endIndex 0, the for loop won't run at all as it checks (i < endIndex) like it was array's length. Let's say you have 1 element array to join (it does not make practical sense, bu should work), it has index 0 and does not have anything beyond 0 index. According to JavaDoc only possible combination of startIndex and endIndex would be (0,0). {{StringUtils.java, line 3394: for (int i = startIndex; i < endIndex; i++) {}} However for loop will not execute even single time because {{(i = startIndex = 0)}} is not lower than {{(endIndex = 0)}}, it is equal to endIndex and the result of joining single element array from it's only index 0 to index 0 will be empty string. Therefore to join that one-element array you need to use combination {{(startIndex = 0, endIndex = 1)}}, where {{(endIndex == array.length)}} is error according to JavaDoc: "endIndex - the index to stop joining from (exclusive). *It is an error to pass in an end index past the end of the array*" Example code: {code:title="test.java"} import org.apache.commons.lang3.StringUtils; public class Test { public static void main(String[] args) { String[] array = new String[] { "0", "1", "2", "3" }; printResult(array, 0, 0); printResult(array, 0, 1); printResult(array, 1, 1); printResult(array, 2, 3); printResult(array, 0, 3); printResult(array, 0, 4); } public static void printResult(String[] array, int startIndex, int endIndex) { String str = StringUtils.join(array, " ", startIndex, endIndex); System.out.println("Running:\tStringUtils.join(array, \" \", " + startIndex + ", " + endIndex + ");"); System.out.println("Result: \t" + str); System.out.println("array[" + startIndex + "]:\t'" + array[startIndex] + '\''); System.out.println("array[" + endIndex + "]:\t'" + array[endIndex] + '\''); System.out.println(); } } {code} Now tell me what is wrong with the code, because result is: {code} Running: StringUtils.join(array, " ", 0, 0); Result: array[0]: '0' array[0]: '0' Running: StringUtils.join(array, " ", 0, 1); Result: 0 array[0]: '0' array[1]: '1' Running: StringUtils.join(array, " ", 1, 1); Result: array[1]: '1' array[1]: '1' Running: StringUtils.join(array, " ", 2, 3); Result: 2 array[2]: '2' array[3]: '3' Running: StringUtils.join(array, " ", 0, 3); Result: 0 1 2 array[0]: '0' array[3]: '3' Running: StringUtils.join(array, " ", 0, 4); Result: 0 1 2 3 array[0]: '0' Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4 at Test.printResult(Test.java:20) at Test.main(Test.java:12) {code} Oh so came up that starting from line 3387: {code} int noOfItems = endIndex - startIndex; if (noOfItems <= 0) { return EMPTY; } {code} should be: {code} int noOfItems = endIndex - startIndex + 1; if (noOfItems <= 0) { return EMPTY; } {code} because joining one element should return that one exact element, not an empty string. was (Author: drag0nius): Basically {{endIndex}} takes values from 1 to array.length instead of from 0 to {{(array.length - 1)}} In current state {{endIndex}} is "1-based index", not "0-based index" while Java language uses 0-based indexes, also previous argument {{startIndex}} is 0-based. If you put valid endIndex 0, the for loop won't run at all as it checks (i < endIndex) like it was array's length. Let's say you have 1 element array to join (it does not make practical sense, bu should work), it has index 0 and does not have anything beyond 0 index. According to JavaDoc only possible combination of startIndex and endIndex would be (0,0). {{StringUtils.java, line 3394: for (int i = startIndex; i < endIndex; i++) {}} However for loop will not execute even single time because {{(i = startIndex = 0)}} is not lower than {{(endIndex = 0)}}, it is equal to endIndex and the result of joining single element array from it's only index 0 to index 0 will be empty string. Therefore to join that one-element array you need to use combination {{(startIndex = 0, endIndex = 1)}}, where {{(endIndex == array.length)}} is error according to JavaDoc: "endIndex - the index to stop joining from (exclusive). *It is an error to pass in an end index past the end of the array*" Example code: {code:title="test.java"} import org.apache.commons.lang3.StringUtils; public class Test { public static void main(String[] args) { String[] array = new String[] { "0", "1", "2", "3" }; printResult(array, 0, 0); printResult(array, 0, 1); printResult(array, 1, 1); printResult(array, 2, 3); printResult(array, 0, 3); printResult(array, 0, 4); } public static void printResult(String[] array, int startIndex, int endIndex) { String str = StringUtils.join(array, " ", startIndex, endIndex); System.out.println("Running:\tStringUtils.join(array, \" \", " + startIndex + ", " + endIndex + ");"); System.out.println("Result: \t" + str); System.out.println("array[" + startIndex + "]:\t'" + array[startIndex] + '\''); System.out.println("array[" + endIndex + "]:\t'" + array[endIndex] + '\''); System.out.println(); } } {code} Now tell me what is wrong with the code, because result is: {code} Running: StringUtils.join(array, " ", 0, 0); Result: array[0]: '0' array[0]: '0' Running: StringUtils.join(array, " ", 0, 1); Result: 0 array[0]: '0' array[1]: '1' Running: StringUtils.join(array, " ", 1, 1); Result: array[1]: '1' array[1]: '1' Running: StringUtils.join(array, " ", 2, 3); Result: 2 array[2]: '2' array[3]: '3' Running: StringUtils.join(array, " ", 0, 3); Result: 0 1 2 array[0]: '0' array[3]: '3' Running: StringUtils.join(array, " ", 0, 4); Result: 0 1 2 3 array[0]: '0' Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4 at Test.printResult(Test.java:20) at Test.main(Test.java:12) {code} Oh so came up that starting from line 3387: {code} int noOfItems = endIndex - startIndex; if (noOfItems <= 0) { return EMPTY; } {code} should be: {code} int noOfItems = endIndex - startIndex + 1; if (noOfItems <= 0) { return EMPTY; } {code} because joining one element should return that one exact element, not an empty string. > StringUtils.join() endIndex, bugged for loop > -------------------------------------------- > > Key: LANG-810 > URL: https://issues.apache.org/jira/browse/LANG-810 > Project: Commons Lang > Issue Type: Bug > Components: lang.* > Affects Versions: 3.1 > Reporter: Krzysztof Nazarewski > Assignee: Joerg Schaible > Original Estimate: 1m > Remaining Estimate: 1m > > endIndex is described as index, but for loop still checks it as "array length". > Basically missing equal sign > commons-lang3-3.1-sources.jar, StringUtils.java lines 3309, 3394: > for (int i = startIndex; i < endIndex; i++) { > should be: > for (int i = startIndex; i <= endIndex; i++) { -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa For more information on JIRA, see: http://www.atlassian.com/software/jira