Repository: AFLplusplus/LibAFL (language: rust)

Issue:
CommandExecutor input not being provided to fuzzer if only `arg_input_arg()` was called 
**Describe the bug**
```rust
// command.rs
            InputLocation::Arg { argnum } => {
                let args = self.command.get_args();
...
                for (i, arg) in args.enumerate() { 
                    if i == *argnum {
                        debug_assert_eq!(arg, "DUMMY");
                        #[cfg(unix)]
                        cmd.arg(OsStr::from_bytes(input.target_bytes().as_slice()));
                        // There is an issue here that the chars on Windows are 16 bit wide.
                        // I can't really test it. Please open a PR if this goes wrong.
                        #[cfg(not(unix))]
                        cmd.arg(OsString::from_vec(input.target_bytes().as_vec()));
                    } else {
                        cmd.arg(arg);
                    }
                }
```
Because `arg_input_arg()` function doesn't actually add anything to command args, args size remains the same.
If you only have that one argument (as fuzzer input) and nothing else, then args will be empty and the input won't be provided to target when fuzzing:
```rust
CommandExecutor::builder()
        .program("CMD")
        .arg_input_arg()
        .arg("DUMMY") // <-- you need this!!!
        .build(...)
        .unwrap();
```

**To Reproduce**
Steps to reproduce the behavior:
1. Try fuzzing `echo` using this setup and pass a string as argument. Argument will not be passed.

**Expected behavior**
It should work without using dummy value (or at least write this in doc!!!)

CommandExecutor input not being provided to fuzzer if only `arg_input_arg()` was called 
**Describe the bug**
```rust
// command.rs
            InputLocation::Arg { argnum } => {
                let args = self.command.get_args();
...
                for (i, arg) in args.enumerate() { 
                    if i == *argnum {
                        debug_assert_eq!(arg, "DUMMY");
                        #[cfg(unix)]
                        cmd.arg(OsStr::from_bytes(input.target_bytes().as_slice()));
                        // There is an issue here that the chars on Windows are 16 bit wide.
                        // I can't really test it. Please open a PR if this goes wrong.
                        #[cfg(not(unix))]
                        cmd.arg(OsString::from_vec(input.target_bytes().as_vec()));
                    } else {
                        cmd.arg(arg);
                    }
                }
```
Because `arg_input_arg()` function doesn't actually add anything to command args, args size remains the same.
If you only have that one argument (as fuzzer input) and nothing else, then args will be empty and the input won't be provided to target when fuzzing:
```rust
CommandExecutor::builder()
        .program("CMD")
        .arg_input_arg()
        .arg("DUMMY") // <-- you need this!!!
        .build(...)
        .unwrap();
```

**To Reproduce**
Steps to reproduce the behavior:
1. Try fuzzing `echo` using this setup and pass a string as argument. Argument will not be passed.

**Expected behavior**
It should work without using dummy value (or at least write this in doc!!!)



Discussion / hints:
@tokatoka you commented out the placeholder arg here:
https://github.com/AFLplusplus/LibAFL/blame/173a9ad8eab4e9ea6e39a3b2cf40f18ad90943e3/libafl/src/executors/command.rs#L382
In PR #2167

Do you remember why? 
Can we un-comment it?
i don't remember anymore
i think i didn't understand the point of that DUMMY and deleted it by mistake. 
you can put it back
@tokatoka you commented out the placeholder arg here:
https://github.com/AFLplusplus/LibAFL/blame/173a9ad8eab4e9ea6e39a3b2cf40f18ad90943e3/libafl/src/executors/command.rs#L382
In PR #2167

Do you remember why? 
Can we un-comment it?
i don't remember anymore
i think i didn't understand the point of that DUMMY and deleted it by mistake. 
you can put it back

Fix patch:
diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs
index 5854414f8d..72a87d05c8 100644
--- a/libafl/src/executors/command.rs
+++ b/libafl/src/executors/command.rs
@@ -105,7 +105,7 @@ where
 
                 for (i, arg) in args.enumerate() {
                     if i == *argnum {
-                        debug_assert_eq!(arg, "DUMMY");
+                        debug_assert_eq!(arg, "PLACEHOLDER");
                         #[cfg(unix)]
                         cmd.arg(OsStr::from_bytes(input.target_bytes().as_slice()));
                         // There is an issue here that the chars on Windows are 16 bit wide.
@@ -379,7 +379,8 @@ impl CommandExecutorBuilder {
     pub fn arg_input_arg(&mut self) -> &mut Self {
         let argnum = self.args.len();
         self.input(InputLocation::Arg { argnum });
-        // self.arg("DUMMY");
+        // Placeholder arg that gets replaced with the input name later.
+        self.arg("PLACEHOLDER");
         self
     }
 
diff --git a/libafl/src/observers/concolic/serialization_format.rs b/libafl/src/observers/concolic/serialization_format.rs
index a72213a05e..72735bb702 100644
--- a/libafl/src/observers/concolic/serialization_format.rs
+++ b/libafl/src/observers/concolic/serialization_format.rs
@@ -242,7 +242,7 @@ impl<W: Write + Seek> MessageFileWriter<W> {
     /// Create a `MessageFileWriter` from the given [`Write`].
     pub fn from_writer(mut writer: W) -> io::Result<Self> {
         let writer_start_position = writer.stream_position()?;
-        // write dummy trace length
+        // write preliminary trace length
         writer.write_all(&0_u64.to_le_bytes())?;
         Ok(Self {
             id_counter: 1,


Test patch: