From 4cd3a16f181b30ffa0a1099d6d676c413b25cc22 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Thu, 4 Oct 2007 20:43:31 -0700 Subject: [PATCH] msvcrt: Improve CR CR LF handling. --- dlls/msvcrt/file.c | 17 ++++++++++++----- dlls/msvcrt/tests/file.c | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 4ceae0beea1..b8787810c71 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -1639,15 +1639,21 @@ int CDECL _rmtmp(void) /********************************************************************* * (internal) remove_cr * - * Remove all \r inplace. + * Translate all \r\n to \n inplace. * return the number of \r removed + * Corner cases required by some apps: + * \r\r\n -> \r\n + * BUG: should save state across calls somehow, so CR LF that + * straddles buffer boundary gets recognized properly? */ static unsigned int remove_cr(char *buf, unsigned int count) { unsigned int i, j; - for (i = 0; i < count; i++) if (buf[i] == '\r') break; - for (j = i + 1; j < count; j++) if (buf[j] != '\r') buf[i++] = buf[j]; + for (i=0, j=0; j < count; j++) + if ((buf[j] != '\r') || ((j+1) < count && buf[j+1] != '\n')) + buf[i++] = buf[j]; + return count - i; } @@ -2210,8 +2216,9 @@ int CDECL MSVCRT_fgetc(MSVCRT_FILE* file) j = *i; } else j = MSVCRT__filbuf(file); - if (!(MSVCRT_fdesc[file->_file].wxflag & WX_TEXT) || (j != '\r')) - return j; + if (!(MSVCRT_fdesc[file->_file].wxflag & WX_TEXT) + || ((j != '\r') || (file->_cnt && ((char *)file->_ptr)[0] != '\n'))) + return j; } while(1); } diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c index bdf0d0ac1e4..4a311e4dfa3 100644 --- a/dlls/msvcrt/tests/file.c +++ b/dlls/msvcrt/tests/file.c @@ -271,6 +271,23 @@ static void test_readmode( BOOL ascii_mode ) unlink ("fdopen.tst"); } +static void test_asciimode(void) +{ + FILE *fp; + char buf[64]; + + /* Simple test of CR CR LF handling. Test both fgets and fread code paths, they're different! */ + fp = fopen("ascii.tst", "wb"); + fputs("\r\r\n", fp); + fclose(fp); + fp = fopen("ascii.tst", "rt"); + ok(fgets(buf, sizeof(buf), fp) != NULL, "fgets\n"); + ok(0 == strcmp(buf, "\r\n"), "CR CR LF not read as CR LF\n"); + rewind(fp); + ok((fread(buf, 1, sizeof(buf), fp) == 2) && (0 == strcmp(buf, "\r\n")), "CR CR LF not read as CR LF\n"); + fclose(fp); + unlink("ascii.tst"); +} static WCHAR* AtoW( const char* p ) { @@ -996,6 +1013,7 @@ START_TEST(file) test_fdopen(); test_fopen_fclose_fcloseall(); test_fileops(); + test_asciimode(); test_readmode(FALSE); /* binary mode */ test_readmode(TRUE); /* ascii mode */ test_fgetc(); -- 2.11.4.GIT