[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    [PATCH 4/5] wininet: return the required buffer size from InternetGetLastResponseInfo() when it's to
From:       Damjan Jovanovic <damjan.jov () gmail ! com>
Date:       2021-06-30 18:16:01
Message-ID: CAJm2B-mBW2kxo0aLfF_DDcUz17JOAHpLJ0435aL=sZWTNi8LPA () mail ! gmail ! com
[Download RAW message or body]

Signed-off-by: Damjan Jovanovic <damjan.jov@gmail.com>
---
 dlls/wininet/internet.c  | 17 +++++++++++++++--
 dlls/wininet/tests/ftp.c | 28 +++++++++++++++++++++++++++-
 2 files changed, 42 insertions(+), 3 deletions(-)

["0004-wininet-return-the-required-buffer-size-from-InternetG.txt" (text/plain)]

diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c
index 94dc37a2b13..5a097058e47 100644
--- a/dlls/wininet/internet.c
+++ b/dlls/wininet/internet.c
@@ -1092,10 +1092,17 @@ BOOL WINAPI InternetGetLastResponseInfoA(LPDWORD lpdwError,
     }
     if (lpwite)
     {
+        if (lpszBuffer == NULL || *lpdwBufferLength < strlen(lpwite->response))
+        {
+            *lpdwBufferLength = strlen(lpwite->response);
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            return FALSE;
+        }
         *lpdwError = lpwite->dwError;
-        if (lpwite->dwError)
+        if (lpwite->dwError && *lpdwBufferLength)
         {
             memcpy(lpszBuffer, lpwite->response, *lpdwBufferLength);
+            lpszBuffer[*lpdwBufferLength - 1] = 0;
             *lpdwBufferLength = strlen(lpszBuffer);
         }
         else
@@ -1134,8 +1141,14 @@ BOOL WINAPI InternetGetLastResponseInfoW(LPDWORD lpdwError,
     }
     if (lpwite)
     {
+        if (lpszBuffer == NULL || *lpdwBufferLength < strlen(lpwite->response))
+        {
+            *lpdwBufferLength = strlen(lpwite->response);
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            return FALSE;
+        }
         *lpdwError = lpwite->dwError;
-        if (lpwite->dwError)
+        if (lpwite->dwError && *lpdwBufferLength)
         {
             MultiByteToWideChar(CP_ACP, 0, lpwite->response, -1, lpszBuffer, \
                *lpdwBufferLength);
             *lpdwBufferLength = lstrlenW(lpszBuffer);
diff --git a/dlls/wininet/tests/ftp.c b/dlls/wininet/tests/ftp.c
index eba7c180939..16fbbcb2ed3 100644
--- a/dlls/wininet/tests/ftp.c
+++ b/dlls/wininet/tests/ftp.c
@@ -738,7 +738,8 @@ static void test_command(HINTERNET hFtp)
 
     for (i = 0; i < ARRAY_SIZE(command_test); i++)
     {
-        DWORD size;
+        DWORD size, orig_size;
+        char *buffer;
 
         SetLastError(0xdeadbeef);
         ret = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, \
command_test[i].cmd, 0, NULL); @@ -747,10 +748,35 @@ static void \
                test_command(HINTERNET hFtp)
         ok(ret == command_test[i].ret, "%d: expected FtpCommandA to %s\n", i, \
                command_test[i].ret ? "succeed" : "fail");
         ok(error == command_test[i].error, "%d: expected error %u, got %u\n", i, \
command_test[i].error, error);  
+        size = 0;
         ret = InternetGetLastResponseInfoA(&error, NULL, NULL);
         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "%d: ret %d, lasterr \
%d\n", i, ret, GetLastError());  ret = InternetGetLastResponseInfoA(NULL, NULL, \
                &size);
         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "%d: ret %d, lasterr \
%d\n", i, ret, GetLastError()); +        /* Zero size */
+        size = 0;
+        ret = InternetGetLastResponseInfoA(&error, NULL, &size);
+        ok((ret && size == 0) || (!ret && GetLastError() == \
ERROR_INSUFFICIENT_BUFFER), "%d: got ret %d, size %d, lasterr %d\n", i, ret, size, \
GetLastError()); +        /* Positive size, NULL buffer */
+        size++;
+        ret = InternetGetLastResponseInfoA(&error, NULL, &size);
+        ok((ret && size == 0) || (!ret && GetLastError() == \
ERROR_INSUFFICIENT_BUFFER), "%d: got ret %d, size %u, lasterr %d\n", i, ret, size, \
GetLastError()); +        /* When buffer is 1 char too short, it succeeds but trims \
the string: */ +        orig_size = size;
+        buffer = HeapAlloc(GetProcessHeap(), 0, size);
+        ok(buffer != NULL, "%d: no memory\n", i);
+        ret = InternetGetLastResponseInfoA(&error, buffer, &size);
+        ok(ret, "%d: got ret %d\n", i, ret);
+        ok(orig_size == 0 ? size == 0 : size == orig_size - 1, "%d: got orig_size \
%d, size %d\n", i, orig_size, size); +        ok(size == 0 || strlen(buffer) == size, \
"%d: size %d, buffer size %d\n", i, size, size ? strlen(buffer) : 0); +        \
HeapFree(GetProcessHeap(), 0, buffer); +        /* Long enough buffer */
+        buffer = HeapAlloc(GetProcessHeap(), 0, ++size);
+        ok(buffer != NULL, "%d: no memory\n", i);
+        ret = InternetGetLastResponseInfoA(&error, buffer, &size);
+        ok(ret, "%d: got ret %d\n", i, ret);
+        ok(size == 0 || strlen(buffer) == size, "%d: size %d, buffer size %d\n", i, \
size, size ? strlen(buffer) : 0); +        HeapFree(GetProcessHeap(), 0, buffer);
     }
 }
 



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic