Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StringIndexOutOfBounds in help when command has too many (and long) aliases #1870

Closed
martlin2cz opened this issue Nov 11, 2022 · 5 comments
Closed
Labels
theme: usagehelp An issue or change related to the usage help message type: bug 🐛
Milestone

Comments

@martlin2cz
Copy link

Hello,

I have a command with several aliases, and they are "long", like so:

@Command(name = "import-from-excel", 
          aliases = { "import-from-xls", "import-from-xlsx", "import-from-csv", "import-from-txt" },
          description = "Imports the data from various excel files (xls, xlsx, csv or even txt).")
public class ImportCommand implements Runnable {

    @Parameters(arity = "1..*")
    public List<File> files;
    
    @Override
    public void run() {
        System.out.println("ImportCommand.run()");    
    }

}

When I use it as a subcommand and trigger help on that supercommand (either by using the HelpCommand or via the usageHelp, picocli fails with following stack trace:

java.lang.IndexOutOfBoundsException: start 0, end -10, length 71
	at java.base/java.lang.AbstractStringBuilder.checkRange(AbstractStringBuilder.java:1802)
	at java.base/java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:680)
	at java.base/java.lang.StringBuilder.append(StringBuilder.java:218)
	at picocli.CommandLine$Help$Ansi$Text.getStyledChars(CommandLine.java:17646)
	at picocli.CommandLine$Help$TextTable.copy(CommandLine.java:16791)
	at picocli.CommandLine$Help$TextTable.copy(CommandLine.java:16780)
	at picocli.CommandLine$Help$TextTable.putValue(CommandLine.java:16742)
	at picocli.CommandLine$Help$TextTable.addRowValues(CommandLine.java:16674)
	at picocli.CommandLine$Help.commandList(CommandLine.java:15811)
	at picocli.CommandLine$Help.commandList(CommandLine.java:15788)
	at picocli.CommandLine$Model$UsageMessageSpec$15.render(CommandLine.java:7793)
	at picocli.CommandLine.usage(CommandLine.java:2673)
	at picocli.CommandLine.usage(CommandLine.java:2651)
	at picocli.CommandLine$HelpCommand.run(CommandLine.java:14755)
	at picocli.CommandLine.executeUserObject(CommandLine.java:1939)
	at picocli.CommandLine.executeHelpRequest(CommandLine.java:1929)
	at picocli.CommandLine.executeHelpRequest(CommandLine.java:1909)
	at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2176)
	at picocli.CommandLine.execute(CommandLine.java:2078)
	at cz.martlin.picoclifailuresample.MyPicocliMain.main(MyPicocliMain.java:14)

It all seems it's trying to fit all the alliases on one help line, but overflowing that line. If I remove the last alias, it outputs really narrow column with the description:

Usage: my [-h] [COMMAND]
  -h, --help
Commands:
  import-from-excel, import-from-xls, import-from-xlsx, import-from-csv  Imports
                                                                            the
                                                                           data
                                                                           from
                                                                           vario
                                                                           us
                                                                           excel

                                                                           files

                                                                           (xls,

                                                                           xlsx,
                                                                            csv
                                                                           or
                                                                           even
                                                                           txt).
  help                                                                   Display
                                                                           s
                                                                           help
                                                                           infor
                                                                           matio
                                                                           n
                                                                           about
                                                                            the
                                                                           speci
                                                                           fied
                                                                           comma
                                                                           nd

Could it be fixed please?

@remkop remkop added type: bug 🐛 theme: usagehelp An issue or change related to the usage help message labels Nov 15, 2022
@remkop
Copy link
Owner

remkop commented Nov 15, 2022

Nice catch! 👍
My time to work on picocli is extremely limited these days.
Will you be able to provide a pull request for this?

@martlin2cz
Copy link
Author

Huh, it seems I won't be able to try to fix that.

There's even a question what should be a solution. Let it overflow? Wrap the line?

@remkop
Copy link
Owner

remkop commented Dec 8, 2022

Picocli’s table component supports both of these options, so try both and see which result you like better.

@martlin2cz
Copy link
Author

Huh, I'm sorry, I wasn't even able to manage my clone to build. It's not a high priority thing, it can wait , maybe a few months.

@remkop remkop added this to the 4.7.1 milestone Jan 25, 2023
@remkop
Copy link
Owner

remkop commented Jan 25, 2023

I have a fix, will commit shortly

Index: src/main/java/picocli/CommandLine.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/picocli/CommandLine.java b/src/main/java/picocli/CommandLine.java
--- a/src/main/java/picocli/CommandLine.java	(date 1674625453185)
+++ b/src/main/java/picocli/CommandLine.java	(date 1674625453185)
@@ -16340,7 +16340,8 @@
          * @since 4.4 */
         public String commandList(Map<String, Help> subcommands) {
             if (subcommands.isEmpty()) { return ""; }
-            int commandLength = maxLength(subcommands.keySet());
+            int maxCommandLength = width() * 2 / 3;
+            int commandLength = Math.min(maxLength(subcommands.keySet()), maxCommandLength);
             Help.TextTable textTable = Help.TextTable.forColumns(colorScheme().ansi(),
                     new Help.Column(commandLength + 2, 2, Help.Column.Overflow.SPAN),
                     new Help.Column(width() - (commandLength + 2), 2, Help.Column.Overflow.WRAP));

test
java/picocli/HelpSubCommandTest.java

    @Test
    public void testIssue1870StringIndexOutOfBounds() {
        @Command(name = "top", subcommands = ImportCommand.class) class Top { }
        String actual = usageString(new CommandLine(new Top()), Help.Ansi.OFF);
        String expected = String.format("" +
            "Usage: top [COMMAND]%n" +
            "Commands:%n" +
            "  import-from-excel, import-from-xls, import-from-xlsx, import-from-csv,%n" +
            "    import-from-txt%n" +
            "                                            Imports the data from various excel%n" +
            "                                              files (xls, xlsx, csv or even%n" +
            "                                              txt).%n");
        assertEquals(expected, actual);
    }

@remkop remkop closed this as completed in 3c3c670 Jan 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: usagehelp An issue or change related to the usage help message type: bug 🐛
Projects
None yet
Development

No branches or pull requests

2 participants