From 62a580f52db5cbf5acdc24756aafcb5628eb947f Mon Sep 17 00:00:00 2001 From: Olivier Bourgain Date: Fri, 3 Nov 2017 15:32:54 +0100 Subject: [PATCH] Revert the behavior of DelimitedLineTokenizer to pre-4 DelimitedLineTokenizer was refactored to improve its performance but its behavior was also slightly changed. When the input is an empty csv string with double quotes, e.g. the java String line = "\"\""; the tokenizer returns the same String, whereas before it was returning an empty string. This is due to the condition checking for quotes to remove not stripping the double quotes from the empty csv string (because its length is 2 and the code check for strictly greater than 2). The previous code is there https://github.com/spring-projects/spring-batch/blob/973fe44d6caf353c271cc896b3f996d1a2c4bf93/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizer.java#L202 and checking for double quotes at the start and end of the string without special handling for the empty string. At test is also added to ensure this won't break again. Resolves BATCH-2657 --- .../batch/item/file/transform/DelimitedLineTokenizer.java | 2 +- .../item/file/transform/DelimitedLineTokenizerTests.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizer.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizer.java index c4af0ffc9..da532470e 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizer.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizer.java @@ -222,7 +222,7 @@ public class DelimitedLineTokenizer extends AbstractLineTokenizer String value; - if ((chars.length > 2) && (chars[start] == quoteCharacter) && (chars[start + len - 1] == quoteCharacter)) { + if ((chars.length >= 2) && (chars[start] == quoteCharacter) && (chars[start + len - 1] == quoteCharacter)) { value = new String(chars, start + 1, len - 2); if (value.contains(escapedQuoteString)) { value = StringUtils.replace(value, escapedQuoteString, quoteString); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizerTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizerTests.java index f10cd6761..72b192e57 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizerTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/transform/DelimitedLineTokenizerTests.java @@ -52,6 +52,12 @@ public class DelimitedLineTokenizerTests { assertTrue(TOKEN_MATCHES, tokens.readString(0).equals("")); } + @Test + public void testEmptyString() { + FieldSet tokens = tokenizer.tokenize("\"\""); + assertTrue(TOKEN_MATCHES, tokens.readString(0).equals("")); + } + @Test public void testInvalidConstructorArgument() { try {