]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Improve newline handling on Windows (#2115)
authorTobias Stoeckmann <stoeckmann@users.noreply.github.com>
Sat, 13 Apr 2024 05:40:02 +0000 (05:40 +0000)
committerGitHub <noreply@github.com>
Sat, 13 Apr 2024 05:40:02 +0000 (22:40 -0700)
If libarchive is compiled on Windows without cygwin, strip \r and \n the
same way as it is done on POSIX systems.

Also, entering an empty password as "\r\n" should lead to an empty
string. Right now, the newlines are kept.

Proof of Concept:

1. Compile libarchive with Visual Studio
2. Create a password-protected ZIP file
```
PS> bsdtar.exe --format zip --options 'zip:encryption' -cf archive.zip input.txt
Enter passphrase: <press enter>
```
3. Extract ZIP file on Windows
```
PS> bsdtar.exe -xf archive.zip
Enter passphrase: <press enter>
```
4. Extract ZIP file on Linux
```
$ bsdtar -xf archive.zip
Enter passphrase: <press enter>
Enter passphrase:
```

As can be seen in step 4, it is impossible to extract the file on Linux
with interactive input, because \r and \n are stripped.
The only way to extract the content is through command line option
passphrase:
```
$ bsdtar -xf archive.zip --passphrase $'\r\n'
```

It's also true the other way around: Creating a ZIP file with an empty
password on Linux cannot be extracted interactively on Windows. Not
allowing empty passwords at all should be part of another PR. This one
is about unifying Windows and POSIX systems regarding newline handling.

libarchive_fe/passphrase.c

index 9d95d527067bb1815dfd83758e2558d30f96eb21..90fef32d254c9b43dda12e8e2068b145a2104222 100644 (file)
@@ -76,6 +76,7 @@
 
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
+#include <string.h>
 #include <windows.h>
 
 static char *
@@ -113,8 +114,7 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
        WriteFile(hStdout, "\r\n", 2, NULL, NULL);
        buf[rbytes] = '\0';
        /* Remove trailing carriage return(s). */
-       if (rbytes > 2 && buf[rbytes - 2] == '\r' && buf[rbytes - 1] == '\n')
-               buf[rbytes - 2] = '\0';
+       buf[strcspn(buf, "\r\n")] = '\0';
 
        return (buf);
 }