]> granicus.if.org Git - curl/commitdiff
easy: fix win32 init to work without CURL_GLOBAL_WIN32
authorJay Satiro <raysatiro@yahoo.com>
Sat, 16 Feb 2019 23:55:40 +0000 (18:55 -0500)
committerJay Satiro <raysatiro@yahoo.com>
Mon, 18 Feb 2019 07:12:12 +0000 (02:12 -0500)
- Change the behavior of win32_init so that the required initialization
  procedures are not affected by CURL_GLOBAL_WIN32 flag.

libcurl via curl_global_init supports initializing for win32 with an
optional flag CURL_GLOBAL_WIN32, which if omitted was meant to stop
Winsock initialization. It did so internally by skipping win32_init()
when that flag was set. Since then win32_init() has been expanded to
include required initialization routines that are separate from
Winsock and therefore must be called in all cases. This commit fixes
it so that CURL_GLOBAL_WIN32 only controls the optional win32
initialization (which is Winsock initialization, according to our doc).

The only users affected by this change are those that don't pass
CURL_GLOBAL_WIN32 to curl_global_init. For them this commit removes the
risk of a potential crash.

Ref: https://github.com/curl/curl/pull/3573

Fixes https://github.com/curl/curl/issues/3313
Closes https://github.com/curl/curl/pull/3575

lib/easy.c

index d2d4166d5e3c01554287bc0c851e2cc4fd7b7f80..b1e264e8dc37c38bad3a29a45bcb52ed4858abfb 100644 (file)
 
 void Curl_version_init(void);
 
-/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
-   of win32_init() */
-static void win32_cleanup(void)
+/* true globals -- for curl_global_init() and curl_global_cleanup() */
+static unsigned int  initialized;
+static long          init_flags;
+
+/*
+ * win32 init and cleanup functions
+ */
+#ifdef WIN32
+
+/* win32_cleanup() is the opposite of win32_init() */
+static void win32_cleanup()
 {
-#ifdef USE_WINSOCK
-  WSACleanup();
-#endif
 #ifdef USE_WINDOWS_SSPI
   Curl_sspi_global_cleanup();
 #endif
+
+  if(init_flags & CURL_GLOBAL_WIN32) {
+#ifdef USE_WINSOCK
+    WSACleanup();
+#endif
+  }
 }
 
-#ifdef WIN32
 LARGE_INTEGER Curl_freq;
 bool Curl_isVistaOrGreater;
-#endif
 
-/* win32_init() performs win32 socket initialization to properly setup the
-   stack to allow networking */
-static CURLcode win32_init(void)
+/* win32_init() performs win32 global initialization */
+static CURLcode win32_init(long flags)
 {
+  /* CURL_GLOBAL_WIN32 controls the *optional* part of the initialization which
+     is just for Winsock at the moment. Any required win32 initialization
+     should take place after this block. */
+  if(flags & CURL_GLOBAL_WIN32) {
 #ifdef USE_WINSOCK
-  WORD wVersionRequested;
-  WSADATA wsaData;
-  int res;
+    WORD wVersionRequested;
+    WSADATA wsaData;
+    int res;
 
 #if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
-  Error IPV6_requires_winsock2
+#error IPV6_requires_winsock2
 #endif
 
-  wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
+    wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
 
-  res = WSAStartup(wVersionRequested, &wsaData);
+    res = WSAStartup(wVersionRequested, &wsaData);
 
-  if(res != 0)
-    /* Tell the user that we couldn't find a usable */
-    /* winsock.dll.     */
-    return CURLE_FAILED_INIT;
+    if(res != 0)
+      /* Tell the user that we couldn't find a usable */
+      /* winsock.dll.     */
+      return CURLE_FAILED_INIT;
 
-  /* Confirm that the Windows Sockets DLL supports what we need.*/
-  /* Note that if the DLL supports versions greater */
-  /* than wVersionRequested, it will still return */
-  /* wVersionRequested in wVersion. wHighVersion contains the */
-  /* highest supported version. */
+    /* Confirm that the Windows Sockets DLL supports what we need.*/
+    /* Note that if the DLL supports versions greater */
+    /* than wVersionRequested, it will still return */
+    /* wVersionRequested in wVersion. wHighVersion contains the */
+    /* highest supported version. */
 
-  if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
-     HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
-    /* Tell the user that we couldn't find a usable */
+    if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
+       HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
+      /* Tell the user that we couldn't find a usable */
 
-    /* winsock.dll. */
-    WSACleanup();
-    return CURLE_FAILED_INIT;
-  }
-  /* The Windows Sockets DLL is acceptable. Proceed. */
-#elif defined(USE_LWIPSOCK)
-  lwip_init();
-#endif
+      /* winsock.dll. */
+      WSACleanup();
+      return CURLE_FAILED_INIT;
+    }
+    /* The Windows Sockets DLL is acceptable. Proceed. */
+  #elif defined(USE_LWIPSOCK)
+    lwip_init();
+  #endif
+  } /* CURL_GLOBAL_WIN32 */
 
 #ifdef USE_WINDOWS_SSPI
   {
@@ -150,7 +163,6 @@ static CURLcode win32_init(void)
   }
 #endif
 
-#ifdef WIN32
   if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT,
                                  VERSION_GREATER_THAN_EQUAL)) {
     Curl_isVistaOrGreater = TRUE;
@@ -158,14 +170,11 @@ static CURLcode win32_init(void)
   }
   else
     Curl_isVistaOrGreater = FALSE;
-#endif
 
   return CURLE_OK;
 }
 
-/* true globals -- for curl_global_init() and curl_global_cleanup() */
-static unsigned int  initialized;
-static long          init_flags;
+#endif /* WIN32 */
 
 /*
  * strdup (and other memory functions) is redefined in complicated
@@ -239,11 +248,12 @@ static CURLcode global_init(long flags, bool memoryfuncs)
     return CURLE_FAILED_INIT;
   }
 
-  if(flags & CURL_GLOBAL_WIN32)
-    if(win32_init()) {
-      DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
-      return CURLE_FAILED_INIT;
-    }
+#ifdef WIN32
+  if(win32_init(flags)) {
+    DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+#endif
 
 #ifdef __AMIGA__
   if(!Curl_amiga_init()) {
@@ -347,8 +357,9 @@ void curl_global_cleanup(void)
   Curl_ssl_cleanup();
   Curl_resolver_global_cleanup();
 
-  if(init_flags & CURL_GLOBAL_WIN32)
-    win32_cleanup();
+#ifdef WIN32
+  win32_cleanup();
+#endif
 
   Curl_amiga_cleanup();