configure.ac                                                                   
    |    2 
 download.lst                                                                   
    |   12 
 external/curl/ExternalProject_curl.mk                                          
    |    1 
 external/curl/UnpackedTarball_curl.mk                                          
    |    1 
 external/curl/configurable-z-option.patch.0                                    
    |    2 
 external/curl/curl-msvc-disable-protocols.patch.1                              
    |   10 
 external/curl/curl-msvc.patch.1                                                
    |   18 
 external/curl/undefined.patch.0                                                
    |   11 
 external/curl/zlib.patch.0                                                     
    |   40 
 external/postgresql/README                                                     
    |    6 
 external/postgresql/postgres-msvc-build.patch.1                                
    |    4 
 
external/python3/0001-3.9-bpo-43757-Make-pathlib-use-os.path.realpath-to-r.patch.1
 |  537 +++
 
external/python3/0001-3.9-bpo-45461-Fix-IncrementalDecoder-and-StreamReade.patch.1
 |  384 ++
 
external/python3/0001-3.9-gh-133767-Fix-use-after-free-in-the-unicode-esca.patch.1
 |  441 ++
 
external/python3/0001-3.9-gh-135034-Normalize-link-targets-in-tarfile-add-.patch.1
 | 1771 ++++++++++
 
external/python3/0001-Cut-disused-recode_encoding-logic-in-_PyBytes_Decode.patch.1
 |  168 
 external/python3/ExternalPackage_python3.mk                                    
    |    2 
 external/python3/UnpackedTarball_python3.mk                                    
    |    5 
 18 files changed, 3370 insertions(+), 45 deletions(-)

New commits:
commit aafa5879ac9500453564b59d2b1bead4f032d8eb
Author:     Xisco Fauli <[email protected]>
AuthorDate: Thu Dec 12 02:11:12 2024 +0100
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:55:10 2026 +0100

    curl: upgrade to 8.13.0
    
    * Add external/curl/undefined.patch.0 to handle
    https://github.com/curl/curl/issues/16925
    
    Downloaded from https://curl.se/download/curl-8.13.0.tar.xz
    
    Change-Id: I5555cdee13f7660b52ac4a513969dfde1563bf56
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183614
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184976
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Andras Timar <[email protected]>
    (cherry picked from commit d12cbef190a1bb306cd37736bace9dd22e0a709b)

diff --git a/download.lst b/download.lst
index c8a2d24b0061..fb11a1dfc554 100644
--- a/download.lst
+++ b/download.lst
@@ -75,8 +75,8 @@ CPPUNIT_TARBALL := cppunit-1.15.1.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-CURL_SHA256SUM := 
db59cf0d671ca6e7f5c2c5ec177084a33a79e04c97e71cf183a5cdea235054eb
-CURL_TARBALL := curl-8.11.0.tar.xz
+CURL_SHA256SUM := 
4a093979a3c2d02de2fbc00549a32771007f2e78032c6faa5ecd2f7a9e152025
+CURL_TARBALL := curl-8.13.0.tar.xz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
diff --git a/external/curl/ExternalProject_curl.mk 
b/external/curl/ExternalProject_curl.mk
index fdc93a46c3cb..d6e558af86cf 100644
--- a/external/curl/ExternalProject_curl.mk
+++ b/external/curl/ExternalProject_curl.mk
@@ -86,6 +86,7 @@ $(call gb_ExternalProject_get_state_target,curl,build):
                        ENABLE_IPV6=yes \
                        ENABLE_SSPI=yes \
                        ENABLE_WINSSL=yes \
+                       WINBUILD_ACKNOWLEDGE_DEPRECATED=yes \
                        WITH_ZLIB=static \
        ,winbuild)
        $(call gb_Trace_EndRange,curl,EXTERNAL)
diff --git a/external/curl/UnpackedTarball_curl.mk 
b/external/curl/UnpackedTarball_curl.mk
index 4412857d36a0..301beef47452 100644
--- a/external/curl/UnpackedTarball_curl.mk
+++ b/external/curl/UnpackedTarball_curl.mk
@@ -25,6 +25,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,curl,\
        external/curl/curl-msvc-disable-protocols.patch.1 \
        external/curl/zlib.patch.0 \
        external/curl/configurable-z-option.patch.0 \
+       external/curl/undefined.patch.0 \
 ))
 
 ifeq ($(OS)-$(COM_IS_CLANG),WNT-TRUE)
diff --git a/external/curl/curl-msvc-disable-protocols.patch.1 
b/external/curl/curl-msvc-disable-protocols.patch.1
index 55970b2757b3..e0c74fed9fd6 100644
--- a/external/curl/curl-msvc-disable-protocols.patch.1
+++ b/external/curl/curl-msvc-disable-protocols.patch.1
@@ -2,9 +2,9 @@ disable protocols nobody needs in MSVC build
 
 --- curl/lib/config-win32.h.orig       2017-08-09 16:43:29.464000000 +0200
 +++ curl/lib/config-win32.h    2017-08-09 16:47:38.549200000 +0200
-@@ -509,4 +509,20 @@
- /* If you want to build curl with the built-in manual */
- #define USE_MANUAL 1
+@@ -500,6 +500,22 @@
+ #  endif /* UNDER_CE */
+ #endif /* !CURL_OS */
  
 +#define CURL_DISABLE_DICT 1
 +#define CURL_DISABLE_FILE 1
@@ -22,7 +22,9 @@ disable protocols nobody needs in MSVC build
 +#define CURL_DISABLE_TELNET 1
 +#define CURL_DISABLE_TFTP 1
 +
- #endif /* HEADER_CURL_CONFIG_WIN32_H */
+ /* ---------------------------------------------------------------- */
+ /*                            Windows CE                            */
+ /* ---------------------------------------------------------------- */
 --- curl/winbuild/MakefileBuild.vc.orig        2017-10-23 23:41:21.393200000 
+0200
 +++ curl/winbuild/MakefileBuild.vc     2017-10-23 23:34:16.028000000 +0200
 @@ -562,7 +562,7 @@
diff --git a/external/curl/undefined.patch.0 b/external/curl/undefined.patch.0
new file mode 100644
index 000000000000..c73d310904fe
--- /dev/null
+++ b/external/curl/undefined.patch.0
@@ -0,0 +1,11 @@
+--- lib/curl_krb5.h    2025-04-03 09:35:06.209290030 +0200
++++ lib/curl_krb5.h    2025-04-03 09:35:19.341187768 +0200
+@@ -39,7 +39,7 @@
+ #define AUTH_CONTINUE   1
+ #define AUTH_ERROR      2
+ 
+-#ifdef HAVE_GSSAPI
++#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_FTP)
+ void Curl_sec_conn_init(struct connectdata *);
+ void Curl_sec_conn_destroy(struct connectdata *);
+ int Curl_sec_read_msg(struct Curl_easy *data, struct connectdata *conn, char 
*,
commit 0a3276f4448b4cb5cc943efd7c1ab436af3dc29b
Author:     Xisco Fauli <[email protected]>
AuthorDate: Wed Nov 6 19:52:22 2024 +0100
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:55:02 2026 +0100

    curl: upgrade to 8.11.0
    
    Downloaded from https://curl.se/download/curl-8.11.0.tar.xz
    
    Change-Id: If1b8175c0e6a32ac5b723a73b07f9971a6f8b739
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176157
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <[email protected]>
    (cherry picked from commit 330bd4679fcb2540776a9a31310e283ac8ab1d68)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176079
    Reviewed-by: Christian Lohmaier <[email protected]>
    (cherry picked from commit dd778f2a3a143e9f699f289306168f550f54afed)

diff --git a/download.lst b/download.lst
index 7ddefd59dfb1..c8a2d24b0061 100644
--- a/download.lst
+++ b/download.lst
@@ -75,8 +75,8 @@ CPPUNIT_TARBALL := cppunit-1.15.1.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-CURL_SHA256SUM := 
73a4b0e99596a09fa5924a4fb7e4b995a85fda0d18a2c02ab9cf134bebce04ee
-CURL_TARBALL := curl-8.10.1.tar.xz
+CURL_SHA256SUM := 
db59cf0d671ca6e7f5c2c5ec177084a33a79e04c97e71cf183a5cdea235054eb
+CURL_TARBALL := curl-8.11.0.tar.xz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
commit 73f785d163fcd5cda6e65cd0872958434bcabf72
Author:     Xisco Fauli <[email protected]>
AuthorDate: Wed Sep 18 09:23:25 2024 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:54:54 2026 +0100

    curl: upgrade to 8.10.1
    
    Downloaded from https://curl.se/download/curl-8.10.1.tar.xz
    
    Change-Id: If65882b06172e9caf93d941011baa49c84d4f054
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173630
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <[email protected]>
    (cherry picked from commit 4c2642166b1d5b7fa88bc26f81515f1ee6cc47b5)

diff --git a/download.lst b/download.lst
index 3c39f1c14964..7ddefd59dfb1 100644
--- a/download.lst
+++ b/download.lst
@@ -75,8 +75,8 @@ CPPUNIT_TARBALL := cppunit-1.15.1.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-CURL_SHA256SUM := 
e6b142f0e85e954759d37e26a3627e2278137595be80e3a860c4353e4335e5a0
-CURL_TARBALL := curl-8.10.0.tar.xz
+CURL_SHA256SUM := 
73a4b0e99596a09fa5924a4fb7e4b995a85fda0d18a2c02ab9cf134bebce04ee
+CURL_TARBALL := curl-8.10.1.tar.xz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
commit 4edb0cce8ced4dfaff670e646f537c1ed8b76aa4
Author:     Xisco Fauli <[email protected]>
AuthorDate: Wed Sep 11 11:04:56 2024 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:54:44 2026 +0100

    curl: upgrade to 8.10.0
    
    Downloaded from https://curl.se/download/curl-8.10.0.tar.xz
    
    Change-Id: I1eb9506a73162ce2e2adf1fe1e02267c34bc78ac
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173194
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <[email protected]>
    (cherry picked from commit c95229bf8e3bd643b8529046f0754e2de4c6625b)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173173
    Reviewed-by: Taichi Haradaguchi <[email protected]>
    (cherry picked from commit dbfe3a3de061b701b40f15c6560d50baa8a01b80)

diff --git a/download.lst b/download.lst
index bdc9cef845be..3c39f1c14964 100644
--- a/download.lst
+++ b/download.lst
@@ -75,8 +75,8 @@ CPPUNIT_TARBALL := cppunit-1.15.1.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-CURL_SHA256SUM := 
f292f6cc051d5bbabf725ef85d432dfeacc8711dd717ea97612ae590643801e5
-CURL_TARBALL := curl-8.9.1.tar.xz
+CURL_SHA256SUM := 
e6b142f0e85e954759d37e26a3627e2278137595be80e3a860c4353e4335e5a0
+CURL_TARBALL := curl-8.10.0.tar.xz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
diff --git a/external/curl/zlib.patch.0 b/external/curl/zlib.patch.0
index ff3ed07b4465..83993fe8a56f 100644
--- a/external/curl/zlib.patch.0
+++ b/external/curl/zlib.patch.0
@@ -8,18 +8,18 @@
  
  # Check whether --with-zlib was given.
  if test ${with_zlib+y}
-@@ -23045,6 +23044,7 @@
+@@ -23609,12 +23609,28 @@
  
  
- if test "$OPT_ZLIB" = "no" ; then
-+    ZLIB_LIBS=""
-     { printf "%s
" "$as_me:${as_lineno-$LINENO}: WARNING: zlib disabled" >&5
+ if test "$OPT_ZLIB" = "no"; then
++  ZLIB_LIBS=""
+   { printf "%s
" "$as_me:${as_lineno-$LINENO}: WARNING: zlib disabled" >&5
  printf "%s
" "$as_me: WARNING: zlib disabled" >&2;}
  else
-@@ -23052,6 +23052,21 @@
+   if test "$OPT_ZLIB" = "yes"; then
      OPT_ZLIB=""
    fi
- 
++  
 + if test -n "$ZLIB_CFLAGS$ZLIB_LIBS"; then
 +  CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS"
 +  LIBS="$ZLIB_LIBS $LIBS"
@@ -34,10 +34,9 @@
 +  AMFIXLIB="1"
 + else
 +  ZLIB_LIBS=""
-+
-   if test -z "$OPT_ZLIB" ; then
  
-     if test -n "$PKG_CONFIG"; then
+   if test -z "$OPT_ZLIB"; then
+
 @@ -23903,6 +23903,7 @@
      LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE zlib"
      curl_zlib_msg="enabled"
@@ -48,21 +47,22 @@
   if test x"$AMFIXLIB" = x1; then
 --- configure.ac
 +++ configure.ac
-@@ -1243,19 +1243,30 @@
+@@ -1302,19 +1302,31 @@
  clean_CPPFLAGS=$CPPFLAGS
  clean_LDFLAGS=$LDFLAGS
  clean_LIBS=$LIBS
 -ZLIB_LIBS=""
++
  AC_ARG_WITH(zlib,
  AS_HELP_STRING([--with-zlib=PATH],[search for zlib in PATH])
  AS_HELP_STRING([--without-zlib],[disable use of zlib]),
-                [OPT_ZLIB="$withval"])
+   [OPT_ZLIB="$withval"])
  
- if test "$OPT_ZLIB" = "no" ; then
-+    ZLIB_LIBS=""
-     AC_MSG_WARN([zlib disabled])
+ if test "$OPT_ZLIB" = "no"; then
++  ZLIB_LIBS=""
+   AC_MSG_WARN([zlib disabled])
  else
-   if test "$OPT_ZLIB" = "yes" ; then
+   if test "$OPT_ZLIB" = "yes"; then
      OPT_ZLIB=""
    fi
  
@@ -77,7 +77,7 @@
 + else
 +  ZLIB_LIBS=""
 +
-   if test -z "$OPT_ZLIB" ; then
+   if test -z "$OPT_ZLIB"; then
      CURL_CHECK_PKGCONFIG(zlib)
  
 @@ -1395,6 +1395,7 @@
commit ea1f31127edfa57ea246fa5340ec0de3ae8ee09f
Author:     Xisco Fauli <[email protected]>
AuthorDate: Wed Jul 31 11:44:49 2024 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:54:33 2026 +0100

    curl: upgrade to 8.9.1
    
    Downloaded from https://curl.se/download/curl-8.9.1.tar.xz
    
    Change-Id: I7a8ddd798c41ee6c9163b771b6c57f100fdc8af0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171292
    Tested-by: Jenkins
    Reviewed-by: Taichi Haradaguchi <[email protected]>
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172834
    Reviewed-by: Christian Lohmaier <[email protected]>
    Tested-by: Christian Lohmaier <[email protected]>
    (cherry picked from commit 221838f5c1bd4c444177fee4a6d6ba38be046b19)

diff --git a/download.lst b/download.lst
index 23e80a9c20db..bdc9cef845be 100644
--- a/download.lst
+++ b/download.lst
@@ -75,8 +75,8 @@ CPPUNIT_TARBALL := cppunit-1.15.1.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-CURL_SHA256SUM := 
ff09b2791ca56d25fd5c3f3a4927dce7c8a9dc4182200c487ca889fba1fdd412
-CURL_TARBALL := curl-8.9.0.tar.xz
+CURL_SHA256SUM := 
f292f6cc051d5bbabf725ef85d432dfeacc8711dd717ea97612ae590643801e5
+CURL_TARBALL := curl-8.9.1.tar.xz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
commit 5cfc7757513bbe85f0cabbf28f99f05d955dd634
Author:     Xisco Fauli <[email protected]>
AuthorDate: Wed Jul 24 12:43:09 2024 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:54:25 2026 +0100

    curl: upgrade to 8.9.0
    
    Downloaded from https://curl.se/download/curl-8.9.0.tar.xz
    
    Change-Id: Id8198dcc73e1679e8f672459b19d84606ae3e762
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170934
    Reviewed-by: Xisco Fauli <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit 282da64a8fbcc71b59479bf13820a0b93c5f5889)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170945
    Reviewed-by: Christian Lohmaier <[email protected]>
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172833
    Tested-by: Christian Lohmaier <[email protected]>
    (cherry picked from commit f4b1b192548695edbd19d43701ff6a21c69ce7c7)

diff --git a/download.lst b/download.lst
index bcb27086fe33..23e80a9c20db 100644
--- a/download.lst
+++ b/download.lst
@@ -75,8 +75,8 @@ CPPUNIT_TARBALL := cppunit-1.15.1.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-CURL_SHA256SUM := 
0f58bb95fc330c8a46eeb3df5701b0d90c9d9bfcc42bd1cd08791d12551d4400
-CURL_TARBALL := curl-8.8.0.tar.xz
+CURL_SHA256SUM := 
ff09b2791ca56d25fd5c3f3a4927dce7c8a9dc4182200c487ca889fba1fdd412
+CURL_TARBALL := curl-8.9.0.tar.xz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
diff --git a/external/curl/configurable-z-option.patch.0 
b/external/curl/configurable-z-option.patch.0
index 84516ad21917..5be2445e28c1 100644
--- a/external/curl/configurable-z-option.patch.0
+++ b/external/curl/configurable-z-option.patch.0
@@ -6,7 +6,7 @@
  CC_NODEBUG  = $(CC) /O2 /DNDEBUG
 -CC_DEBUG    = $(CC) /Od /Gm /Zi /D_DEBUG /GZ
 +CC_DEBUG    = $(CC) /Od /Gm $(DEBUG_FLAGS_VALUE) /D_DEBUG /GZ
- CFLAGS      = /I. /I../lib /I../include /nologo /W4 /GX /DWIN32 /YX /FD /c 
/DBUILDING_LIBCURL
+ CFLAGS      = /I. /I../lib /I../include /nologo /W4 /GX /YX /FD /c 
/DBUILDING_LIBCURL
  !ELSE
  CC_NODEBUG  = $(CC) /O2 /DNDEBUG
 @@ -64,7 +64,7 @@
diff --git a/external/curl/curl-msvc.patch.1 b/external/curl/curl-msvc.patch.1
index 54ad026ec8c7..2295b1b53ecf 100644
--- a/external/curl/curl-msvc.patch.1
+++ b/external/curl/curl-msvc.patch.1
@@ -6,22 +6,22 @@ MSVC: using SOLARINC
  !ELSE
  CC_NODEBUG  = $(CC) /O2 /DNDEBUG
  CC_DEBUG    = $(CC) /Od /D_DEBUG /RTC1 /Z7 /LDd
--CFLAGS      = /I. /I ../lib /I../include /nologo /W4 /EHsc /DWIN32 /FD /c 
/DBUILDING_LIBCURL
-+CFLAGS      = /I. /I ../lib /I../include /nologo /W4 /EHsc /DWIN32 /FD /c 
/DBUILDING_LIBCURL $(SOLARINC)
+-CFLAGS      = /I. /I ../lib /I../include /nologo /W4 /EHsc /FD /c 
/DBUILDING_LIBCURL
++CFLAGS      = /I. /I ../lib /I../include /nologo /W4 /EHsc /FD /c 
/DBUILDING_LIBCURL $(SOLARINC)
  !ENDIF
  
  LFLAGS     = /nologo /machine:$(MACHINE)
-@@ -426,11 +426,11 @@
+@@ -428,11 +428,11 @@
  # CURL_XX macros are for the curl.exe command
  
  !IF "$(DEBUG)"=="yes"
--RC_FLAGS = /dDEBUGBUILD=1 /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc
-+RC_FLAGS = $(SOLARINC) /dDEBUGBUILD=1 /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc
+-RC_FLAGS = /d_DEBUG /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc
++RC_FLAGS = $(SOLARINC) /d_DEBUG /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc
  CURL_CC       = $(CC_DEBUG) $(RTLIB_DEBUG)
- CURL_RC_FLAGS = $(CURL_RC_FLAGS) /i../include /dDEBUGBUILD=1 /Fo $@ 
$(CURL_SRC_DIR)+ CURL_RC_FLAGS = $(CURL_RC_FLAGS) /i../include /d_DEBUG /Fo $@ 
$(CURL_SRC_DIR)  !ELSE
--RC_FLAGS = /dDEBUGBUILD=0 /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc
-+RC_FLAGS = $(SOLARINC) /dDEBUGBUILD=0 /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc
+-RC_FLAGS = /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc
++RC_FLAGS = $(SOLARINC) /Fo $@ $(LIBCURL_SRC_DIR)\libcurl.rc
  CURL_CC       = $(CC_NODEBUG) $(RTLIB)
- CURL_RC_FLAGS = $(CURL_RC_FLAGS) /i../include /dDEBUGBUILD=0 /Fo $@ 
$(CURL_SRC_DIR)+ CURL_RC_FLAGS = $(CURL_RC_FLAGS) /i../include /Fo $@ 
$(CURL_SRC_DIR)  !ENDIF
diff --git a/external/curl/zlib.patch.0 b/external/curl/zlib.patch.0
index b4442ba262d1..ff3ed07b4465 100644
--- a/external/curl/zlib.patch.0
+++ b/external/curl/zlib.patch.0
@@ -38,8 +38,8 @@
    if test -z "$OPT_ZLIB" ; then
  
      if test -n "$PKG_CONFIG"; then
-@@ -23344,6 +23359,7 @@
- printf "%s
" "$as_me: found both libz and libz.h header" >&6;}
+@@ -23903,6 +23903,7 @@
+     LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE zlib"
      curl_zlib_msg="enabled"
    fi
 + fi
@@ -80,8 +80,8 @@
    if test -z "$OPT_ZLIB" ; then
      CURL_CHECK_PKGCONFIG(zlib)
  
-@@ -1336,6 +1347,7 @@
-     AC_MSG_NOTICE([found both libz and libz.h header])
+@@ -1395,6 +1395,7 @@
+     LIBCURL_PC_REQUIRES_PRIVATE="$LIBCURL_PC_REQUIRES_PRIVATE zlib"
      curl_zlib_msg="enabled"
    fi
 + fi
commit bcfed4e288f7b01470eccbf07f0a733ead1c271b
Author:     Xisco Fauli <[email protected]>
AuthorDate: Wed May 22 11:46:17 2024 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:54:14 2026 +0100

    curl: Upgrade to 8.8.0
    
    Downloaded from https://curl.se/download/curl-8.8.0.tar.xz
    
    Change-Id: Ib6ecbdb774f4d2643d8e848d8826704a51884eac
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167929
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <[email protected]>
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172832
    Reviewed-by: Taichi Haradaguchi <[email protected]>
    (cherry picked from commit a68d1d75ad11c41396a2c2c3437cdef48a3454e6)

diff --git a/download.lst b/download.lst
index f26e0ce50f3c..bcb27086fe33 100644
--- a/download.lst
+++ b/download.lst
@@ -75,8 +75,8 @@ CPPUNIT_TARBALL := cppunit-1.15.1.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-CURL_SHA256SUM := 
6fea2aac6a4610fbd0400afb0bcddbe7258a64c63f1f68e5855ebc0c659710cd
-CURL_TARBALL := curl-8.7.1.tar.xz
+CURL_SHA256SUM := 
0f58bb95fc330c8a46eeb3df5701b0d90c9d9bfcc42bd1cd08791d12551d4400
+CURL_TARBALL := curl-8.8.0.tar.xz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
diff --git a/external/curl/curl-msvc-disable-protocols.patch.1 
b/external/curl/curl-msvc-disable-protocols.patch.1
index 71ff0c01a028..55970b2757b3 100644
--- a/external/curl/curl-msvc-disable-protocols.patch.1
+++ b/external/curl/curl-msvc-disable-protocols.patch.1
@@ -2,9 +2,9 @@ disable protocols nobody needs in MSVC build
 
 --- curl/lib/config-win32.h.orig       2017-08-09 16:43:29.464000000 +0200
 +++ curl/lib/config-win32.h    2017-08-09 16:47:38.549200000 +0200
-@@ -654,4 +654,20 @@
- #  define ENABLE_IPV6 1
- #endif
+@@ -509,4 +509,20 @@
+ /* If you want to build curl with the built-in manual */
+ #define USE_MANUAL 1
  
 +#define CURL_DISABLE_DICT 1
 +#define CURL_DISABLE_FILE 1
commit 39aeb272ad9bb41869739775a29c79afaf75124f
Author:     Xisco Fauli <[email protected]>
AuthorDate: Thu Mar 28 11:40:25 2024 +0100
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:53:41 2026 +0100

    curl: upgrade to release 8.7.1
    
    Change-Id: I0064b4cf6baf1ccd951c95945539961fe72c2a28
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165455
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <[email protected]>
    (cherry picked from commit 2c1a7cb13629177f824ed35138907aef10714e89)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165489
    Reviewed-by: Taichi Haradaguchi <[email protected]>
    (cherry picked from commit c5e991b8103caaebb4c83adb2d62d51b8f13aad6)

diff --git a/download.lst b/download.lst
index 5bd7a6282dd9..f26e0ce50f3c 100644
--- a/download.lst
+++ b/download.lst
@@ -75,8 +75,8 @@ CPPUNIT_TARBALL := cppunit-1.15.1.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-CURL_SHA256SUM := 
3ccd55d91af9516539df80625f818c734dc6f2ecf9bada33c76765e99121db15
-CURL_TARBALL := curl-8.6.0.tar.xz
+CURL_SHA256SUM := 
6fea2aac6a4610fbd0400afb0bcddbe7258a64c63f1f68e5855ebc0c659710cd
+CURL_TARBALL := curl-8.7.1.tar.xz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
commit e40f4bf2165cc916472398fbcf4752809c07811b
Author:     Xisco Fauli <[email protected]>
AuthorDate: Mon Mar 31 10:29:29 2025 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:46:26 2026 +0100

    postgresql: upgrade to 15.15
    
    According to https://www.postgresql.org/support/versioning/
    the last release of branch 14 is on November 12, 2026
    Upgrade master branch to branch 15 to avoid reaching the EOL
    
    Downloaded from 
https://ftp.postgresql.org/pub/source/v15.15/postgresql-15.15.tar.bz2
    
    Change-Id: Iff451dcc6f1f4dfaa763869056e610eee4a946d7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193978
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <[email protected]>
    (cherry picked from commit 1b89a45baa7214977350ea6558b2c2f3af6c4a1a)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196914
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    (cherry picked from commit 0ffbbec9fa9062cb7600e3f3896091e3b35e667e)

diff --git a/download.lst b/download.lst
index 900732f155df..5bd7a6282dd9 100644
--- a/download.lst
+++ b/download.lst
@@ -529,8 +529,8 @@ POPPLER_DATA_TARBALL := poppler-data-0.4.12.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-POSTGRESQL_SHA256SUM := 
727e9e334bc1a31940df808259f69fe47a59f6d42174b22ae62d67fe7a01ad80
-POSTGRESQL_TARBALL := postgresql-14.19.tar.bz2
+POSTGRESQL_SHA256SUM := 
5753aaeb8b09cbf61016f78aa69bf5cbdf01b43263f010cbf168c82896213aaa
+POSTGRESQL_TARBALL := postgresql-15.15.tar.bz2
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
commit a1cc47f0edbbca24cbecb789fa14b3b22a600f29
Author:     Xisco Fauli <[email protected]>
AuthorDate: Tue Jun 11 17:05:14 2024 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:46:19 2026 +0100

    postgresql: upgrade to 14.19
    
    Postgres 13 will reach the EOL in November 13, 2025
    https://www.postgresql.org/support/versioning/ so upgrade it
    now after the creation of the libreoffice-24-8 branch towards
    LibreOffice 25.2
    
    * 
external/postgresql/0001-Assume-that-stdbool.h-conforms-to-the-C-standard.patch.1
    has been fixed upstream
    
    Downloaded from 
https://ftp.postgresql.org/pub/source/v14.19/postgresql-14.19.tar.bz2
    
    Change-Id: Ied1619e7a8c01fee9ad137ac5edc5e5869bd278c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189648
    Reviewed-by: Taichi Haradaguchi <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit f16e982bdf85427e1cba1fe300bf1f5a1b76d6e2)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196913
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    (cherry picked from commit eb35b12e6e377176122bc1e9523bfe6f3b1052b5)

diff --git a/download.lst b/download.lst
index 73f203d30e54..900732f155df 100644
--- a/download.lst
+++ b/download.lst
@@ -529,8 +529,8 @@ POPPLER_DATA_TARBALL := poppler-data-0.4.12.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-POSTGRESQL_SHA256SUM := 
c9cbbb6129f02328204828066bb3785c00a85c8ca8fd329c2a8a53c1f5cd8865
-POSTGRESQL_TARBALL := postgresql-13.16.tar.bz2
+POSTGRESQL_SHA256SUM := 
727e9e334bc1a31940df808259f69fe47a59f6d42174b22ae62d67fe7a01ad80
+POSTGRESQL_TARBALL := postgresql-14.19.tar.bz2
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
diff --git 
a/external/postgresql/0001-Assume-that-stdbool.h-conforms-to-the-C-standard.patch.1
 
b/external/postgresql/0001-Assume-that-stdbool.h-conforms-to-the-C-standard.patch.1
deleted file mode 100644
index 669b9a567d2f..000000000000
--- 
a/external/postgresql/0001-Assume-that-stdbool.h-conforms-to-the-C-standard.patch.1
+++ /dev/null
@@ -1,397 +0,0 @@
-From d5fb5a35816df670d329600e44fe22617b578415 Mon Sep 17 00:00:00 2001
-From: Thomas Munro <[email protected]>
-Date: Mon, 25 Nov 2024 13:11:28 +1300
-Subject: Assume that <stdbool.h> conforms to the C standard.
-
-Previously we checked "for <stdbool.h> that conforms to C99" using
-autoconf's AC_HEADER_STDBOOL macro.  We've required C99 since PostgreSQL
-12, so the test was redundant, and under C23 it was broken: autoconf
-2.69's implementation doesn't understand C23's new empty header (the
-macros it's looking for went away, replaced by language keywords).
-Later autoconf versions fixed that, but let's just remove the
-anachronistic test.
-
-HAVE_STDBOOL_H and HAVE__BOOL will no longer be defined, but they
-weren't directly tested in core or likely extensions (except in 11, see
-below).  PG_USE_STDBOOL (or USE_STDBOOL in 11 and 12) is still defined
-when sizeof(bool) is 1, which should be true on all modern systems.
-Otherwise we define our own bool type and values of size 1, which would
-fail to compile under C23 as revealed by the broken test.  (We'll
-probably clean that dead code up in master, but here we want a minimal
-back-patchable change.)
-
-This came to our attention when GCC 15 recently started using using C23
-by default and failed to compile the replacement code, as reported by
-Sam James and build farm animal alligator.
-
-Back-patch to all supported releases, and then two older versions that
-also know about <stdbool.h>, per the recently-out-of-support policy[1].
-12 requires C99 so it's much like the supported releases, but 11 only
-assumes C89 so it now uses AC_CHECK_HEADERS instead of the overly picky
-AC_HEADER_STDBOOL.  (I could find no discussion of which historical
-systems had <stdbool.h> but failed the conformance test; if they ever
-existed, they surely aren't relevant to that policy's goals.)
-
-[1] https://wiki.postgresql.org/wiki/Committing_checklist#Policies
-
-Reported-by: Sam James <[email protected]>
-Reviewed-by: Peter Eisentraut <[email protected]> (master version)
-Reviewed-by: Tom Lane <[email protected]> (approach)
-Discussion: 
https://www.postgresql.org/message-id/flat/87o72eo9iu.fsf%40gentoo.org
-(cherry picked from commit bc5a4dfcf7390145dc3ba3c1c18c5ce561b778cd)
-Conflicts:
-       configure
-       meson.build
-       src/include/pg_config.h.in
-       src/tools/msvc/Solution.pm
----
- configure                  | 182 +++++++++----------------------------
- configure.ac               |  13 +--
- src/include/c.h            |   2 +-
- src/include/pg_config.h.in |   6 --
- src/tools/msvc/Solution.pm |   2 -
- 5 files changed, 48 insertions(+), 157 deletions(-)
-
-diff --git a/configure b/configure
-index 7e6030e9e1..7a5bdeddbd 100755
---- a/configure
-+++ b/configure
-@@ -2085,116 +2085,116 @@ $as_echo "$ac_res" >&6; }
- 
- } # ac_fn_c_check_func
- 
--# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
--# -------------------------------------------
--# Tests whether TYPE exists after having included INCLUDES, setting cache
--# variable VAR accordingly.
--ac_fn_c_check_type ()
-+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
-+# ----------------------------------------------------
-+# Tries to find if the field MEMBER exists in type AGGR, after including
-+# INCLUDES, setting cache variable VAR accordingly.
-+ac_fn_c_check_member ()
- {
-   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
--  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
--$as_echo_n "checking for $2... " >&6; }
--if eval \${$3+:} false; then :
-+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
-+$as_echo_n "checking for $2.$3... " >&6; }
-+if eval \${$4+:} false; then :
-   $as_echo_n "(cached) " >&6
- else
--  eval "$3=no"
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
- /* end confdefs.h.  */
--$4
-+$5
- int
- main ()
- {
--if (sizeof ($2))
--       return 0;
-+static $2 ac_aggr;
-+if (ac_aggr.$3)
-+return 0;
-   ;
-   return 0;
- }
- _ACEOF
- if ac_fn_c_try_compile "$LINENO"; then :
-+  eval "$4=yes"
-+else
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
- /* end confdefs.h.  */
--$4
-+$5
- int
- main ()
- {
--if (sizeof (($2)))
--          return 0;
-+static $2 ac_aggr;
-+if (sizeof ac_aggr.$3)
-+return 0;
-   ;
-   return 0;
- }
- _ACEOF
- if ac_fn_c_try_compile "$LINENO"; then :
--
-+  eval "$4=yes"
- else
--  eval "$3=yes"
-+  eval "$4=no"
- fi
- rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
- rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
--eval ac_res=\$$3
-+eval ac_res=\$$4
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
- $as_echo "$ac_res" >&6; }
-   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- 
--} # ac_fn_c_check_type
-+} # ac_fn_c_check_member
- 
--# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
--# ----------------------------------------------------
--# Tries to find if the field MEMBER exists in type AGGR, after including
--# INCLUDES, setting cache variable VAR accordingly.
--ac_fn_c_check_member ()
-+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
-+# -------------------------------------------
-+# Tests whether TYPE exists after having included INCLUDES, setting cache
-+# variable VAR accordingly.
-+ac_fn_c_check_type ()
- {
-   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
--  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
--$as_echo_n "checking for $2.$3... " >&6; }
--if eval \${$4+:} false; then :
-+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-+$as_echo_n "checking for $2... " >&6; }
-+if eval \${$3+:} false; then :
-   $as_echo_n "(cached) " >&6
- else
-+  eval "$3=no"
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
- /* end confdefs.h.  */
--$5
-+$4
- int
- main ()
- {
--static $2 ac_aggr;
--if (ac_aggr.$3)
--return 0;
-+if (sizeof ($2))
-+       return 0;
-   ;
-   return 0;
- }
- _ACEOF
- if ac_fn_c_try_compile "$LINENO"; then :
--  eval "$4=yes"
--else
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
- /* end confdefs.h.  */
--$5
-+$4
- int
- main ()
- {
--static $2 ac_aggr;
--if (sizeof ac_aggr.$3)
--return 0;
-+if (sizeof (($2)))
-+          return 0;
-   ;
-   return 0;
- }
- _ACEOF
- if ac_fn_c_try_compile "$LINENO"; then :
--  eval "$4=yes"
-+
- else
--  eval "$4=no"
-+  eval "$3=yes"
- fi
- rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
- rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- fi
--eval ac_res=\$$4
-+eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
- $as_echo "$ac_res" >&6; }
-   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- 
--} # ac_fn_c_check_member
-+} # ac_fn_c_check_type
- 
- # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
- # --------------------------------------------
-@@ -13746,100 +13746,6 @@ fi
- ## Header files
- ##
- 
--{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms 
to C99" >&5
--$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
--if ${ac_cv_header_stdbool_h+:} false; then :
--  $as_echo_n "(cached) " >&6
--else
--  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
--/* end confdefs.h.  */
--
--             #include <stdbool.h>
--             #ifndef bool
--              "error: bool is not defined"
--             #endif
--             #ifndef false
--              "error: false is not defined"
--             #endif
--             #if false
--              "error: false is not 0"
--             #endif
--             #ifndef true
--              "error: true is not defined"
--             #endif
--             #if true != 1
--              "error: true is not 1"
--             #endif
--             #ifndef __bool_true_false_are_defined
--              "error: __bool_true_false_are_defined is not defined"
--             #endif
--
--             struct s { _Bool s: 1; _Bool t; } s;
--
--             char a[true == 1 ? 1 : -1];
--             char b[false == 0 ? 1 : -1];
--             char c[__bool_true_false_are_defined == 1 ? 1 : -1];
--             char d[(bool) 0.5 == true ? 1 : -1];
--             /* See body of main program for 'e'.  */
--             char f[(_Bool) 0.0 == false ? 1 : -1];
--             char g[true];
--             char h[sizeof (_Bool)];
--             char i[sizeof s.t];
--             enum { j = false, k = true, l = false * true, m = true * 256 };
--             /* The following fails for
--                HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
--             _Bool n[m];
--             char o[sizeof n == m * sizeof n[0] ? 1 : -1];
--             char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
--             /* Catch a bug in an HP-UX C compiler.  See
--                http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
--                
http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
--              */
--             _Bool q = true;
--             _Bool *pq = &q;
--
--int
--main ()
--{
--
--             bool e = &s;
--             *pq |= q;
--             *pq |= ! q;
--             /* Refer to every declared value, to avoid compiler 
optimizations.  */
--             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + 
!!l
--                     + !m + !n + !o + !p + !q + !pq);
--
--  ;
--  return 0;
--}
--_ACEOF
--if ac_fn_c_try_compile "$LINENO"; then :
--  ac_cv_header_stdbool_h=yes
--else
--  ac_cv_header_stdbool_h=no
--fi
--rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
--fi
--{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
--$as_echo "$ac_cv_header_stdbool_h" >&6; }
--   ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" 
"$ac_includes_default"
--if test "x$ac_cv_type__Bool" = xyes; then :
--
--cat >>confdefs.h <<_ACEOF
--#define HAVE__BOOL 1
--_ACEOF
--
--
--fi
--
--
--if test $ac_cv_header_stdbool_h = yes; then
--
--$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
--
--fi
--
--
- for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h 
mbarrier.h poll.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h 
sys/prctl.h sys/procctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h 
sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h wctype.h
- do :
-   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-@@ -15711,9 +15617,7 @@ $as_echo_n "checking size of bool... " >&6; }
- if ${ac_cv_sizeof_bool+:} false; then :
-   $as_echo_n "(cached) " >&6
- else
--  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (bool))" 
"ac_cv_sizeof_bool"        "#ifdef HAVE_STDBOOL_H
--#include <stdbool.h>
--#endif
-+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (bool))" 
"ac_cv_sizeof_bool"        "#include <stdbool.h>
- "; then :
- 
- else
-@@ -15739,7 +15643,7 @@ _ACEOF
- 
- 
- 
--if test "$ac_cv_header_stdbool_h" = yes -a "$ac_cv_sizeof_bool" = 1; then
-+if test "$ac_cv_sizeof_bool" = 1; then
- 
- $as_echo "#define PG_USE_STDBOOL 1" >>confdefs.h
- 
-diff --git a/src/include/c.h b/src/include/c.h
-index dd2e3b0f3e..cc19c23fb6 100644
---- a/src/include/c.h
-+++ b/src/include/c.h
-@@ -398,7 +398,7 @@ typedef void (*pg_funcptr_t) (void);
-  * bool
-  *            Boolean value, either true or false.
-  *
-- * We use stdbool.h if available and its bool has size 1.  That's useful for
-+ * We use stdbool.h if bool has size 1 after including it.  That's useful for
-  * better compiler and debugger output and for compatibility with third-party
-  * libraries.  But PostgreSQL currently cannot deal with bool of other sizes;
-  * there are static assertions around the code to prevent that.
-diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
-index 99e3731813..d9ef9a41bf 100644
---- a/src/include/pg_config.h.in
-+++ b/src/include/pg_config.h.in
-@@ -517,9 +517,6 @@
- /* Define to 1 if you have the `SSL_CTX_set_num_tickets' function. */
- #undef HAVE_SSL_CTX_SET_NUM_TICKETS
- 
--/* Define to 1 if stdbool.h conforms to C99. */
--#undef HAVE_STDBOOL_H
--
- /* Define to 1 if you have the <stdint.h> header file. */
- #undef HAVE_STDINT_H
- 
-@@ -730,9 +727,6 @@
- /* Define to 1 if the assembler supports X86_64's POPCNTQ instruction. */
- #undef HAVE_X86_64_POPCNTQ
- 
--/* Define to 1 if the system has the type `_Bool'. */
--#undef HAVE__BOOL
--
- /* Define to 1 if your compiler understands __builtin_bswap16. */
- #undef HAVE__BUILTIN_BSWAP16
- 
-diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
-index 07cc7b7ba2..f0ce2ac804 100644
---- a/src/tools/msvc/Solution.pm
-+++ b/src/tools/msvc/Solution.pm
-@@ -365,7 +365,6 @@ sub GenerateFiles
-               HAVE_SPINLOCKS                           => 1,
-               HAVE_SSL_CTX_SET_NUM_TICKETS             => undef,
-               HAVE_SRANDOM                             => undef,
--              HAVE_STDBOOL_H                           => 1,
-               HAVE_STDINT_H                            => 1,
-               HAVE_STDLIB_H                            => 1,
-               HAVE_STRCHRNUL                           => undef,
-@@ -436,7 +435,6 @@ sub GenerateFiles
-               HAVE_X509_GET_SIGNATURE_NID              => 1,
-               HAVE_X509_GET_SIGNATURE_INFO             => undef,
-               HAVE_X86_64_POPCNTQ                      => undef,
--              HAVE__BOOL                               => undef,
-               HAVE__BUILTIN_BSWAP16                    => undef,
-               HAVE__BUILTIN_BSWAP32                    => undef,
-               HAVE__BUILTIN_BSWAP64                    => undef,
--- 
-2.47.0
-
diff --git a/external/postgresql/UnpackedTarball_postgresql.mk 
b/external/postgresql/UnpackedTarball_postgresql.mk
index 44528b78d26f..11fb603ef34f 100644
--- a/external/postgresql/UnpackedTarball_postgresql.mk
+++ b/external/postgresql/UnpackedTarball_postgresql.mk
@@ -17,7 +17,6 @@ $(eval $(call gb_UnpackedTarball_add_patches,postgresql, \
        external/postgresql/windows.patch.0 \
        external/postgresql/postgresql.exit.patch.0 \
        external/postgresql/postgres-msvc-build.patch.1 \
-       
external/postgresql/0001-Assume-that-stdbool.h-conforms-to-the-C-standard.patch.1
 \
        $(if $(filter WNT_AARCH64,$(OS)_$(CPUNAME)), 
external/postgresql/arm64.patch.1) \
 ))
 
diff --git a/external/postgresql/postgres-msvc-build.patch.1 
b/external/postgresql/postgres-msvc-build.patch.1
index dec31742238e..161ea7e91daf 100644
--- a/external/postgresql/postgres-msvc-build.patch.1
+++ b/external/postgresql/postgres-msvc-build.patch.1
@@ -33,7 +33,7 @@ Also Cygwin perl has $Config{osname} different from MSWin32, 
and why even check
                libraries             => [],
 --- postgresql/src/tools/msvc/Solution.pm.orig 2021-01-19 18:03:04.594229100 
+0100
 +++ postgresql/src/tools/msvc/Solution.pm      2021-01-19 18:04:13.677610100 
+0100
-@@ -59,7 +59,7 @@
+@@ -62,7 +62,7 @@
  {
        my $self = shift;
  
@@ -41,7 +41,7 @@ Also Cygwin perl has $Config{osname} different from MSWin32, 
and why even check
 +      if (1) #($^O eq "MSWin32")
        {
                # Examine CL help output to determine if we are in 32 or 64-bit 
mode.
-               my $output = `cl /? 2>&1`;
+               my $output = `cl /help 2>&1`;
 @@ -1100,7 +1100,7 @@
                }
                if ($fld ne "")
commit ea8c7e39e7a51f093624b21ccdb5817cbbe6e479
Author:     Stephan Bergmann <[email protected]>
AuthorDate: Mon Nov 25 18:12:39 2024 +0100
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:45:27 2026 +0100

    external/postgresql: Include configure fix for C23 stdbool.h
    
    ...by backporting upstream
    
<https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=bc5a4dfcf7390145dc3ba3c1c18c5ce561b778cd>
    "Assume that <stdbool.h> conforms to the C standard." to our REL_14_15 
version.
    GCC 15 trunk defaults to C23 now, so started to fail with
    
    > In file included from fls.c:49:
    > ../../src/include/c.h:419:23: error: two or more data types in 
declaration specifiers
    >   419 | typedef unsigned char bool;
    >       |                       ^~~~
    > ../../src/include/c.h:419:1: warning: useless type name in empty 
declaration
    >   419 | typedef unsigned char bool;
    >       | ^~~~~~~
    > make: *** [<builtin>: fls.o] Error 1
    > make: Leaving directory 'workdir/UnpackedTarball/postgresql/src/port'
    
    (Removing HAVE__BOOL and HAVE_STDBOOL_H also from 
src/tools/msvc/Solution.pm is
    necessary to avoid failures like
    
    > 
"C:/cygwin64/home/tdf/jenkins/workspace/gerrit_windows/workdir/UnpackedTarball/opensslpps\openssl.exe"
 version 2>&1unused defines: HAVE_STDBOOL_H HAVE__BOOL at 
/home/tdf/jenkins/workspace/gerrit_windows/workdir/UnpackedTarball/postgresql/src/tools/msvc/Mkvcbuild.pm
 line 870.
    > make[1]: *** 
[C:/cygwin64/home/tdf/jenkins/workspace/gerrit_windows/external/postgresql/ExternalProject_postgresql.mk:27:
 
C:/cygwin64/home/tdf/jenkins/workspace/gerrit_windows/workdir/ExternalProject/postgresql/build]
 Error 1
    
    in MSVC builds.)
    
    Change-Id: I1f6bd0d613ae4d6ce70feaaf67aaf95496eeff87
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177280
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit ea0b06415b35ff68959c8fb24355f2c15ad63e64)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191779
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    (cherry picked from commit 330310788014b894b4e78c66e7fe4c4974437b81)

diff --git 
a/external/postgresql/0001-Assume-that-stdbool.h-conforms-to-the-C-standard.patch.1
 
b/external/postgresql/0001-Assume-that-stdbool.h-conforms-to-the-C-standard.patch.1
new file mode 100644
index 000000000000..669b9a567d2f
--- /dev/null
+++ 
b/external/postgresql/0001-Assume-that-stdbool.h-conforms-to-the-C-standard.patch.1
@@ -0,0 +1,397 @@
+From d5fb5a35816df670d329600e44fe22617b578415 Mon Sep 17 00:00:00 2001
+From: Thomas Munro <[email protected]>
+Date: Mon, 25 Nov 2024 13:11:28 +1300
+Subject: Assume that <stdbool.h> conforms to the C standard.
+
+Previously we checked "for <stdbool.h> that conforms to C99" using
+autoconf's AC_HEADER_STDBOOL macro.  We've required C99 since PostgreSQL
+12, so the test was redundant, and under C23 it was broken: autoconf
+2.69's implementation doesn't understand C23's new empty header (the
+macros it's looking for went away, replaced by language keywords).
+Later autoconf versions fixed that, but let's just remove the
+anachronistic test.
+
+HAVE_STDBOOL_H and HAVE__BOOL will no longer be defined, but they
+weren't directly tested in core or likely extensions (except in 11, see
+below).  PG_USE_STDBOOL (or USE_STDBOOL in 11 and 12) is still defined
+when sizeof(bool) is 1, which should be true on all modern systems.
+Otherwise we define our own bool type and values of size 1, which would
+fail to compile under C23 as revealed by the broken test.  (We'll
+probably clean that dead code up in master, but here we want a minimal
+back-patchable change.)
+
+This came to our attention when GCC 15 recently started using using C23
+by default and failed to compile the replacement code, as reported by
+Sam James and build farm animal alligator.
+
+Back-patch to all supported releases, and then two older versions that
+also know about <stdbool.h>, per the recently-out-of-support policy[1].
+12 requires C99 so it's much like the supported releases, but 11 only
+assumes C89 so it now uses AC_CHECK_HEADERS instead of the overly picky
+AC_HEADER_STDBOOL.  (I could find no discussion of which historical
+systems had <stdbool.h> but failed the conformance test; if they ever
+existed, they surely aren't relevant to that policy's goals.)
+
+[1] https://wiki.postgresql.org/wiki/Committing_checklist#Policies
+
+Reported-by: Sam James <[email protected]>
+Reviewed-by: Peter Eisentraut <[email protected]> (master version)
+Reviewed-by: Tom Lane <[email protected]> (approach)
+Discussion: 
https://www.postgresql.org/message-id/flat/87o72eo9iu.fsf%40gentoo.org
+(cherry picked from commit bc5a4dfcf7390145dc3ba3c1c18c5ce561b778cd)
+Conflicts:
+       configure
+       meson.build
+       src/include/pg_config.h.in
+       src/tools/msvc/Solution.pm
+---
+ configure                  | 182 +++++++++----------------------------
+ configure.ac               |  13 +--
+ src/include/c.h            |   2 +-
+ src/include/pg_config.h.in |   6 --
+ src/tools/msvc/Solution.pm |   2 -
+ 5 files changed, 48 insertions(+), 157 deletions(-)
+
+diff --git a/configure b/configure
+index 7e6030e9e1..7a5bdeddbd 100755
+--- a/configure
++++ b/configure
+@@ -2085,116 +2085,116 @@ $as_echo "$ac_res" >&6; }
+ 
+ } # ac_fn_c_check_func
+ 
+-# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+-# -------------------------------------------
+-# Tests whether TYPE exists after having included INCLUDES, setting cache
+-# variable VAR accordingly.
+-ac_fn_c_check_type ()
++# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
++# ----------------------------------------------------
++# Tries to find if the field MEMBER exists in type AGGR, after including
++# INCLUDES, setting cache variable VAR accordingly.
++ac_fn_c_check_member ()
+ {
+   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+-$as_echo_n "checking for $2... " >&6; }
+-if eval \${$3+:} false; then :
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
++$as_echo_n "checking for $2.$3... " >&6; }
++if eval \${$4+:} false; then :
+   $as_echo_n "(cached) " >&6
+ else
+-  eval "$3=no"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+-$4
++$5
+ int
+ main ()
+ {
+-if (sizeof ($2))
+-       return 0;
++static $2 ac_aggr;
++if (ac_aggr.$3)
++return 0;
+   ;
+   return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
++  eval "$4=yes"
++else
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+-$4
++$5
+ int
+ main ()
+ {
+-if (sizeof (($2)))
+-          return 0;
++static $2 ac_aggr;
++if (sizeof ac_aggr.$3)
++return 0;
+   ;
+   return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+-
++  eval "$4=yes"
+ else
+-  eval "$3=yes"
++  eval "$4=no"
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+-eval ac_res=\$$3
++eval ac_res=\$$4
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+ $as_echo "$ac_res" >&6; }
+   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ 
+-} # ac_fn_c_check_type
++} # ac_fn_c_check_member
+ 
+-# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+-# ----------------------------------------------------
+-# Tries to find if the field MEMBER exists in type AGGR, after including
+-# INCLUDES, setting cache variable VAR accordingly.
+-ac_fn_c_check_member ()
++# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
++# -------------------------------------------
++# Tests whether TYPE exists after having included INCLUDES, setting cache
++# variable VAR accordingly.
++ac_fn_c_check_type ()
+ {
+   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+-$as_echo_n "checking for $2.$3... " >&6; }
+-if eval \${$4+:} false; then :
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
++$as_echo_n "checking for $2... " >&6; }
++if eval \${$3+:} false; then :
+   $as_echo_n "(cached) " >&6
+ else
++  eval "$3=no"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+-$5
++$4
+ int
+ main ()
+ {
+-static $2 ac_aggr;
+-if (ac_aggr.$3)
+-return 0;
++if (sizeof ($2))
++       return 0;
+   ;
+   return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+-  eval "$4=yes"
+-else
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+-$5
++$4
+ int
+ main ()
+ {
+-static $2 ac_aggr;
+-if (sizeof ac_aggr.$3)
+-return 0;
++if (sizeof (($2)))
++          return 0;
+   ;
+   return 0;
+ }
+ _ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+-  eval "$4=yes"
++
+ else
+-  eval "$4=no"
++  eval "$3=yes"
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+-eval ac_res=\$$4
++eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+ $as_echo "$ac_res" >&6; }
+   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ 
+-} # ac_fn_c_check_member
++} # ac_fn_c_check_type
+ 
+ # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+ # --------------------------------------------
+@@ -13746,100 +13746,6 @@ fi
+ ## Header files
+ ##
+ 
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms 
to C99" >&5
+-$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
+-if ${ac_cv_header_stdbool_h+:} false; then :
+-  $as_echo_n "(cached) " >&6
+-else
+-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h.  */
+-
+-             #include <stdbool.h>
+-             #ifndef bool
+-              "error: bool is not defined"
+-             #endif
+-             #ifndef false
+-              "error: false is not defined"
+-             #endif
+-             #if false
+-              "error: false is not 0"
+-             #endif
+-             #ifndef true
+-              "error: true is not defined"
+-             #endif
+-             #if true != 1
+-              "error: true is not 1"
+-             #endif
+-             #ifndef __bool_true_false_are_defined
+-              "error: __bool_true_false_are_defined is not defined"
+-             #endif
+-
+-             struct s { _Bool s: 1; _Bool t; } s;
+-
+-             char a[true == 1 ? 1 : -1];
+-             char b[false == 0 ? 1 : -1];
+-             char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+-             char d[(bool) 0.5 == true ? 1 : -1];
+-             /* See body of main program for 'e'.  */
+-             char f[(_Bool) 0.0 == false ? 1 : -1];
+-             char g[true];
+-             char h[sizeof (_Bool)];
+-             char i[sizeof s.t];
+-             enum { j = false, k = true, l = false * true, m = true * 256 };
+-             /* The following fails for
+-                HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+-             _Bool n[m];
+-             char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+-             char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+-             /* Catch a bug in an HP-UX C compiler.  See
+-                http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+-                
http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+-              */
+-             _Bool q = true;
+-             _Bool *pq = &q;
+-
+-int
+-main ()
+-{
+-
+-             bool e = &s;
+-             *pq |= q;
+-             *pq |= ! q;
+-             /* Refer to every declared value, to avoid compiler 
optimizations.  */
+-             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + 
!!l
+-                     + !m + !n + !o + !p + !q + !pq);
+-
+-  ;
+-  return 0;
+-}
+-_ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
+-  ac_cv_header_stdbool_h=yes
+-else
+-  ac_cv_header_stdbool_h=no
+-fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+-fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
+-$as_echo "$ac_cv_header_stdbool_h" >&6; }
+-   ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" 
"$ac_includes_default"
+-if test "x$ac_cv_type__Bool" = xyes; then :
+-
+-cat >>confdefs.h <<_ACEOF
+-#define HAVE__BOOL 1
+-_ACEOF
+-
+-
+-fi
+-
+-
+-if test $ac_cv_header_stdbool_h = yes; then
+-
+-$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
+-
+-fi
+-
+-
+ for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h 
mbarrier.h poll.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h 
sys/prctl.h sys/procctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h 
sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h wctype.h
+ do :
+   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+@@ -15711,9 +15617,7 @@ $as_echo_n "checking size of bool... " >&6; }
+ if ${ac_cv_sizeof_bool+:} false; then :
+   $as_echo_n "(cached) " >&6
+ else
+-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (bool))" 
"ac_cv_sizeof_bool"        "#ifdef HAVE_STDBOOL_H
+-#include <stdbool.h>
+-#endif
++  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (bool))" 
"ac_cv_sizeof_bool"        "#include <stdbool.h>
+ "; then :
+ 
+ else
+@@ -15739,7 +15643,7 @@ _ACEOF
+ 
+ 
+ 
+-if test "$ac_cv_header_stdbool_h" = yes -a "$ac_cv_sizeof_bool" = 1; then
++if test "$ac_cv_sizeof_bool" = 1; then
+ 
+ $as_echo "#define PG_USE_STDBOOL 1" >>confdefs.h
+ 
+diff --git a/src/include/c.h b/src/include/c.h
+index dd2e3b0f3e..cc19c23fb6 100644
+--- a/src/include/c.h
++++ b/src/include/c.h
+@@ -398,7 +398,7 @@ typedef void (*pg_funcptr_t) (void);
+  * bool
+  *            Boolean value, either true or false.
+  *
+- * We use stdbool.h if available and its bool has size 1.  That's useful for
++ * We use stdbool.h if bool has size 1 after including it.  That's useful for
+  * better compiler and debugger output and for compatibility with third-party
+  * libraries.  But PostgreSQL currently cannot deal with bool of other sizes;
+  * there are static assertions around the code to prevent that.
+diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
+index 99e3731813..d9ef9a41bf 100644
+--- a/src/include/pg_config.h.in
++++ b/src/include/pg_config.h.in
+@@ -517,9 +517,6 @@
+ /* Define to 1 if you have the `SSL_CTX_set_num_tickets' function. */
+ #undef HAVE_SSL_CTX_SET_NUM_TICKETS
+ 
+-/* Define to 1 if stdbool.h conforms to C99. */
+-#undef HAVE_STDBOOL_H
+-
+ /* Define to 1 if you have the <stdint.h> header file. */
+ #undef HAVE_STDINT_H
+ 
+@@ -730,9 +727,6 @@
+ /* Define to 1 if the assembler supports X86_64's POPCNTQ instruction. */
+ #undef HAVE_X86_64_POPCNTQ
+ 
+-/* Define to 1 if the system has the type `_Bool'. */
+-#undef HAVE__BOOL
+-
+ /* Define to 1 if your compiler understands __builtin_bswap16. */
+ #undef HAVE__BUILTIN_BSWAP16
+ 
+diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
+index 07cc7b7ba2..f0ce2ac804 100644
+--- a/src/tools/msvc/Solution.pm
++++ b/src/tools/msvc/Solution.pm
+@@ -365,7 +365,6 @@ sub GenerateFiles
+               HAVE_SPINLOCKS                           => 1,
+               HAVE_SSL_CTX_SET_NUM_TICKETS             => undef,
+               HAVE_SRANDOM                             => undef,
+-              HAVE_STDBOOL_H                           => 1,
+               HAVE_STDINT_H                            => 1,
+               HAVE_STDLIB_H                            => 1,
+               HAVE_STRCHRNUL                           => undef,
+@@ -436,7 +435,6 @@ sub GenerateFiles
+               HAVE_X509_GET_SIGNATURE_NID              => 1,
+               HAVE_X509_GET_SIGNATURE_INFO             => undef,
+               HAVE_X86_64_POPCNTQ                      => undef,
+-              HAVE__BOOL                               => undef,
+               HAVE__BUILTIN_BSWAP16                    => undef,
+               HAVE__BUILTIN_BSWAP32                    => undef,
+               HAVE__BUILTIN_BSWAP64                    => undef,
+-- 
+2.47.0
+
diff --git a/external/postgresql/UnpackedTarball_postgresql.mk 
b/external/postgresql/UnpackedTarball_postgresql.mk
index 11fb603ef34f..44528b78d26f 100644
--- a/external/postgresql/UnpackedTarball_postgresql.mk
+++ b/external/postgresql/UnpackedTarball_postgresql.mk
@@ -17,6 +17,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,postgresql, \
        external/postgresql/windows.patch.0 \
        external/postgresql/postgresql.exit.patch.0 \
        external/postgresql/postgres-msvc-build.patch.1 \
+       
external/postgresql/0001-Assume-that-stdbool.h-conforms-to-the-C-standard.patch.1
 \
        $(if $(filter WNT_AARCH64,$(OS)_$(CPUNAME)), 
external/postgresql/arm64.patch.1) \
 ))
 
commit 701476a2de71ddfbf7d250aaf5f3d8cfb3138aa0
Author:     Xisco Fauli <[email protected]>
AuthorDate: Mon Aug 19 13:57:47 2024 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:45:11 2026 +0100

    postgresql: Upgrade to 13.16
    
    Downloaded from 
https://ftp.postgresql.org/pub/source/v13.16/postgresql-13.16.tar.bz2
    
    Change-Id: I2854bca1ba3ac0a9beda61718d3a2e2002a2815c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172035
    Reviewed-by: Xisco Fauli <[email protected]>
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172045
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 4a9874f44181b2108d5615f6e017e12962755675)

diff --git a/download.lst b/download.lst
index 4f2f35e560d9..73f203d30e54 100644
--- a/download.lst
+++ b/download.lst
@@ -529,8 +529,8 @@ POPPLER_DATA_TARBALL := poppler-data-0.4.12.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-POSTGRESQL_SHA256SUM := 
b8df078551898960bd500dc5d38a177e9905376df81fe7f2b660a1407fa6a5ed
-POSTGRESQL_TARBALL := postgresql-13.14.tar.bz2
+POSTGRESQL_SHA256SUM := 
c9cbbb6129f02328204828066bb3785c00a85c8ca8fd329c2a8a53c1f5cd8865
+POSTGRESQL_TARBALL := postgresql-13.16.tar.bz2
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
commit 868625573b9130718a877604473a192d777be4d7
Author:     Xisco Fauli <[email protected]>
AuthorDate: Mon Mar 25 11:23:27 2024 +0100
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:45:03 2026 +0100

    postgresql: upgrade to release 13.14
    
    Change-Id: Ia9607fd9c8dad9d5936e867ad76b18a476f1057f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165278
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <[email protected]>
    (cherry picked from commit e311a6a09d753fb566f248d653434f10a4645e63)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165237
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 50aaacd317da93228b0d0ae4b9acafa75530b742)

diff --git a/download.lst b/download.lst
index 677c84bbc82f..4f2f35e560d9 100644
--- a/download.lst
+++ b/download.lst
@@ -529,8 +529,8 @@ POPPLER_DATA_TARBALL := poppler-data-0.4.12.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-POSTGRESQL_SHA256SUM := 
4992ff647203566b670d4e54dc5317499a26856c93576d0ea951bdf6bee50bfb
-POSTGRESQL_TARBALL := postgresql-13.11.tar.bz2
+POSTGRESQL_SHA256SUM := 
b8df078551898960bd500dc5d38a177e9905376df81fe7f2b660a1407fa6a5ed
+POSTGRESQL_TARBALL := postgresql-13.14.tar.bz2
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
commit 43ab39640687af1e55d8c5c61e8e477e6b9e3279
Author:     Taichi Haradaguchi <[email protected]>
AuthorDate: Wed Jun 28 18:58:58 2023 +0900
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:44:51 2026 +0100

    postgresql: upgrade to release 13.11
    
    CVE-2023-2454 and CVE-2023-2455 don't affect LibreOffice.
    
    Release Notes: https://www.postgresql.org/docs/release/13.11/
    
    Change-Id: I1de521b6aa9af1e6d84ea794b0f4f5d62de377f8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153728
    Tested-by: Jenkins
    Reviewed-by: Taichi Haradaguchi <[email protected]>
    (cherry picked from commit a815a1dbc765df464a36f120ff32c2a834c1fc8f)

diff --git a/download.lst b/download.lst
index ff484f0a874e..677c84bbc82f 100644
--- a/download.lst
+++ b/download.lst
@@ -529,8 +529,8 @@ POPPLER_DATA_TARBALL := poppler-data-0.4.12.tar.gz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
-POSTGRESQL_SHA256SUM := 
5bbcf5a56d85c44f3a8b058fb46862ff49cbc91834d07e295d02e6de3c216df2
-POSTGRESQL_TARBALL := postgresql-13.10.tar.bz2
+POSTGRESQL_SHA256SUM := 
4992ff647203566b670d4e54dc5317499a26856c93576d0ea951bdf6bee50bfb
+POSTGRESQL_TARBALL := postgresql-13.11.tar.bz2
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
diff --git a/external/postgresql/README b/external/postgresql/README
index edc3d5df2781..a04037993690 100644
--- a/external/postgresql/README
+++ b/external/postgresql/README
@@ -1,3 +1,7 @@
 PostgreSQL object-relational database management system
 
-We use some pieces of this code for the postgresql database connector.
\ No newline at end of file
+We use some pieces of this code for the postgresql database connector.
+
+From [https://www.postgresql.org/].
+
+Release archives at [https://www.postgresql.org/ftp/source/].
commit 8cd08eb7f0441cb727059ab1a15a2929990997ac
Author:     Michael Stahl <[email protected]>
AuthorDate: Wed Oct 1 20:05:16 2025 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Jan 27 17:30:00 2026 +0100

    python3: add patch for tarfile issues
    
    CVE-2025-4435 CVE-2024-12718 CVE-2025-4138 CVE-2025-4330 CVE-2025-4517
    
    ... plus some prerequisites to be able to apply it.
    
    This was fixed in 3.9.23 but 3.8 is EOL.
    
    Change-Id: I490ef48fbd95ec9b92ad7ed722f0c3c1cd535955
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191751
    Tested-by: allotropia jenkins <[email protected]>
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 3ef91e344e89faf6fe0b333d0a8115f1d621594e)

diff --git 
a/external/python3/0001-3.9-bpo-43757-Make-pathlib-use-os.path.realpath-to-r.patch.1
 
b/external/python3/0001-3.9-bpo-43757-Make-pathlib-use-os.path.realpath-to-r.patch.1
new file mode 100644
index 000000000000..0b117111c9ee
--- /dev/null
+++ 
b/external/python3/0001-3.9-bpo-43757-Make-pathlib-use-os.path.realpath-to-r.patch.1
@@ -0,0 +1,537 @@
+From 00af9794dd118f7b835dd844b2b609a503ad951e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C5=81ukasz=20Langa?= <[email protected]>
+Date: Mon, 2 Jun 2025 18:28:09 +0200
+Subject: [PATCH] [3.9] bpo-43757: Make pathlib use os.path.realpath() to
+ resolve symlinks in a path (GH-25264) (GH-135035)
+
+Also adds a new "strict" argument to realpath() to avoid changing the default 
behaviour of pathlib while sharing the implementation.
+
+(cherry-picked from commit baecfbd849dbf42360d3a84af6cc13160838f24d)
+
+Co-authored-by: Barney Gale <[email protected]>
+---
+ Doc/library/os.path.rst                       |  18 ++-
+ Lib/ntpath.py                                 |   4 +-
+ Lib/pathlib.py                                | 148 +++++-------------
+ Lib/posixpath.py                              |  26 ++-
+ Lib/test/test_ntpath.py                       |  60 ++++++-
+ Lib/test/test_posixpath.py                    |  57 ++++++-
+ .../2021-04-08-22-11-27.bpo-25264.b33fa0.rst  |   3 +
+ 7 files changed, 192 insertions(+), 124 deletions(-)
+ create mode 100644 
Misc/NEWS.d/next/Library/2021-04-08-22-11-27.bpo-25264.b33fa0.rst
+
+diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst
+index 97bb684a245..19a5ae028a5 100644
+--- a/Doc/library/os.path.rst
++++ b/Doc/library/os.path.rst
+@@ -345,15 +345,24 @@ the :mod:`glob` module.)
+       Accepts a :term:`path-like object`.
+ 
+ 
+-.. function:: realpath(path)
++.. function:: realpath(path, *, strict=False)
+ 
+    Return the canonical path of the specified filename, eliminating any 
symbolic
+    links encountered in the path (if they are supported by the operating
+    system).
+ 
++   If a path doesn't exist or a symlink loop is encountered, and *strict* is
++   ``True``, :exc:`OSError` is raised. If *strict* is ``False``, the path is
++   resolved as far as possible and any remainder is appended without checking
++   whether it exists.
++
+    .. note::
+-      When symbolic link cycles occur, the returned path will be one member of
+-      the cycle, but no guarantee is made about which member that will be.
++      This function emulates the operating system's procedure for making a 
path
++      canonical, which differs slightly between Windows and UNIX with respect
++      to how links and subsequent path components interact.
++
++      Operating system APIs make paths canonical as needed, so it's not
++      normally necessary to call this function.
+ 
+    .. versionchanged:: 3.6
+       Accepts a :term:`path-like object`.
+@@ -361,6 +370,9 @@ the :mod:`glob` module.)
+    .. versionchanged:: 3.8
+       Symbolic links and junctions are now resolved on Windows.
+ 
++   .. versionchanged:: 3.9.23
++      The *strict* parameter was added.
++
+ 
+ .. function:: relpath(path, start=os.curdir)
+ 
+diff --git a/Lib/ntpath.py b/Lib/ntpath.py
+index 6f771773a7d..92b46e20fc8 100644
+--- a/Lib/ntpath.py
++++ b/Lib/ntpath.py
+@@ -622,7 +622,7 @@ def _getfinalpathname_nonstrict(path):
+                 tail = join(name, tail) if tail else name
+         return tail
+ 
+-    def realpath(path):
++    def realpath(path, *, strict=False):
+         path = normpath(path)
+         if isinstance(path, bytes):
+             prefix = b'\\?\'
+@@ -647,6 +647,8 @@ def realpath(path):
+             path = _getfinalpathname(path)
+             initial_winerror = 0
+         except OSError as ex:
++            if strict:
++                raise
+             initial_winerror = ex.winerror
+             path = _getfinalpathname_nonstrict(path)
+         # The path returned by _getfinalpathname will always start with \?\ -
+diff --git a/Lib/pathlib.py b/Lib/pathlib.py
+index 7aeda14a141..1185a245739 100644
+--- a/Lib/pathlib.py
++++ b/Lib/pathlib.py
+@@ -14,15 +14,6 @@
+ 
+ 
+ supports_symlinks = True
+-if os.name == 'nt':
+-    import nt
+-    if sys.getwindowsversion()[:2] >= (6, 0):
+-        from nt import _getfinalpathname
+-    else:
+-        supports_symlinks = False
+-        _getfinalpathname = None
+-else:
+-    nt = None
+ 
+ 
+ __all__ = [
+@@ -34,14 +25,17 @@
+ # Internals
+ #
+ 
++_WINERROR_NOT_READY = 21  # drive exists but is not accessible
++_WINERROR_INVALID_NAME = 123  # fix for bpo-35306
++_WINERROR_CANT_RESOLVE_FILENAME = 1921  # broken symlink pointing to itself
++
+ # EBADF - guard against macOS `stat` throwing EBADF
+ _IGNORED_ERROS = (ENOENT, ENOTDIR, EBADF, ELOOP)
+ 
+ _IGNORED_WINERRORS = (
+-    21,  # ERROR_NOT_READY - drive exists but is not accessible
+-    123, # ERROR_INVALID_NAME - fix for bpo-35306
+-    1921,  # ERROR_CANT_RESOLVE_FILENAME - fix for broken symlink pointing to 
itself
+-)
++    _WINERROR_NOT_READY,
++    _WINERROR_INVALID_NAME,
++    _WINERROR_CANT_RESOLVE_FILENAME)
+ 
+ def _ignore_error(exception):
+     return (getattr(exception, 'errno', None) in _IGNORED_ERROS or
+@@ -200,30 +194,6 @@ def casefold_parts(self, parts):
+     def compile_pattern(self, pattern):
+         return re.compile(fnmatch.translate(pattern), re.IGNORECASE).fullmatch
+ 
+-    def resolve(self, path, strict=False):
+-        s = str(path)
+-        if not s:
+-            return os.getcwd()
+-        previous_s = None
+-        if _getfinalpathname is not None:
+-            if strict:
+-                return self._ext_to_normal(_getfinalpathname(s))
+-            else:
+-                tail_parts = []  # End of the path after the first one not 
found
+-                while True:
+-                    try:
+-                        s = self._ext_to_normal(_getfinalpathname(s))
+-                    except FileNotFoundError:
+-                        previous_s = s
+-                        s, tail = os.path.split(s)
+-                        tail_parts.append(tail)
+-                        if previous_s == s:
+-                            return path
+-                    else:
+-                        return os.path.join(s, *reversed(tail_parts))
+-        # Means fallback on absolute
+-        return None
+-
+     def _split_extended_path(self, s, ext_prefix=ext_namespace_prefix):
+         prefix = ''
+         if s.startswith(ext_prefix):
+@@ -234,10 +204,6 @@ def _split_extended_path(self, s, 
ext_prefix=ext_namespace_prefix):
+                 s = '\' + s[3:]
+         return prefix, s
+ 
+-    def _ext_to_normal(self, s):
+-        # Turn back an extended path into a normal DOS-like path
+-        return self._split_extended_path(s)[1]
+-
+     def is_reserved(self, parts):
+         # NOTE: the rules for reserved names seem somewhat complicated
+         # (e.g. r"..\NUL" is reserved but not r"foo\NUL").
+@@ -324,54 +290,6 @@ def casefold_parts(self, parts):
+     def compile_pattern(self, pattern):
+         return re.compile(fnmatch.translate(pattern)).fullmatch
+ 
+-    def resolve(self, path, strict=False):
+-        sep = self.sep
+-        accessor = path._accessor
+-        seen = {}
+-        def _resolve(path, rest):
+-            if rest.startswith(sep):
+-                path = ''
+-
+-            for name in rest.split(sep):
+-                if not name or name == '.':
+-                    # current dir
+-                    continue
+-                if name == '..':
+-                    # parent dir
+-                    path, _, _ = path.rpartition(sep)
+-                    continue
+-                if path.endswith(sep):
+-                    newpath = path + name
+-                else:
+-                    newpath = path + sep + name
+-                if newpath in seen:
+-                    # Already seen this path
+-                    path = seen[newpath]
+-                    if path is not None:
+-                        # use cached value
+-                        continue
+-                    # The symlink is not resolved, so we must have a symlink 
loop.
+-                    raise RuntimeError("Symlink loop from %r" % newpath)
+-                # Resolve the symbolic link
+-                try:
+-                    target = accessor.readlink(newpath)
+-                except OSError as e:
+-                    if e.errno != EINVAL and strict:
+-                        raise
+-                    # Not a symlink, or non-strict mode. We just leave the 
path
+-                    # untouched.
+-                    path = newpath
+-                else:
+-                    seen[newpath] = None # not resolved symlink
+-                    path = _resolve(path, target)
+-                    seen[newpath] = path # resolved symlink
+-
+-            return path
+-        # NOTE: according to POSIX, getcwd() cannot contain path components
+-        # which are symlinks.
+-        base = '' if path.is_absolute() else os.getcwd()
+-        return _resolve(base, str(path)) or sep
+-
+     def is_reserved(self, parts):
+         return False
+ 
+@@ -443,17 +361,11 @@ def link_to(self, target):
+ 
+     replace = os.replace
+ 
+-    if nt:
+-        if supports_symlinks:
+-            symlink = os.symlink
+-        else:
+-            def symlink(a, b, target_is_directory):
+-                raise NotImplementedError("symlink() not available on this 
system")
++    if hasattr(os, "symlink"):
++        symlink = os.symlink
+     else:
+-        # Under POSIX, os.symlink() takes two args
+-        @staticmethod
+-        def symlink(a, b, target_is_directory):
+-            return os.symlink(a, b)
++        def symlink(self, src, dst, target_is_directory=False):
++            raise NotImplementedError("os.symlink() not available on this 
system")
+ 
+     utime = os.utime
+ 
+@@ -475,6 +387,12 @@ def group(self, path):
+     def readlink(self, path):
+         return os.readlink(path)
+ 
++    getcwd = os.getcwd
++
++    expanduser = staticmethod(os.path.expanduser)
++
++    realpath = staticmethod(os.path.realpath)
++
+ 
+ _normal_accessor = _NormalAccessor()
+ 
+@@ -1212,17 +1130,27 @@ def resolve(self, strict=False):
+         """
+         if self._closed:
+             self._raise_closed()
+-        s = self._flavour.resolve(self, strict=strict)
+-        if s is None:
+-            # No symlink resolution => for consistency, raise an error if
+-            # the path doesn't exist or is forbidden
+-            self.stat()
+-            s = str(self.absolute())
+-        # Now we have no symlinks in the path, it's safe to normalize it.
+-        normed = self._flavour.pathmod.normpath(s)
+-        obj = self._from_parts((normed,), init=False)
+-        obj._init(template=self)
+-        return obj
++
++        def check_eloop(e):
++            winerror = getattr(e, 'winerror', 0)
++            if e.errno == ELOOP or winerror == 
_WINERROR_CANT_RESOLVE_FILENAME:
++                raise RuntimeError("Symlink loop from %r" % e.filename)
++
++        try:
++            s = self._accessor.realpath(self, strict=strict)
++        except OSError as e:
++            check_eloop(e)
++            raise
++        p = self._from_parts((s,))
++
++        # In non-strict mode, realpath() doesn't raise on symlink loops.
++        # Ensure we get an exception by calling stat()
++        if not strict:
++            try:
++                p.stat()
++            except OSError as e:
++                check_eloop(e)
++        return p
+ 
+     def stat(self):
+         """
+diff --git a/Lib/posixpath.py b/Lib/posixpath.py
+index af2814bdb05..eb80fb9e9be 100644
+--- a/Lib/posixpath.py
++++ b/Lib/posixpath.py
+@@ -385,16 +385,16 @@ def abspath(path):
+ # Return a canonical path (i.e. the absolute location of a file on the
+ # filesystem).
+ 
+-def realpath(filename):
++def realpath(filename, *, strict=False):
+     """Return the canonical path of the specified filename, eliminating any
+ symbolic links encountered in the path."""
+     filename = os.fspath(filename)
+-    path, ok = _joinrealpath(filename[:0], filename, {})
++    path, ok = _joinrealpath(filename[:0], filename, strict, {})
+     return abspath(path)
+ 
+ # Join two paths, normalizing and eliminating any symbolic links
+ # encountered in the second path.
+-def _joinrealpath(path, rest, seen):
++def _joinrealpath(path, rest, strict, seen):
+     if isinstance(path, bytes):
+         sep = b'/'
+         curdir = b'.'
+@@ -423,7 +423,15 @@ def _joinrealpath(path, rest, seen):
+                 path = pardir
+             continue
+         newpath = join(path, name)
+-        if not islink(newpath):
++        try:
++            st = os.lstat(newpath)
++        except OSError:
++            if strict:
++                raise
++            is_link = False
++        else:
++            is_link = stat.S_ISLNK(st.st_mode)
++        if not is_link:
+             path = newpath
+             continue
+         # Resolve the symbolic link
+@@ -434,10 +442,14 @@ def _joinrealpath(path, rest, seen):
+                 # use cached value
+                 continue
+             # The symlink is not resolved, so we must have a symlink loop.
+-            # Return already resolved part + rest of the path unchanged.
+-            return join(newpath, rest), False
++            if strict:
++                # Raise OSError(errno.ELOOP)
++                os.stat(newpath)
++            else:
++                # Return already resolved part + rest of the path unchanged.
++                return join(newpath, rest), False
+         seen[newpath] = None # not resolved symlink
+-        path, ok = _joinrealpath(path, os.readlink(newpath), seen)
++        path, ok = _joinrealpath(path, os.readlink(newpath), strict, seen)
+         if not ok:
+             return join(path, rest), False
+         seen[newpath] = path # resolved symlink
+diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py
+index 6f881f197c4..2d3fa101bc4 100644
+--- a/Lib/test/test_ntpath.py
++++ b/Lib/test/test_ntpath.py
+@@ -267,6 +267,17 @@ def test_realpath_basic(self):
+         self.assertPathEqual(ntpath.realpath(os.fsencode(ABSTFN + "1")),
+                          os.fsencode(ABSTFN))
+ 
++    @support.skip_unless_symlink
++    @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
++    def test_realpath_strict(self):
++        # Bug #43757: raise FileNotFoundError in strict mode if we encounter
++        # a path that does not exist.
++        ABSTFN = ntpath.abspath(support.TESTFN)
++        os.symlink(ABSTFN + "1", ABSTFN)
++        self.addCleanup(support.unlink, ABSTFN)
++        self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN, 
strict=True)
++        self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN + "2", 
strict=True)
++
+     @support.skip_unless_symlink
+     @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
+     def test_realpath_relative(self):
+@@ -338,8 +349,9 @@ def test_realpath_broken_symlinks(self):
+     @support.skip_unless_symlink
+     @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
+     def test_realpath_symlink_loops(self):
+-        # Symlink loops are non-deterministic as to which path is returned, 
but
+-        # it will always be the fully resolved path of one member of the cycle
++        # Symlink loops in non-strict mode are non-deterministic as to which
++        # path is returned, but it will always be the fully resolved path of
++        # one member of the cycle
+         ABSTFN = ntpath.abspath(support.TESTFN)
+         self.addCleanup(support.unlink, ABSTFN)
+         self.addCleanup(support.unlink, ABSTFN + "1")
+@@ -381,6 +393,50 @@ def test_realpath_symlink_loops(self):
+         # Test using relative path as well.
+         self.assertPathEqual(ntpath.realpath(ntpath.basename(ABSTFN)), ABSTFN)
+ 
++    @support.skip_unless_symlink
++    @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
++    def test_realpath_symlink_loops_strict(self):
++        # Symlink loops raise OSError in strict mode
++        ABSTFN = ntpath.abspath(support.TESTFN)
++        self.addCleanup(support.unlink, ABSTFN)
++        self.addCleanup(support.unlink, ABSTFN + "1")
++        self.addCleanup(support.unlink, ABSTFN + "2")
++        self.addCleanup(support.unlink, ABSTFN + "y")
++        self.addCleanup(support.unlink, ABSTFN + "c")
++        self.addCleanup(support.unlink, ABSTFN + "a")
++
++        os.symlink(ABSTFN, ABSTFN)
++        self.assertRaises(OSError, ntpath.realpath, ABSTFN, strict=True)
++
++        os.symlink(ABSTFN + "1", ABSTFN + "2")
++        os.symlink(ABSTFN + "2", ABSTFN + "1")
++        self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1", strict=True)
++        self.assertRaises(OSError, ntpath.realpath, ABSTFN + "2", strict=True)
++        self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\x", 
strict=True)
++        # Windows eliminates '..' components before resolving links, so the
++        # following call is not expected to raise.
++        self.assertPathEqual(ntpath.realpath(ABSTFN + "1\..", strict=True),
++                             ntpath.dirname(ABSTFN))
++        self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\..\x", 
strict=True)
++        os.symlink(ABSTFN + "x", ABSTFN + "y")
++        self.assertRaises(OSError, ntpath.realpath, ABSTFN + "1\..\"
++                                             + ntpath.basename(ABSTFN) + "y",
++                                             strict=True)
++        self.assertRaises(OSError, ntpath.realpath,
++                          ABSTFN + "1\..\" + ntpath.basename(ABSTFN) + "1",
++                          strict=True)
++
++        os.symlink(ntpath.basename(ABSTFN) + "a\b", ABSTFN + "a")
++        self.assertRaises(OSError, ntpath.realpath, ABSTFN + "a", strict=True)
++
++        os.symlink("..\" + ntpath.basename(ntpath.dirname(ABSTFN))
++                   + "\" + ntpath.basename(ABSTFN) + "c", ABSTFN + "c")
++        self.assertRaises(OSError, ntpath.realpath, ABSTFN + "c", strict=True)
++
++        # Test using relative path as well.
++        self.assertRaises(OSError, ntpath.realpath, ntpath.basename(ABSTFN),
++                          strict=True)
++
+     @support.skip_unless_symlink
+     @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
+     def test_realpath_symlink_prefix(self):
+diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py
+index 18819a5dc1c..aee3cb421fb 100644
+--- a/Lib/test/test_posixpath.py
++++ b/Lib/test/test_posixpath.py
+@@ -350,6 +350,19 @@ def test_realpath_basic(self):
+         finally:
+             support.unlink(ABSTFN)
+ 
++    @unittest.skipUnless(hasattr(os, "symlink"),
++                         "Missing symlink implementation")
++    @skip_if_ABSTFN_contains_backslash
++    def test_realpath_strict(self):
++        # Bug #43757: raise FileNotFoundError in strict mode if we encounter
++        # a path that does not exist.
++        try:
++            os.symlink(ABSTFN+"1", ABSTFN)
++            self.assertRaises(FileNotFoundError, realpath, ABSTFN, 
strict=True)
++            self.assertRaises(FileNotFoundError, realpath, ABSTFN + "2", 
strict=True)
++        finally:
++            support.unlink(ABSTFN)
++
+     @unittest.skipUnless(hasattr(os, "symlink"),
+                          "Missing symlink implementation")
+     @skip_if_ABSTFN_contains_backslash
+@@ -365,7 +378,7 @@ def test_realpath_relative(self):
+     @skip_if_ABSTFN_contains_backslash
+     def test_realpath_symlink_loops(self):
+         # Bug #930024, return the path unchanged if we get into an infinite
+-        # symlink loop.
++        # symlink loop in non-strict mode (default).
+         try:
+             os.symlink(ABSTFN, ABSTFN)
+             self.assertEqual(realpath(ABSTFN), ABSTFN)
+@@ -402,6 +415,48 @@ def test_realpath_symlink_loops(self):
+             support.unlink(ABSTFN+"c")
+             support.unlink(ABSTFN+"a")
+ 
++    @unittest.skipUnless(hasattr(os, "symlink"),
++                         "Missing symlink implementation")
++    @skip_if_ABSTFN_contains_backslash
++    def test_realpath_symlink_loops_strict(self):
++        # Bug #43757, raise OSError if we get into an infinite symlink loop in
++        # strict mode.
++        try:
++            os.symlink(ABSTFN, ABSTFN)
++            self.assertRaises(OSError, realpath, ABSTFN, strict=True)
++
++            os.symlink(ABSTFN+"1", ABSTFN+"2")
++            os.symlink(ABSTFN+"2", ABSTFN+"1")
++            self.assertRaises(OSError, realpath, ABSTFN+"1", strict=True)
++            self.assertRaises(OSError, realpath, ABSTFN+"2", strict=True)
++
++            self.assertRaises(OSError, realpath, ABSTFN+"1/x", strict=True)
++            self.assertRaises(OSError, realpath, ABSTFN+"1/..", strict=True)
++            self.assertRaises(OSError, realpath, ABSTFN+"1/../x", strict=True)
++            os.symlink(ABSTFN+"x", ABSTFN+"y")
++            self.assertRaises(OSError, realpath,
++                              ABSTFN+"1/../" + basename(ABSTFN) + "y", 
strict=True)
++            self.assertRaises(OSError, realpath,
++                              ABSTFN+"1/../" + basename(ABSTFN) + "1", 
strict=True)
++
++            os.symlink(basename(ABSTFN) + "a/b", ABSTFN+"a")
++            self.assertRaises(OSError, realpath, ABSTFN+"a", strict=True)
++
++            os.symlink("../" + basename(dirname(ABSTFN)) + "/" +
++                       basename(ABSTFN) + "c", ABSTFN+"c")
++            self.assertRaises(OSError, realpath, ABSTFN+"c", strict=True)
++
++            # Test using relative path as well.
++            with support.change_cwd(dirname(ABSTFN)):
++                self.assertRaises(OSError, realpath, basename(ABSTFN), 
strict=True)
++        finally:
++            support.unlink(ABSTFN)
++            support.unlink(ABSTFN+"1")
++            support.unlink(ABSTFN+"2")
++            support.unlink(ABSTFN+"y")
++            support.unlink(ABSTFN+"c")
++            support.unlink(ABSTFN+"a")
++
+     @unittest.skipUnless(hasattr(os, "symlink"),
+                          "Missing symlink implementation")
+     @skip_if_ABSTFN_contains_backslash
+diff --git a/Misc/NEWS.d/next/Library/2021-04-08-22-11-27.bpo-25264.b33fa0.rst 
b/Misc/NEWS.d/next/Library/2021-04-08-22-11-27.bpo-25264.b33fa0.rst
+new file mode 100644
+index 00000000000..593846ec15c
+--- /dev/null
++++ b/Misc/NEWS.d/next/Library/2021-04-08-22-11-27.bpo-25264.b33fa0.rst
+@@ -0,0 +1,3 @@
++:func:`os.path.realpath` now accepts a *strict* keyword-only argument.
++When set to ``True``, :exc:`OSError` is raised if a path doesn't exist
++or a symlink loop is encountered.
+-- 
+2.51.0
+
diff --git 
a/external/python3/0001-3.9-gh-135034-Normalize-link-targets-in-tarfile-add-.patch.1
 
b/external/python3/0001-3.9-gh-135034-Normalize-link-targets-in-tarfile-add-.patch.1
new file mode 100644
index 000000000000..9d6c34b1ece9
--- /dev/null
+++ 
b/external/python3/0001-3.9-gh-135034-Normalize-link-targets-in-tarfile-add-.patch.1
@@ -0,0 +1,1771 @@
+From dd8f187d0746da151e0025c51680979ac5b4cfb1 Mon Sep 17 00:00:00 2001
+From: "T. Wouters" <[email protected]>
+Date: Tue, 3 Jun 2025 19:02:50 +0200
+Subject: [PATCH] [3.9] gh-135034: Normalize link targets in tarfile, add
+ `os.path.realpath(strict='allow_missing')` (GH-135037) (GH-135084)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Addresses CVEs 2024-12718, 2025-4138, 2025-4330, and 2025-4517.
+(cherry picked from commit 3612d8f51741b11f36f8fb0494d79086bac9390a)
+
+Co-authored-by: Łukasz Langa <[email protected]>
+Co-authored-by: Petr Viktorin <[email protected]>
+Co-authored-by: Seth Michael Larson <[email protected]>
+Co-authored-by: Adam Turner <[email protected]>
+Co-authored-by: Serhiy Storchaka <[email protected]>
+---
+ Doc/library/os.path.rst                       |  33 +-
+ Doc/library/tarfile.rst                       |  20 ++
+ Doc/whatsnew/3.9.rst                          |  34 ++
+ Lib/genericpath.py                            |  11 +-
+ Lib/ntpath.py                                 |  35 +-
+ Lib/posixpath.py                              |  15 +-
+ Lib/tarfile.py                                | 161 +++++++--
+ Lib/test/test_ntpath.py                       | 169 +++++++++-
+ Lib/test/test_posixpath.py                    | 282 +++++++++++++---
+ Lib/test/test_tarfile.py                      | 314 ++++++++++++++++--
+ ...-06-02-11-32-23.gh-issue-135034.RLGjbp.rst |   6 +
+ 11 files changed, 946 insertions(+), 134 deletions(-)
+ create mode 100644 
Misc/NEWS.d/next/Security/2025-06-02-11-32-23.gh-issue-135034.RLGjbp.rst
+
+diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst
+index 19a5ae028a5..235a4deecfc 100644
+--- a/Doc/library/os.path.rst
++++ b/Doc/library/os.path.rst
+@@ -351,10 +351,26 @@ the :mod:`glob` module.)
+    links encountered in the path (if they are supported by the operating
+    system).
+ 
+-   If a path doesn't exist or a symlink loop is encountered, and *strict* is
+-   ``True``, :exc:`OSError` is raised. If *strict* is ``False``, the path is
+-   resolved as far as possible and any remainder is appended without checking
+-   whether it exists.
++   By default, the path is evaluated up to the first component that does not
++   exist, is a symlink loop, or whose evaluation raises :exc:`OSError`.
++   All such components are appended unchanged to the existing part of the 
path.
++
++   Some errors that are handled this way include "access denied", "not a
++   directory", or "bad argument to internal function". Thus, the
++   resulting path may be missing or inaccessible, may still contain
++   links or loops, and may traverse non-directories.
++
++   This behavior can be modified by keyword arguments:
++
++   If *strict* is ``True``, the first error encountered when evaluating the 
path is
++   re-raised.
++   In particular, :exc:`FileNotFoundError` is raised if *path* does not exist,
++   or another :exc:`OSError` if it is otherwise inaccessible.
++
++   If *strict* is :py:data:`os.path.ALLOW_MISSING`, errors other than
++   :exc:`FileNotFoundError` are re-raised (as with ``strict=True``).
++   Thus, the returned path will not contain any symbolic links, but the named
++   file and some of its parent directories may be missing.
+ 
+    .. note::
+       This function emulates the operating system's procedure for making a 
path
+@@ -373,6 +389,15 @@ the :mod:`glob` module.)
+    .. versionchanged:: 3.9.23
+       The *strict* parameter was added.
+ 
++   .. versionchanged:: next
++      The :py:data:`~os.path.ALLOW_MISSING` value for the *strict* parameter
++      was added.
++
++.. data:: ALLOW_MISSING
++
++   Special value used for the *strict* argument in :func:`realpath`.
++
++   .. versionadded:: next
+ 
+ .. function:: relpath(path, start=os.curdir)
+ 
+diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst
+index 165088529a8..d03f13db5d8 100644
+--- a/Doc/library/tarfile.rst
++++ b/Doc/library/tarfile.rst
+@@ -237,6 +237,15 @@ The :mod:`tarfile` module defines the following 
exceptions:
+    Raised to refuse extracting a symbolic link pointing outside the 
destination
+    directory.
+ 
++.. exception:: LinkFallbackError
++
++   Raised to refuse emulating a link (hard or symbolic) by extracting another
++   archive member, when that member would be rejected by the filter location.
++   The exception that was raised to reject the replacement member is available
++   as :attr:`!BaseException.__context__`.
++
++   .. versionadded:: next
++
+ 
+ The following constants are available at the module level:
+ 
+@@ -954,6 +963,12 @@ reused in custom filters:
+   Implements the ``'data'`` filter.
+   In addition to what ``tar_filter`` does:
+ 
++  - Normalize link targets (:attr:`TarInfo.linkname`) using
++    :func:`os.path.normpath`.
++    Note that this removes internal ``..`` components, which may change the
++    meaning of the link if the path in :attr:`!TarInfo.linkname` traverses
++    symbolic links.
++
+   - :ref:`Refuse <tarfile-extraction-refuse>` to extract links (hard or soft)
+     that link to absolute paths, or ones that link outside the destination.
+ 
+@@ -982,6 +997,10 @@ reused in custom filters:
+ 
+   Return the modified ``TarInfo`` member.
+ 
++  .. versionchanged:: next
++
++     Link targets are now normalized.
++
+ 
+ .. _tarfile-extraction-refuse:
+ 
+@@ -1008,6 +1027,7 @@ Here is an incomplete list of things to consider:
+ * Extract to a :func:`new temporary directory <tempfile.mkdtemp>`
+   to prevent e.g. exploiting pre-existing links, and to make it easier to
+   clean up after a failed extraction.
++* Disallow symbolic links if you do not need the functionality.
+ * When working with untrusted data, use external (e.g. OS-level) limits on
+   disk, memory and CPU usage.
+ * Check filenames against an allow-list of characters
+diff --git a/Lib/genericpath.py b/Lib/genericpath.py
+index ce36451a3af..ad8d47b41d4 100644
+--- a/Lib/genericpath.py
++++ b/Lib/genericpath.py
+@@ -8,7 +8,7 @@
+ 
+ __all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
+            'getsize', 'isdir', 'isfile', 'samefile', 'sameopenfile',
+-           'samestat']
++           'samestat', 'ALLOW_MISSING']
+ 
+ 
+ # Does a path exist?
+@@ -153,3 +153,12 @@ def _check_arg_types(funcname, *args):
+                             f'os.PathLike object, not 
{s.__class__.__name__!r}') from None
+     if hasstr and hasbytes:
+         raise TypeError("Can't mix strings and bytes in path components") 
from None
++
++# A singleton with a true boolean value.
++@object.__new__
++class ALLOW_MISSING:
++    """Special value for use in realpath()."""
++    def __repr__(self):
++        return 'os.path.ALLOW_MISSING'
++    def __reduce__(self):
++        return self.__class__.__name__
+diff --git a/Lib/ntpath.py b/Lib/ntpath.py
+index 92b46e20fc8..2588ea356fe 100644
+--- a/Lib/ntpath.py
++++ b/Lib/ntpath.py
+@@ -29,7 +29,8 @@
+            "ismount", "expanduser","expandvars","normpath","abspath",
+            "curdir","pardir","sep","pathsep","defpath","altsep",
+            
"extsep","devnull","realpath","supports_unicode_filenames","relpath",
+-           "samefile", "sameopenfile", "samestat", "commonpath"]
++           "samefile", "sameopenfile", "samestat", "commonpath",
++           "ALLOW_MISSING"]
+ 
+ def _get_bothseps(path):
+     if isinstance(path, bytes):
+@@ -532,9 +533,10 @@ def abspath(path):
+     from nt import _getfinalpathname, readlink as _nt_readlink
+ except ImportError:
+     # realpath is a no-op on systems without _getfinalpathname support.
+-    realpath = abspath
++    def realpath(path, *, strict=False):
++        return abspath(path)
+ else:
+-    def _readlink_deep(path):
++    def _readlink_deep(path, ignored_error=OSError):
+         # These error codes indicate that we should stop reading links and
+         # return the path we currently have.
+         # 1: ERROR_INVALID_FUNCTION
+@@ -567,7 +569,7 @@ def _readlink_deep(path):
+                         path = old_path
+                         break
+                     path = normpath(join(dirname(old_path), path))
+-            except OSError as ex:
++            except ignored_error as ex:
+                 if ex.winerror in allowed_winerror:
+                     break
+                 raise
+@@ -576,7 +578,7 @@ def _readlink_deep(path):
+                 break
+         return path
+ 
+-    def _getfinalpathname_nonstrict(path):
++    def _getfinalpathname_nonstrict(path, ignored_error=OSError):
+         # These error codes indicate that we should stop resolving the path
+         # and return the value we currently have.
+         # 1: ERROR_INVALID_FUNCTION
+@@ -600,17 +602,18 @@ def _getfinalpathname_nonstrict(path):
+             try:
+                 path = _getfinalpathname(path)
+                 return join(path, tail) if tail else path
+-            except OSError as ex:
++            except ignored_error as ex:
+                 if ex.winerror not in allowed_winerror:
+                     raise
+                 try:
+                     # The OS could not resolve this path fully, so we attempt
+                     # to follow the link ourselves. If we succeed, join the 
tail
+                     # and return.
+-                    new_path = _readlink_deep(path)
++                    new_path = _readlink_deep(path,
++                                              ignored_error=ignored_error)
+                     if new_path != path:
+                         return join(new_path, tail) if tail else new_path
+-                except OSError:
++                except ignored_error:
+                     # If we fail to readlink(), let's keep traversing
+                     pass
+                 path, name = split(path)
+@@ -641,16 +644,24 @@ def realpath(path, *, strict=False):
+             if normcase(path) == normcase(devnull):
+                 return '\\.\NUL'
+         had_prefix = path.startswith(prefix)
++
++        if strict is ALLOW_MISSING:
++            ignored_error = FileNotFoundError
++            strict = True
++        elif strict:
++            ignored_error = ()
++        else:
++            ignored_error = OSError
++
+         if not had_prefix and not isabs(path):
+             path = join(cwd, path)
+         try:
+             path = _getfinalpathname(path)
+             initial_winerror = 0
+-        except OSError as ex:
+-            if strict:
+-                raise
++        except ignored_error as ex:
+             initial_winerror = ex.winerror
+-            path = _getfinalpathname_nonstrict(path)
++            path = _getfinalpathname_nonstrict(path,
++                                               ignored_error=ignored_error)
+         # The path returned by _getfinalpathname will always start with \?\ -
+         # strip off that prefix unless it was already provided on the original
+         # path.
+diff --git a/Lib/posixpath.py b/Lib/posixpath.py
+index eb80fb9e9be..de2b90c10cc 100644
+--- a/Lib/posixpath.py
++++ b/Lib/posixpath.py
+@@ -35,7 +35,7 @@
+            "samefile","sameopenfile","samestat",
+            "curdir","pardir","sep","pathsep","defpath","altsep","extsep",
+            "devnull","realpath","supports_unicode_filenames","relpath",
+-           "commonpath"]
++           "commonpath", "ALLOW_MISSING"]
+ 
+ 
+ def _get_sep(path):
+@@ -403,6 +403,15 @@ def _joinrealpath(path, rest, strict, seen):
+         sep = '/'
+         curdir = '.'
+         pardir = '..'
++        getcwd = os.getcwd
++    if strict is ALLOW_MISSING:
++        ignored_error = FileNotFoundError
++    elif strict:
++        ignored_error = ()
++    else:
++        ignored_error = OSError
++
++    maxlinks = None
+ 
+     if isabs(rest):
+         rest = rest[1:]
+@@ -425,9 +434,7 @@ def _joinrealpath(path, rest, strict, seen):
+         newpath = join(path, name)
+         try:
+             st = os.lstat(newpath)
+-        except OSError:
+-            if strict:
+-                raise
++        except ignored_error:
+             is_link = False
+         else:
+             is_link = stat.S_ISLNK(st.st_mode)
+diff --git a/Lib/tarfile.py b/Lib/tarfile.py
+index d75ba50b667..7c9027dde84 100755
+--- a/Lib/tarfile.py
++++ b/Lib/tarfile.py
+@@ -749,10 +749,22 @@ def __init__(self, tarinfo, path):
+         super().__init__(f'{tarinfo.name!r} would link to {path!r}, '
+                          + 'which is outside the destination')
+ 
++class LinkFallbackError(FilterError):
++    def __init__(self, tarinfo, path):
++        self.tarinfo = tarinfo
++        self._path = path
++        super().__init__(f'link {tarinfo.name!r} would be extracted as a '
++                         + f'copy of {path!r}, which was rejected')
++
++# Errors caused by filters -- both "fatal" and "non-fatal" -- that
++# we consider to be issues with the argument, rather than a bug in the
++# filter function
++_FILTER_ERRORS = (FilterError, OSError, ExtractError)
++
+ def _get_filtered_attrs(member, dest_path, for_data=True):
+     new_attrs = {}
+     name = member.name
+-    dest_path = os.path.realpath(dest_path)
++    dest_path = os.path.realpath(dest_path, strict=os.path.ALLOW_MISSING)
+     # Strip leading / (tar's directory separator) from filenames.
+     # Include os.sep (target OS directory separator) as well.
+     if name.startswith(('/', os.sep)):
+@@ -762,7 +774,8 @@ def _get_filtered_attrs(member, dest_path, for_data=True):
+         # For example, 'C:/foo' on Windows.
+         raise AbsolutePathError(member)
+     # Ensure we stay in the destination
+-    target_path = os.path.realpath(os.path.join(dest_path, name))
++    target_path = os.path.realpath(os.path.join(dest_path, name),
++                                   strict=os.path.ALLOW_MISSING)
+     if os.path.commonpath([target_path, dest_path]) != dest_path:
+         raise OutsideDestinationError(member, target_path)
+     # Limit permissions (no high bits, and go-w)
+@@ -800,6 +813,9 @@ def _get_filtered_attrs(member, dest_path, for_data=True):
+         if member.islnk() or member.issym():
+             if os.path.isabs(member.linkname):
+                 raise AbsoluteLinkError(member)
++            normalized = os.path.normpath(member.linkname)
++            if normalized != member.linkname:
++                new_attrs['linkname'] = normalized
+             if member.issym():
+                 target_path = os.path.join(dest_path,
+                                            os.path.dirname(name),
+@@ -807,7 +823,8 @@ def _get_filtered_attrs(member, dest_path, for_data=True):
+             else:
+                 target_path = os.path.join(dest_path,
+                                            member.linkname)
+-            target_path = os.path.realpath(target_path)
++            target_path = os.path.realpath(target_path,
++                                           strict=os.path.ALLOW_MISSING)
+             if os.path.commonpath([target_path, dest_path]) != dest_path:
+                 raise LinkOutsideDestinationError(member, target_path)
+     return new_attrs
-e 
... etc. - the rest is truncated

Reply via email to