From 07ff621b4bdd45f2289f8e6da72b95aefdb55e58 Mon Sep 17 00:00:00 2001 From: Joachim Henze Date: Wed, 11 Nov 2020 17:39:36 +0100 Subject: [PATCH] [0.4.9][CONUTILS] Fix regression with file redirection of 'more' CORE-14592 In ConWrite(), emit an \r when a \n is encountered but not already preceded by \r. And, don't emit \r\n when an \r alone is encountered. This fixes the problem of extra newlines appearing when redirecting "more" output to a file. It regressed somewhere in between SVN [r68849-r73441], most likely with some commit that touched 'conutils' or 'more'. fix picked from commit 0.4.11-dev-1-g b277cbdf222a67f7bf4e7acc246189be91474aa0 --- sdk/lib/conutils/outstream.c | 70 +++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/sdk/lib/conutils/outstream.c b/sdk/lib/conutils/outstream.c index 645452f3eff..6d3f9d8915e 100644 --- a/sdk/lib/conutils/outstream.c +++ b/sdk/lib/conutils/outstream.c @@ -162,36 +162,43 @@ ConWrite( /* * Find any newline character in the buffer, - * write the part BEFORE the newline, then write - * a carriage-return + newline, and then write - * the remaining part of the buffer. + * write the part BEFORE the newline, then emit + * a carriage-return + newline sequence and finally + * write the remaining part of the buffer. * * This fixes output in files and serial console. */ while (len > 0) { - /* Loop until we find a \r or \n character */ - // FIXME: What about the pair \r\n ? + /* Loop until we find a newline character */ p = szStr; - while (len > 0 && *(PWCHAR)p != L'\r' && *(PWCHAR)p != L'\n') + while (len > 0 && *(PWCHAR)p != L'\n') { /* Advance one character */ p = (PVOID)((PWCHAR)p + 1); - len--; + --len; } - /* Write everything up to \r or \n */ + /* Write everything up to \n */ dwNumBytes = ((PWCHAR)p - (PWCHAR)szStr) * sizeof(WCHAR); WriteFile(Stream->hHandle, szStr, dwNumBytes, &dwNumBytes, NULL); - /* If we hit \r or \n ... */ - if (len > 0 && (*(PWCHAR)p == L'\r' || *(PWCHAR)p == L'\n')) + /* + * If we hit a newline and the previous character is not a carriage-return, + * emit a carriage-return + newline sequence, otherwise just emit the newline. + */ + if (len > 0 && *(PWCHAR)p == L'\n') { - /* ... send a carriage-return + newline sequence and skip \r or \n */ - WriteFile(Stream->hHandle, L"\r\n", 2 * sizeof(WCHAR), &dwNumBytes, NULL); - szStr = (PVOID)((PWCHAR)p + 1); - len--; + if (p == (PVOID)szStr || (p > (PVOID)szStr && *((PWCHAR)p - 1) != L'\r')) + WriteFile(Stream->hHandle, L"\r\n", 2 * sizeof(WCHAR), &dwNumBytes, NULL); + else + WriteFile(Stream->hHandle, L"\n", sizeof(WCHAR), &dwNumBytes, NULL); + + /* Skip \n */ + p = (PVOID)((PWCHAR)p + 1); + --len; } + szStr = p; } #ifndef _UNICODE @@ -239,36 +246,43 @@ ConWrite( /* * Find any newline character in the buffer, - * write the part BEFORE the newline, then write - * a carriage-return + newline, and then write - * the remaining part of the buffer. + * write the part BEFORE the newline, then emit + * a carriage-return + newline sequence and finally + * write the remaining part of the buffer. * * This fixes output in files and serial console. */ while (len > 0) { - /* Loop until we find a \r or \n character */ - // FIXME: What about the pair \r\n ? + /* Loop until we find a newline character */ p = szStr; - while (len > 0 && *(PCHAR)p != '\r' && *(PCHAR)p != '\n') + while (len > 0 && *(PCHAR)p != '\n') { /* Advance one character */ p = (PVOID)((PCHAR)p + 1); - len--; + --len; } - /* Write everything up to \r or \n */ + /* Write everything up to \n */ dwNumBytes = ((PCHAR)p - (PCHAR)szStr) * sizeof(CHAR); WriteFile(Stream->hHandle, szStr, dwNumBytes, &dwNumBytes, NULL); - /* If we hit \r or \n ... */ - if (len > 0 && (*(PCHAR)p == '\r' || *(PCHAR)p == '\n')) + /* + * If we hit a newline and the previous character is not a carriage-return, + * emit a carriage-return + newline sequence, otherwise just emit the newline. + */ + if (len > 0 && *(PCHAR)p == '\n') { - /* ... send a carriage-return + newline sequence and skip \r or \n */ - WriteFile(Stream->hHandle, "\r\n", 2, &dwNumBytes, NULL); - szStr = (PVOID)((PCHAR)p + 1); - len--; + if (p == (PVOID)szStr || (p > (PVOID)szStr && *((PCHAR)p - 1) != '\r')) + WriteFile(Stream->hHandle, "\r\n", 2, &dwNumBytes, NULL); + else + WriteFile(Stream->hHandle, "\n", 1, &dwNumBytes, NULL); + + /* Skip \n */ + p = (PVOID)((PCHAR)p + 1); + --len; } + szStr = p; } #ifdef _UNICODE