Skip to content

Commit

Permalink
remkop#148 Fix infinite loop when word is too large for column
Browse files Browse the repository at this point in the history
Splits the word naively at the column boundary.
  • Loading branch information
Alex Abbott committed Jul 19, 2017
1 parent 11f2a58 commit feabd69
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/main/java/picocli/CommandLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -3040,6 +3040,10 @@ private int copy(BreakIterator line, Text text, Text columnValue, int offset) {
break;
}
}
if (done == 0 && length(text) > columnValue.maxLength) {
// The value is a single word that is too big to be written to the column. Write as much as we can.
done = copy(text, columnValue, offset);
}
return done;
}
private static int copy(Text value, Text destination, int offset) {
Expand Down
28 changes: 28 additions & 0 deletions src/test/java/picocli/CommandLineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
Expand Down Expand Up @@ -2774,4 +2775,31 @@ class App {
assertFalse(app.objectTrue);
assertTrue(app.objectNull);
}

@Test(timeout = 15000)
public void testIssue148InfiniteLoop() throws Exception {
@Command(showDefaultValues = true)
class App {
@Option(names = "--foo-bar-baz")
String foo = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
// Default value needs to be at least 1 character larger than the "WRAP" column in TextTable(Ansi), which is
// currently 51 characters. Going with 81 to be safe.
}

ByteArrayOutputStream output = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(output);
CommandLine.usage(new App(), printStream);

String content = new String(output.toByteArray(), "UTF-8")
.replaceAll("\r\n", "\n"); // Normalize line endings.

String expectedOutput =
"Usage: <main class> [--foo-bar-baz=<foo>]\n" +
" --foo-bar-baz=<foo> Default:\n" +
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" +
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" +
"\n";

assertEquals(expectedOutput, content);
}
}

0 comments on commit feabd69

Please sign in to comment.