Commit 83add39260d44a35e9acd2fc40389e7a9a27111f

Pali Rohár 2019-04-25T19:36:57

Simplify implementation of save_err_str() Check return value of FormatMessageA() function and remove copy_string() function as it is not needed.

diff --git a/dlfcn.c b/dlfcn.c
index 475b069..8687c51 100644
--- a/dlfcn.c
+++ b/dlfcn.c
@@ -133,45 +133,41 @@ static char error_buffer[65535];
 static char *current_error;
 static char dlerror_buffer[65536];
 
-static int copy_string( char *dest, int dest_size, const char *src )
-{
-    int i = 0;
-
-    /* gcc should optimize this out */
-    if( !src || !dest )
-        return 0;
-
-    for( i = 0 ; i < dest_size-1 ; i++ )
-    {
-        if( !src[i] )
-            break;
-        else
-            dest[i] = src[i];
-    }
-    dest[i] = '\0';
-
-    return i;
-}
-
 static void save_err_str( const char *str )
 {
     DWORD dwMessageId;
-    DWORD pos;
+    DWORD ret;
+    size_t pos, len;
 
     dwMessageId = GetLastError( );
 
     if( dwMessageId == 0 )
         return;
 
+    len = strlen( str );
+    if( len > sizeof( error_buffer ) - 5 )
+        len = sizeof( error_buffer ) - 5;
+
     /* Format error message to:
      * "<argument to function that failed>": <Windows localized error message>
       */
-    pos  = copy_string( error_buffer,     sizeof(error_buffer),     "\"" );
-    pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, str );
-    pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, "\": " );
-    pos += FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId,
+    pos = 0;
+    error_buffer[pos++] = '"';
+    memcpy( error_buffer+pos, str, len );
+    pos += len;
+    error_buffer[pos++] = '"';
+    error_buffer[pos++] = ':';
+    error_buffer[pos++] = ' ';
+
+    ret = FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId,
         MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
-        error_buffer+pos, sizeof(error_buffer)-pos, NULL );
+        error_buffer+pos, (DWORD) (sizeof(error_buffer)-pos), NULL );
+    pos += ret;
+
+    /* When FormatMessageA() fails it returns zero and does not touch buffer
+     * so add trailing null byte */
+    if( ret == 0 )
+        error_buffer[pos] = '\0';
 
     if( pos > 1 )
     {