From f21d7a2bbf1a6083c3b748456a3155dab50a3784 Mon Sep 17 00:00:00 2001 From: Vincent Blondeau Date: Sat, 11 Apr 2020 20:25:36 +0200 Subject: [PATCH 1/2] Fix Issue when opening heaps of more than MAX DWORD size - Add Writing and Reading by block of MAX_DWORD --- .../plugins/FilePlugin/sqWin32FilePrims.c | 36 ++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c b/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c index 4f37347582..397f5ba8a0 100644 --- a/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c +++ b/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c @@ -37,6 +37,7 @@ extern struct VirtualMachine *interpreterProxy; #define true 1 #define false 0 +static const DWORD MAX_DWORD = 4294967295; #define FILE_HANDLE(f) ((HANDLE) (f)->file) #define FAIL() { return interpreterProxy->primitiveFail(); } @@ -511,10 +512,24 @@ squeakFileOffsetType sqImageFilePosition(sqImageFile h) size_t sqImageFileRead(void *ptr, size_t sz, size_t count, sqImageFile h) { DWORD dwReallyRead; + + size_t reallyRead = 0; + + size_t totalToRead = count * sz; + squeakFileOffsetType position; - + + if (totalToRead > (size_t)MAX_DWORD - 1) { + while (reallyRead != totalToRead) { + DWORD toRead = (totalToRead - reallyRead) > (size_t)MAX_DWORD ? MAX_DWORD : totalToRead - reallyRead; + ReadFile((HANDLE)(h - 1), (LPVOID)((sqInt)ptr + (sqInt)reallyRead), toRead, &dwReallyRead, NULL); + reallyRead += dwReallyRead; + } + return (reallyRead / sz); + } + position = sqImageFilePosition(h); - ReadFile((HANDLE)(h-1), (LPVOID) ptr, count*sz, &dwReallyRead, NULL); + ReadFile((HANDLE)(h - 1), (LPVOID)ptr, count * sz, &dwReallyRead, NULL); while(dwReallyRead != (DWORD)(count*sz)) { DWORD err = GetLastError(); if(sqMessageBox(MB_ABORTRETRYIGNORE, TEXT("Squeak Warning"),TEXT("Image file read problem (%d out of %d bytes read)"), dwReallyRead, count*sz) @@ -522,7 +537,7 @@ size_t sqImageFileRead(void *ptr, size_t sz, size_t count, sqImageFile h) sqImageFileSeek(h, position); ReadFile((HANDLE)(h-1), (LPVOID) ptr, count*sz, &dwReallyRead, NULL); } - return (dwReallyRead / sz); + return (size_t)(dwReallyRead / sz); } squeakFileOffsetType sqImageFileSeek(sqImageFile h, squeakFileOffsetType pos) @@ -543,9 +558,20 @@ squeakFileOffsetType sqImageFileSeekEnd(sqImageFile h, squeakFileOffsetType pos) size_t sqImageFileWrite(const void *ptr, size_t sz, size_t count, sqImageFile h) { + size_t reallyWritten =0; DWORD dwReallyWritten; - WriteFile((HANDLE)(h-1), (LPVOID) ptr, count*sz, &dwReallyWritten, NULL); - return (size_t) (dwReallyWritten / sz); + size_t totalToWrite = count * sz; + if (totalToWrite < (size_t)MAX_DWORD -1) { + WriteFile((HANDLE)(h - 1), (LPVOID)ptr, count * sz, &dwReallyWritten, NULL); + return (size_t)(dwReallyWritten / sz); + } + + while (reallyWritten != totalToWrite) { + DWORD toWrite = (totalToWrite - reallyWritten) > (size_t) MAX_DWORD ? MAX_DWORD : totalToWrite - reallyWritten; + WriteFile((HANDLE)(h - 1), (LPVOID)((sqInt)ptr + (sqInt) reallyWritten), toWrite, &dwReallyWritten, NULL); + reallyWritten += dwReallyWritten; + } + return (size_t) (reallyWritten / sz); } squeakFileOffsetType sqImageFileSize(sqImageFile h) From 561bea72d0caa699bdd920f786e38b87f137f2a4 Mon Sep 17 00:00:00 2001 From: Vincent Blondeau Date: Sat, 11 Apr 2020 20:40:51 +0200 Subject: [PATCH 2/2] Add function return test Display an error message if it the amount of bytes that should be written or read is not consistent --- .../plugins/FilePlugin/sqWin32FilePrims.c | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c b/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c index 397f5ba8a0..8bc5b4a6a5 100644 --- a/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c +++ b/platforms/win32/plugins/FilePlugin/sqWin32FilePrims.c @@ -512,32 +512,26 @@ squeakFileOffsetType sqImageFilePosition(sqImageFile h) size_t sqImageFileRead(void *ptr, size_t sz, size_t count, sqImageFile h) { DWORD dwReallyRead; - size_t reallyRead = 0; - size_t totalToRead = count * sz; - squeakFileOffsetType position; - if (totalToRead > (size_t)MAX_DWORD - 1) { - while (reallyRead != totalToRead) { - DWORD toRead = (totalToRead - reallyRead) > (size_t)MAX_DWORD ? MAX_DWORD : totalToRead - reallyRead; - ReadFile((HANDLE)(h - 1), (LPVOID)((sqInt)ptr + (sqInt)reallyRead), toRead, &dwReallyRead, NULL); - reallyRead += dwReallyRead; + position = sqImageFilePosition(h); + while (reallyRead != totalToRead) { + DWORD toRead = (totalToRead - reallyRead) > (size_t)MAX_DWORD ? MAX_DWORD : totalToRead - reallyRead; + BOOL ret = ReadFile((HANDLE)(h - 1), (LPVOID)((sqInt)ptr + (sqInt)reallyRead), toRead, &dwReallyRead, NULL); + reallyRead += dwReallyRead; + + if (!ret | dwReallyRead != toRead) { + DWORD err = GetLastError(); + if (sqMessageBox(MB_ABORTRETRYIGNORE, TEXT("VM Warning"), TEXT("Image file read problem (%d out of %d bytes read)"), dwReallyRead, toRead) + == IDABORT) return (size_t)(reallyRead / sz); + sqImageFileSeek(h, position); + reallyRead = 0; } - return (reallyRead / sz); - } - position = sqImageFilePosition(h); - ReadFile((HANDLE)(h - 1), (LPVOID)ptr, count * sz, &dwReallyRead, NULL); - while(dwReallyRead != (DWORD)(count*sz)) { - DWORD err = GetLastError(); - if(sqMessageBox(MB_ABORTRETRYIGNORE, TEXT("Squeak Warning"),TEXT("Image file read problem (%d out of %d bytes read)"), dwReallyRead, count*sz) - == IDABORT) return (dwReallyRead / sz); - sqImageFileSeek(h, position); - ReadFile((HANDLE)(h-1), (LPVOID) ptr, count*sz, &dwReallyRead, NULL); } - return (size_t)(dwReallyRead / sz); + return (reallyRead / sz); } squeakFileOffsetType sqImageFileSeek(sqImageFile h, squeakFileOffsetType pos) @@ -561,15 +555,21 @@ size_t sqImageFileWrite(const void *ptr, size_t sz, size_t count, sqImageFile h) size_t reallyWritten =0; DWORD dwReallyWritten; size_t totalToWrite = count * sz; - if (totalToWrite < (size_t)MAX_DWORD -1) { - WriteFile((HANDLE)(h - 1), (LPVOID)ptr, count * sz, &dwReallyWritten, NULL); - return (size_t)(dwReallyWritten / sz); - } + squeakFileOffsetType position; + position = sqImageFilePosition(h); while (reallyWritten != totalToWrite) { DWORD toWrite = (totalToWrite - reallyWritten) > (size_t) MAX_DWORD ? MAX_DWORD : totalToWrite - reallyWritten; - WriteFile((HANDLE)(h - 1), (LPVOID)((sqInt)ptr + (sqInt) reallyWritten), toWrite, &dwReallyWritten, NULL); + BOOL ret = WriteFile((HANDLE)(h - 1), (LPVOID)((sqInt)ptr + (sqInt) reallyWritten), toWrite, &dwReallyWritten, NULL); reallyWritten += dwReallyWritten; + + if (!ret | dwReallyWritten != toWrite) { + DWORD err = GetLastError(); + if (sqMessageBox(MB_ABORTRETRYIGNORE, TEXT("VM Warning"), TEXT("Image file read problem (%d out of %d bytes read)"), dwReallyWritten, toWrite) + == IDABORT) return (size_t)(reallyWritten / sz); + sqImageFileSeek(h, position); + reallyWritten = 0; + } } return (size_t) (reallyWritten / sz); }