frohoff/ysoserial · error · IllegalArgumentException
Bad command format.
Error message
Bad command format.
What it means
ysoserial's Wicket1 payload generator throws this IllegalArgumentException from getObject() when the command string does not split into exactly 3 ';'-separated parts. The Wicket1 DiskFileItem gadget requires a command of the form '<operation>;<arg1>;<arg2>', so any other shape is rejected before dispatch.
Solutions
- Supply exactly three semicolon-separated fields: operation, arg1, arg2 (e.g. 'copyAndDelete;/tmp/source;/tmp/dest' or 'write;/tmp/target;content').
- Check the command for stray/missing semicolons; escape-free ';' characters must number exactly two.
- Pick a supported operation name as parts[0]: 'copyAndDelete', 'write', 'writeOld', or 'writeOldB64' (see error 21 for unknown ops).
Example fix
// before String command = "write /tmp/x hello"; DiskFileItem item = new Wicket1().getObject(command); // after String command = "write;/tmp/x;hello"; DiskFileItem item = new Wicket1().getObject(command);
Defensive patterns
Strategy: validation
Validate before calling
public static void validateWicket1Command(String command) {
if (command == null || command.split(";", -1).length != 3) {
throw new IllegalArgumentException("Wicket1 command must be 'op;arg1;arg2' (exactly 3 parts): " + command);
}
} Type guard
public static boolean isValidWicket1Command(String command) {
return command != null && command.split(";", -1).length == 3;
} Try / catch
try {
DiskFileItem item = new Wicket1().getObject(command);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Bad command format")) {
System.err.println("Command must have exactly 3 ';'-separated parts: 'op;arg1;arg2'");
} else {
throw e;
}
} Prevention
- Always format Wicket1 commands as 'operation;arg1;arg2' with exactly two semicolons.
- Write a small helper that builds the command string from an op enum plus two args instead of hand-concatenating.
- Trim user-supplied input and reject null/empty commands before calling getObject().
When it happens
Trigger: Calling new Wicket1().getObject(command) with a command that yields parts.length != 3 after command.split(";"), e.g. 'write' alone, 'copyAndDelete;file' (only 2 parts), or a string containing no semicolons at all.
Common situations: Users forget the semicolon-delimited format when configuring the payload, pass a path containing no separator but omit the second argument, or copy a command from another ysoserial payload with a different argument format.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of frohoff/ysoserial@218bcffcaa (2026-09-12).
Data as JSON: /api/errors/e29863ad49eee70f.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/ysoserial/payloads/Wicket1.java:59
* Wicket1 "write;/tmp;blue lobster"
*
* Result:
* $ ls -l /tmp/
* -rw-rw-r-- 1 albino_lobster albino_lobster 12 Jul 25 14:10 upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp
* $ cat /tmp/upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp
* blue lobster
*/
@PayloadTest(harness="ysoserial.test.payloads.FileUploadTest", flaky="possible race condition")
@Dependencies({"org.apache.wicket:wicket-util:6.23.0", "org.slf4j:slf4j-api:1.6.4"})
@Authors({ Authors.JACOBAINES })
public class Wicket1 implements ReleaseableObjectPayload<DiskFileItem> {
public DiskFileItem getObject(String command) throws Exception {
String[] parts = command.split(";");
if (parts.length != 3) {
throw new IllegalArgumentException("Bad command format.");
}
if ("copyAndDelete".equals(parts[0])) {
return copyAndDelete(parts[1], parts[2]);
}
else if ("write".equals(parts[0])) {
return write(parts[1], parts[2].getBytes("US-ASCII"));
}
else if ("writeB64".equals(parts[0]) ) {
return write(parts[1], Base64.decodeBase64(parts[2]));
}
else if ("writeOld".equals(parts[0]) ) {
return writeOldJRE(parts[1], parts[2].getBytes("US-ASCII"));
}
else if ("writeOldB64".equals(parts[0]) ) {
return writeOldJRE(parts[1], Base64.decodeBase64(parts[2]));
}
throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(parts));View on GitHub (pinned to 218bcffcaa)