Skip to content

configure.ac: error if --with-winidn and target OS too old#12684

Closed
jay wants to merge 1 commit intocurl:masterfrom
jay:winidn_min_os_err
Closed

configure.ac: error if --with-winidn and target OS too old#12684
jay wants to merge 1 commit intocurl:masterfrom
jay:winidn_min_os_err

Conversation

@jay
Copy link
Member

@jay jay commented Jan 12, 2024

  • If the minimum Windows target OS is pre-Vista (_WIN32_WINNT < 0x600) then error.

  • Stop comparing against WINVER when making the minimum OS determinations (ie check only _WIN32_WINNT instead of both since that's the one that matters).

Prior to this change, if --with-winidn was used in such a case configure would change the minimum target OS to Vista (0x600) so the build would compile. That was done primarily as a workaround for original MinGW which we no longer support.

Bug: #12606 (comment)
Reported-by: Viktor Szakats

Closes #xxxxx

- If the minimum Windows target OS is pre-Vista (_WIN32_WINNT < 0x600)
  then error.

- Stop comparing against WINVER when making the minimum OS
  determinations (ie check only _WIN32_WINNT instead of both since
  that's the one that matters).

Prior to this change, if --with-winidn was used in such a case configure
would change the minimum target OS to Vista (0x600) so the build would
compile. That was done primarily as a workaround for original MinGW
which we no longer support.

Bug: curl#12606 (comment)
Reported-by: Viktor Szakats

Closes #xxxxx
@jay jay force-pushed the winidn_min_os_err branch from 76b8d0b to e02b27e Compare January 12, 2024 00:19
@vszakats
Copy link
Member

vszakats commented Jan 12, 2024

Thinking about this, if we require Vista, we'd need some additional tweaks for consistency. In lib/idn.c we have logic to declare these WinIDN APIs ourselves when building for < 0x0600. (Which is kind of valid, since WinIDN could also work on XP, though it needed normaliz.dll, which used to be a separate download, but Microsoft deleted that download a long time ago. So in practice it became problematic.)

Anyway, if we require Vista for IDN, the lib/idn.c trick is no longer necessary and it'd probably be better to replace it with something like this in lib/curl-setup.h and CMake could also use an update:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3a6ae3d42..332c08186 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -841,13 +841,6 @@ else()
   set(HAVE_LIBIDN2 OFF)
 endif()
 
-if(WIN32)
-  option(USE_WIN32_IDN "Use WinIDN for IDN support" OFF)
-  if(USE_WIN32_IDN)
-    list(APPEND CURL_LIBS "normaliz")
-  endif()
-endif()
-
 #libpsl
 option(CURL_USE_LIBPSL "Use libPSL" ON)
 mark_as_advanced(CURL_USE_LIBPSL)
@@ -1085,6 +1078,14 @@ if(WIN32)
       unset(HAVE_INET_PTON CACHE)
     endif()
   endif()
+
+  option(USE_WIN32_IDN "Use WinIDN for IDN support" OFF)
+  if(USE_WIN32_IDN)
+    if(HAVE_WIN32_WINNT AND HAVE_WIN32_WINNT STRLESS "0x600")
+      message(FATAL_ERROR "WinIDN requires building for Windows Vista or newer.")
+    endif()
+    list(APPEND CURL_LIBS "normaliz")
+  endif()
 endif()
 
 check_include_file_concat("sys/filio.h"      HAVE_SYS_FILIO_H)
diff --git a/lib/curl_setup.h b/lib/curl_setup.h
index 551243e27..794d42058 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -623,6 +623,14 @@
 
 /* ---------------------------------------------------------------- */
 
+#if !defined(_WIN32) && defined(USE_WIN32_IDN)
+#undef USE_WIN32_IDN
+#endif
+
+#if defined(USE_WIN32_IDN) && (_WIN32_WINNT < 0x0600)
+#error "WinIDN requires building for Windows Vista or newer."
+#endif
+
 #if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H) && !defined(USE_WIN32_IDN)
 /* The lib and header are present */
 #define USE_LIBIDN2
diff --git a/lib/idn.c b/lib/idn.c
index 81a177f8c..c4167db18 100644
--- a/lib/idn.c
+++ b/lib/idn.c
@@ -51,20 +51,6 @@
 #include "memdebug.h"
 
 #ifdef USE_WIN32_IDN
-/* using Windows kernel32 and normaliz libraries. */
-
-#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x600
-WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags,
-                                 const WCHAR *lpUnicodeCharStr,
-                                 int cchUnicodeChar,
-                                 WCHAR *lpASCIICharStr,
-                                 int cchASCIIChar);
-WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags,
-                                   const WCHAR *lpASCIICharStr,
-                                   int cchASCIIChar,
-                                   WCHAR *lpUnicodeCharStr,
-                                   int cchUnicodeChar);
-#endif
 
 #define IDN_MAX_LENGTH 255

Edits:

  • autotools' --with-winidn=PATH option is also obsolete in this case (because IDN is part of the SDK for Vista)
  • autotools' normaliz checker is also redundant because it's always present with Vista.
  • we might consider enabling WinIDN by default if libidn2 isn't enabled and targeting Windows.

If want to keep supporting WinIDN for XP, maybe the autotools detection could probe building with IdnToAscii() with normaliz lib, but that's a little shaky because an XP target env might not have the DLL.

@bagder
Copy link
Member

bagder commented Jul 1, 2024

Stalled.

@bagder bagder closed this Jul 1, 2024
vszakats added a commit to vszakats/curl that referenced this pull request Aug 26, 2024
vszakats added a commit to vszakats/curl that referenced this pull request Aug 26, 2024
Originall added in 37f1c21 curl#7581
for classic mingw. curl no longer supports building with classic mingw.

Ref: curl#12684
Ref: curl#12606 (comment)
vszakats added a commit that referenced this pull request Aug 27, 2024
1. GHA/windows: enable WinIDN in Linux cross-builds.
   (to reveal the issue in CI.)

2. fix compiler warning when building with mingw-w64 supporting
   WinIDN, while targeting pre-Vista Windows, with a `WINVER` set to
   target Vista or newer. (Such was Ubuntu's mingw-w64 with the
   classic-mingw-specific trick in point 3 of this PR.)
   ```
   ../../lib/idn.c:154:23: error: redundant redeclaration of ‘IdnToAscii’ [-Werror=redundant-decls]
     154 | WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags,
         |                       ^~~~~~~~~~
   In file included from /usr/share/mingw-w64/include/windows.h:73,
                    from /usr/share/mingw-w64/include/winsock2.h:23,
                    from ../../lib/setup-win32.h:91,
                    from ../../lib/curl_setup.h:308,
                    from ../../lib/idn.c:29:
   /usr/share/mingw-w64/include/winnls.h:1075:30: note: previous declaration of ‘IdnToAscii’ was here
    1075 |   WINNORMALIZEAPI int WINAPI IdnToAscii (DWORD dwFlags, LPCWSTR lpUnicodeCharStr, int cchUnicodeChar, LPWSTR lpASCIICharStr, int cchASCIIChar);
         |                              ^~~~~~~~~~
   [...same for IdnToUnicode...]
   ```
   Ref: https://github.com/curl/curl/actions/runs/10542832783/job/29210098553#step:7:89

3. drop `WINVER` override for classic-mingw. curl no longer supports
   building with classic-mingw.
   Reverts 37f1c21 #7581

4. sync `if IdnToUnicode can be linked` detection snippet with the live
   code in `lib/idn.c`. It fixes detection for the scenario in point 2.

5. delete unused `WINIDN_DIR` variable.

Bug: #12606 (comment)
Previous abandoned attempt: #12684
Reviewed-by: Jay Satiro
Closes #14680
@jay jay deleted the winidn_min_os_err branch December 27, 2024 05:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Windows Windows-specific

Development

Successfully merging this pull request may close these issues.

3 participants