From: Tobias Stoeckmann Date: Sat, 13 Apr 2024 05:40:02 +0000 (+0000) Subject: Improve newline handling on Windows (#2115) X-Git-Tag: v3.7.4~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=46818684c3dfcb8ace2721491b9e15aff5341725;p=thirdparty%2Flibarchive.git Improve newline handling on Windows (#2115) 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: ``` 3. Extract ZIP file on Windows ``` PS> bsdtar.exe -xf archive.zip Enter passphrase: ``` 4. Extract ZIP file on Linux ``` $ bsdtar -xf archive.zip Enter passphrase: 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. --- diff --git a/libarchive_fe/passphrase.c b/libarchive_fe/passphrase.c index 9d95d5270..90fef32d2 100644 --- a/libarchive_fe/passphrase.c +++ b/libarchive_fe/passphrase.c @@ -76,6 +76,7 @@ #if defined(_WIN32) && !defined(__CYGWIN__) +#include #include 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); }