Version in base suite: 25.2.3-2+deb13u6 Version in overlay suite: 25.2.3-2+deb13u7 Base version: libreoffice_25.2.3-2+deb13u7 Target version: libreoffice_25.2.3-2+deb13u8 Base file: /srv/ftp-master.debian.org/ftp/pool/main/libr/libreoffice/libreoffice_25.2.3-2+deb13u7.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/libr/libreoffice/libreoffice_25.2.3-2+deb13u8.dsc changelog | 27 patches/CVE-2026-63266-1.diff | 55 + patches/CVE-2026-63266-2.diff | 187 ++++ patches/CVE-2026-63266-3.diff | 172 ++++ patches/CVE-2026-63266-4.diff | 87 ++ patches/CVE-2026-63267-1.diff | 316 +++++++ patches/CVE-2026-63267-2.diff | 55 + patches/CVE-2026-63268-1.diff | 57 + patches/CVE-2026-63268-2.diff | 65 + patches/CVE-2026-63269-1.diff | 83 + patches/CVE-2026-63269-2.diff | 393 +++++++++ patches/CVE-2026-63269-3.diff | 82 + patches/CVE-2026-63277.diff | 53 + patches/Show-infobar-for-calc-graphics-with-remote-content-too.diff | 120 ++ patches/do-not-load-exotic-protocols-for-document-supplied-data.diff | 128 +++ patches/firebird-call-writeFile-outside-the-SAL_WARN_IF-cond.patch | 71 + patches/firebird-db-connection.diff | 418 ++++++++++ patches/firebird-module-path.diff | 291 ++++++ patches/series | 20 source/include-binaries | 2 20 files changed, 2682 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpw5suao_7/libreoffice_25.2.3-2+deb13u7.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpw5suao_7/libreoffice_25.2.3-2+deb13u8.dsc: no acceptable signature found diff -Nru libreoffice-25.2.3/debian/changelog libreoffice-25.2.3/debian/changelog --- libreoffice-25.2.3/debian/changelog 2026-07-21 16:41:22.000000000 +0000 +++ libreoffice-25.2.3/debian/changelog 2026-10-03 10:46:08.000000000 +0000 @@ -1,3 +1,30 @@ +libreoffice (4:25.2.3-2+deb13u8) trixie-security; urgency=medium + + * debian/patches/CVE-2026-63277.diff: fix CVE-2026-63277 + ("RCE on document open in Calc") + * debian/patches/do-not-load-exotic-protocols-for-document-supplied-data.diff: + fix CVE-2026-63270 environment / config disclosure via missing + exotic-protocol guards, also prerequisite for CVE-2026-62367 and + CVE-2026-63268 + * debian/patches/CVE-2026-63269-?.diff: fix CVE-2026-63269 local file read + + GET SSRF via GStreamer and HLS media + * debian/patches/CVE-2026-63267-?.diff: fix CVE-2026-63267 local file read + + GET SSRF via csv data provider + * debian/patches/CVE-2026-63268-?.diff: fix CVE-2026-63268 local file read + via sql sdbc:flat:file:// db href + * debian/patches/CVE-2026-63266-?.diff: fix + CVE-2026-63266 arbitrary file write via firebird backup + escalates to RCE + * debian/patches/firebird-db-connection.diff: backport from upstream, fix + db connection to firebird + debian/patches/firebird-module-path.diff, + debian/patches/firebird-call-writeFile-outside-the-SAL_WARN_IF-cond.patch: + backport from upstream to fix tests with Debian's patched firebird + * debian/source/include-binaries: add (changed by the build, 3.0->4.0?) + firebird_integer_ods12.odb and tdf132924.odb + + -- Rene Engelhard Sat, 03 Oct 2026 12:46:08 +0200 + libreoffice (4:25.2.3-2+deb13u7) trixie-security; urgency=medium * debian/patches/CVE-2026-62327?.diff: fix diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63266-1.diff libreoffice-25.2.3/debian/patches/CVE-2026-63266-1.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63266-1.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63266-1.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,55 @@ +From 27ba4a9d24cb915048dd44e6e08bfa24756c09bd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sun, 12 Jul 2026 10:28:48 +0000 +Subject: [PATCH] firebird: don't run an attached database's own event triggers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +for the embedded and file cases suppress the database's ON CONNECT and +similar event triggers when attaching, they should not fire just because +the document was opened + +Change-Id: I37edab43f25d8cb72cc6dcafd743045f96b4c2e6 +Signed-off-by: Caolán McNamara +Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/6700 +Reviewed-by: Miklos Vajna +Tested-by: Jenkins CPCI +(cherry picked from commit 36335ff89ea2309e99da02b449c9b35517cd6f9d) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208029 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208062 +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208074 +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208110 +Tested-by: Christian Lohmaier +Reviewed-by: Christian Lohmaier +Reviewed-by: Hossein +--- + connectivity/source/drivers/firebird/Connection.cxx | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx +index 09ba278579bc..6b678387bf28 100644 +--- a/connectivity/source/drivers/firebird/Connection.cxx ++++ b/connectivity/source/drivers/firebird/Connection.cxx +@@ -233,8 +233,13 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& + + // Do any more dpbBuffer additions here + ++ // attach without running the database's own event triggers + if (m_bIsEmbedded || m_bIsFile) + { ++ dpbBuffer.push_back(isc_dpb_no_db_triggers); ++ dpbBuffer.push_back(1); // 1 byte long ++ dpbBuffer.push_back(1); ++ + userName = "sysdba"_ostr; + userPassword = "masterkey"_ostr; + } +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63266-2.diff libreoffice-25.2.3/debian/patches/CVE-2026-63266-2.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63266-2.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63266-2.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,187 @@ +From b7c1e1cc355c63b343f8e2ee4275621d85cef987 Mon Sep 17 00:00:00 2001 +From: Xisco Fauli +Date: Fri, 17 Jul 2026 11:59:00 +0200 +Subject: [PATCH] Reapply "firebird: keep each embedded database's files in one + directory" + +This reverts commit 23a5d0dc305fc04bdd277b24db8d5c8e41aa9ccd. + +it also contains https://gerrit.collaboraoffice.com/c/core/+/7093 +"firebird: upper-case the DatabaseAccess Restrict path on Windows" + +Change-Id: I52ea962a51da19a112892d6a2497a7ddf682c579 +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208212 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +(cherry picked from commit e4dc6a3cb2bfbf9d4c1e30e777b0f46417cf4c92) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208224 +Reviewed-by: Ilmari Lauhakangas +Tested-by: Ilmari Lauhakangas +Reviewed-by: Hossein +--- + .../source/drivers/firebird/Connection.cxx | 5 +- + .../source/drivers/firebird/Connection.hxx | 3 +- + .../source/drivers/firebird/Driver.cxx | 52 ++++++++++++++++++- + .../source/drivers/firebird/Driver.hxx | 7 +++ + 4 files changed, 63 insertions(+), 4 deletions(-) + +diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx +index fc105a883e4e..e01ea918a930 100644 +--- a/connectivity/source/drivers/firebird/Connection.cxx ++++ b/connectivity/source/drivers/firebird/Connection.cxx +@@ -121,7 +121,8 @@ struct ConnectionGuard + + } + +-void Connection::construct(const OUString& url, const Sequence< PropertyValue >& info) ++void Connection::construct(const OUString& url, const Sequence< PropertyValue >& info, ++ const OUString& rDatabaseDataDirectoryURL) + { + ConnectionGuard aGuard(m_refCount); + +@@ -161,7 +162,7 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& + + bIsNewDatabase = !m_xEmbeddedStorage->hasElements(); + +- m_pDatabaseFileDir.reset(new ::utl::TempFileNamed(nullptr, true)); ++ m_pDatabaseFileDir.reset(new ::utl::TempFileNamed(&rDatabaseDataDirectoryURL, true)); + m_pDatabaseFileDir->EnableKillingFile(); + m_sFirebirdURL = m_pDatabaseFileDir->GetFileName() + "/firebird.fdb"; + m_sFBKPath = m_pDatabaseFileDir->GetFileName() + "/firebird.fbk"; +diff --git a/connectivity/source/drivers/firebird/Connection.hxx b/connectivity/source/drivers/firebird/Connection.hxx +index 524c0a7c476f..6ec020374883 100644 +--- a/connectivity/source/drivers/firebird/Connection.hxx ++++ b/connectivity/source/drivers/firebird/Connection.hxx +@@ -163,7 +163,8 @@ + /// @throws css::sdbc::SQLException + /// @throws css::uno::RuntimeException + void construct( const OUString& url, +- const css::uno::Sequence< css::beans::PropertyValue >& info); ++ const css::uno::Sequence< css::beans::PropertyValue >& info, ++ const OUString& rDatabaseDataDirectoryURL); + + const OUString& getConnectionURL() const {return m_sConnectionURL;} + bool isEmbedded() const {return m_bIsEmbedded;} +diff --git a/connectivity/source/drivers/firebird/Driver.cxx b/connectivity/source/drivers/firebird/Driver.cxx +index 0879a7eca310..3d0b8db41642 100644 +--- a/connectivity/source/drivers/firebird/Driver.cxx ++++ b/connectivity/source/drivers/firebird/Driver.cxx +@@ -48,6 +48,7 @@ namespace { + constexpr OUString our_sFirebirdTmpVar = u"FIREBIRD_TMP"_ustr; + constexpr OUString our_sFirebirdLockVar = u"FIREBIRD_LOCK"_ustr; + constexpr OUString our_sFirebirdMsgVar = u"FIREBIRD_MSG"_ustr; ++constexpr OUString our_sFirebirdRootVar = u"FIREBIRD"_ustr; + #ifdef MACOSX + constexpr OUString our_sFirebirdLibVar = u"LIBREOFFICE_FIREBIRD_LIB"_ustr; + #endif +@@ -58,12 +59,15 @@ FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentCo + , m_aContext(_rxContext) + , m_firebirdTMPDirectory(nullptr, true) + , m_firebirdLockDirectory(nullptr, true) ++ , m_firebirdDataDirectory(nullptr, true) ++ , m_bConfined(false) + { + // ::utl::TempFile uses a unique temporary directory (subdirectory of + // /tmp or other user specific tmp directory) per instance in which + // we can create directories for firebird at will. + m_firebirdTMPDirectory.EnableKillingFile(true); + m_firebirdLockDirectory.EnableKillingFile(true); ++ m_firebirdDataDirectory.EnableKillingFile(true); + + // Overrides firebird's default of /tmp or c:\temp + osl_setEnvironment(our_sFirebirdTmpVar.pData, m_firebirdTMPDirectory.GetFileName().pData); +@@ -71,6 +75,41 @@ FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentCo + // Overrides firebird's default of /tmp/firebird or c:\temp\firebird + osl_setEnvironment(our_sFirebirdLockVar.pData, m_firebirdLockDirectory.GetFileName().pData); + ++ // Keep the files firebird opens or creates together in one directory. ++ // Embedded databases are extracted here, and DatabaseAccess = Restrict ++ // keeps any associated files firebird makes for it under the same ++ // directory. firebird reads this firebird.conf from the directory the ++ // FIREBIRD variable names, once, on its first use, so it has to be set ++ // before the first connection. ++ OUString sDataDirPath; ++ ::osl::FileBase::getSystemPathFromFileURL(m_firebirdDataDirectory.GetURL(), sDataDirPath); ++ ++#if defined(_WIN32) ++ // firebird upper-cases the database path before the exact-match ++ // DatabaseAccess check, so match that here. ++ sDataDirPath = sDataDirPath.toAsciiUpperCase(); ++#endif ++ ++ OString sConf = "DatabaseAccess = Restrict " ++ + OUStringToOString(sDataDirPath, RTL_TEXTENCODING_UTF8) + "\n"; ++ ++ OUString sConfURL = m_firebirdDataDirectory.GetURL() + "/firebird.conf"; ++ ::osl::File aConfFile(sConfURL); ++ if (aConfFile.open(osl_File_OpenFlag_Create | osl_File_OpenFlag_Write) == ::osl::FileBase::E_None) ++ { ++ sal_uInt64 nWritten = 0; ++ if (aConfFile.write(sConf.getStr(), sConf.getLength(), nWritten) == ::osl::FileBase::E_None ++ && nWritten == static_cast(sConf.getLength())) ++ { ++ osl_setEnvironment(our_sFirebirdRootVar.pData, sDataDirPath.pData); ++ m_bConfined = true; ++ } ++ aConfFile.close(); ++ } ++ ++ SAL_WARN_IF(!m_bConfined, "connectivity.firebird", ++ "could not write " << sConfURL << ", firebird connections will be refused"); ++ + #ifndef SYSTEM_FIREBIRD + // Overrides firebird's hardcoded default of /usr/local/firebird on *nix, + // however on Windows it seems to use the current directory as a default. +@@ -107,6 +146,7 @@ void FirebirdDriver::disposing() + + osl_clearEnvironment(our_sFirebirdTmpVar.pData); + osl_clearEnvironment(our_sFirebirdLockVar.pData); ++ osl_clearEnvironment(our_sFirebirdRootVar.pData); + + #ifndef SYSTEM_FIREBIRD + osl_clearEnvironment(our_sFirebirdMsgVar.pData); +@@ -148,8 +188,18 @@ Reference< XConnection > SAL_CALL FirebirdDriver::connect( + if ( ! acceptsURL(url) ) + return nullptr; + ++ // Without the firebird.conf that keeps firebird inside its own directory ++ // we do not open any database. ++ if (!m_bConfined) ++ { ++ ::connectivity::SharedResources aResources; ++ const OUString sMessage = aResources.getResourceString(STR_COULD_NOT_LOAD_FILE).replaceFirst( ++ "$filename$", u"firebird.conf"); ++ ::dbtools::throwGenericSQLException(sMessage, *this); ++ } ++ + rtl::Reference pCon = new Connection(); +- pCon->construct(url, info); ++ pCon->construct(url, info, getDatabaseDataDirectoryURL()); + + m_xConnections.emplace_back(*pCon); + +diff --git a/connectivity/source/drivers/firebird/Driver.hxx b/connectivity/source/drivers/firebird/Driver.hxx +index 5428568b4166..122fa1fc5f3d 100644 +--- a/connectivity/source/drivers/firebird/Driver.hxx ++++ b/connectivity/source/drivers/firebird/Driver.hxx +@@ -47,6 +47,8 @@ + css::uno::Reference m_aContext; + ::utl::TempFileNamed m_firebirdTMPDirectory; + ::utl::TempFileNamed m_firebirdLockDirectory; ++ ::utl::TempFileNamed m_firebirdDataDirectory; ++ bool m_bConfined; + + protected: + ::osl::Mutex m_aMutex; // mutex is need to control member access +@@ -60,6 +62,11 @@ + virtual ~FirebirdDriver() override; + const css::uno::Reference& getContext() const { return m_aContext; } + ++ // The directory that embedded databases are extracted into. Each ++ // connection makes its own subdirectory here, and firebird keeps ++ // associated files it creates for them under this directory as well. ++ OUString getDatabaseDataDirectoryURL() const { return m_firebirdDataDirectory.GetURL(); } ++ + // OComponentHelper + virtual void SAL_CALL disposing() override; + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63266-3.diff libreoffice-25.2.3/debian/patches/CVE-2026-63266-3.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63266-3.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63266-3.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,172 @@ +From 4c75c4c035779b7b5f9f9b74bd17ba4a29966c98 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sun, 12 Jul 2026 16:09:48 +0000 +Subject: [PATCH] firebird: don't attach a database that is not in the normal + backup state +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A database we extract from a .odb is always in the normal backup state, +so refuse one that is not, we're not interested in the difference file +mode case. + +firebird upstream attempt as: +https://github.com/FirebirdSQL/firebird/pull/9089 + +And do it manually for the system-firebird case. + +Change-Id: Iff9ebbb075379ca47a7f7f5886b693ac23860566 +Signed-off-by: Caolán McNamara +Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/6702 +Reviewed-by: Miklos Vajna +Tested-by: Jenkins CPCI +(cherry picked from commit e7ea381e87cadaf31bf1ad2213a23f17a6284d1c) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208040 +Reviewed-by: Xisco Fauli +Tested-by: Xisco Fauli +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208064 +Tested-by: Jenkins +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208076 +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208112 +Tested-by: Christian Lohmaier +Reviewed-by: Hossein +Reviewed-by: Christian Lohmaier +--- + .../source/drivers/firebird/Connection.cxx | 42 +++++++++++++++++ + external/firebird/UnpackedTarball_firebird.mk | 1 + + ...rebird-nbak-difference-file-access.patch.1 | 47 +++++++++++++++++++ + 3 files changed, 90 insertions(+) + create mode 100644 external/firebird/firebird-nbak-difference-file-access.patch.1 + +diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx +index 6b678387bf28..37b79e4764a5 100644 +--- a/connectivity/source/drivers/firebird/Connection.cxx ++++ b/connectivity/source/drivers/firebird/Connection.cxx +@@ -120,6 +120,39 @@ struct ConnectionGuard + } + }; + ++// A set nbackup state makes firebird open a difference file ++// (BackupManager::actualizeState and openDelta, firebird/src/jrd/nbak.cpp). ++// A database we made is never in that state, so refuse it. ++bool databaseHeaderHasBackupState(const OUString& rDatabasePath) ++{ ++ OUString sFileURL; ++ if (::osl::FileBase::getFileURLFromSystemPath(rDatabasePath, sFileURL) != ::osl::FileBase::E_None) ++ return false; ++ ++ ::osl::File aFile(sFileURL); ++ if (aFile.open(osl_File_OpenFlag_Read) != ::osl::FileBase::E_None) ++ return false; ++ ++ // Ods::header_page, firebird/src/jrd/ods.h ++ sal_uInt8 aHeader[44]; ++ sal_uInt64 nRead = 0; ++ ::osl::FileBase::RC eRead = aFile.read(aHeader, sizeof(aHeader), nRead); ++ aFile.close(); ++ ++ if (eRead != ::osl::FileBase::E_None || nRead < sizeof(aHeader)) ++ return false; ++ ++ // pag_type, Ods::pag_header ++ const sal_uInt8 nPageTypeHeader = 1; ++ if (aHeader[0] != nPageTypeHeader) ++ return false; ++ ++ // hdr_flags & hdr_backup_mask, normal state is 0 ++ const sal_uInt16 nFlags = aHeader[42] | (aHeader[43] << 8); ++ const sal_uInt16 nBackupStateMask = 0x0C00; ++ return (nFlags & nBackupStateMask) != 0; ++} ++ + } + + void Connection::construct(const OUString& url, const Sequence< PropertyValue >& info, +@@ -184,6 +217,15 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& + SAL_INFO("connectivity.firebird", "Found .fdb instead of .fbk"); + bIsFdbStored = true; + loadDatabaseFile(our_sFDBLocation, m_sFirebirdURL); ++ // Decline a database whose header asks firebird to use a ++ // difference file ++ if (databaseHeaderHasBackupState(m_sFirebirdURL)) ++ { ++ ::connectivity::SharedResources aResources; ++ const OUString sMessage = aResources.getResourceString(STR_COULD_NOT_LOAD_FILE).replaceFirst( ++ "$filename$", m_sConnectionURL); ++ ::dbtools::throwGenericSQLException(sMessage, *this); ++ } + } + else + { +diff --git a/external/firebird/UnpackedTarball_firebird.mk b/external/firebird/UnpackedTarball_firebird.mk +index 79e1da16daee..5ac456e40a01 100644 +--- a/external/firebird/UnpackedTarball_firebird.mk ++++ b/external/firebird/UnpackedTarball_firebird.mk +@@ -31,6 +31,7 @@ $(eval $(call gb_UnpackedTarball_update_autoconf_configs,firebird,\ + # at "extern/cloop: Missing dependencies of + # compilations on output directories": + $(eval $(call gb_UnpackedTarball_add_patches,firebird,\ ++ external/firebird/firebird-nbak-difference-file-access.patch.1 \ + external/firebird/firebird.disable-ib-util-not-found.patch.1 \ + external/firebird/firebird-Engine12.patch \ + external/firebird/firebird-rpath.patch.0 \ +diff --git a/external/firebird/firebird-nbak-difference-file-access.patch.1 b/external/firebird/firebird-nbak-difference-file-access.patch.1 +new file mode 100644 +index 000000000000..256d805e8f1d +--- /dev/null ++++ b/external/firebird/firebird-nbak-difference-file-access.patch.1 +@@ -0,0 +1,47 @@ ++Verify difference file path against DatabaseAccess ++ ++The difference file opened in openDelta and beginBackup was not verified ++against DatabaseAccess like the other database file paths. ++ ++Submitted upstream as https://github.com/FirebirdSQL/firebird/pull/9089 ++ ++--- firebird/src/jrd/nbak.cpp +++++ firebird/src/jrd/nbak.cpp ++@@ -35,6 +35,7 @@ ++ #include "lck.h" ++ #include "cch.h" ++ #include "lck_proto.h" +++#include "jrd_proto.h" ++ #include "pag_proto.h" ++ #include "err_proto.h" ++ #include "cch_proto.h" ++@@ -224,6 +225,14 @@ ++ void BackupManager::openDelta(thread_db* tdbb) ++ { ++ fb_assert(!diff_file); +++ +++ // Verify difference file path against DatabaseAccess entry of firebird.conf +++ if (!JRD_verify_database_access(diff_name)) +++ { +++ ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("difference file") << +++ Arg::Str(diff_name)); +++ } +++ ++ diff_file = PIO_open(tdbb, diff_name, diff_name); ++ ++ if (database->dbb_flags & (DBB_force_write | DBB_no_fs_cache)) ++@@ -283,6 +292,14 @@ ++ { ++ // Create file ++ NBAK_TRACE(("Creating difference file %s", diff_name.c_str())); +++ +++ // Verify difference file path against DatabaseAccess entry of firebird.conf +++ if (!JRD_verify_database_access(diff_name)) +++ { +++ ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("difference file") << +++ Arg::Str(diff_name)); +++ } +++ ++ diff_file = PIO_create(tdbb, diff_name, true, false); ++ } ++ catch (const Firebird::Exception&) +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63266-4.diff libreoffice-25.2.3/debian/patches/CVE-2026-63266-4.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63266-4.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63266-4.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,87 @@ +From 249c36ad76dae0b0f02357bc6dee7295ccf9a639 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sun, 12 Jul 2026 13:46:11 +0000 +Subject: [PATCH] firebird: only write back an embedded database that was + opened +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When construct throws before the attach succeeds, the connection is +disposed with the temporary .fdb extracted but never opened, but +storeDatabase ran the backup service against it anyway. + +Note whether the database was opened and skip the write back when it was +not. + +Change-Id: I7c1bfdd880699d661e4b798fff441a357c141f12 +Signed-off-by: Caolán McNamara +Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/6703 +Tested-by: Jenkins CPCI +Reviewed-by: Miklos Vajna +(cherry picked from commit a73db8b145af1c74cb181e094c0b7ccc4d92d8f0) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208041 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208065 +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208077 +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208113 +Reviewed-by: Ilmari Lauhakangas +Reviewed-by: Hossein +Tested-by: Ilmari Lauhakangas +--- + connectivity/source/drivers/firebird/Connection.cxx | 7 ++++++- + connectivity/source/drivers/firebird/Connection.hxx | 5 +++++ + 2 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx +index e01ea918a930..09ba278579bc 100644 +--- a/connectivity/source/drivers/firebird/Connection.cxx ++++ b/connectivity/source/drivers/firebird/Connection.cxx +@@ -82,6 +82,7 @@ Connection::Connection() + : Connection_BASE(m_aMutex) + , m_bIsEmbedded(false) + , m_bIsFile(false) ++ , m_bBackupDataOnDispose(false) + , m_bIsAutoCommit(true) + , m_bIsReadOnly(false) + , m_aTransactionIsolation(TransactionIsolation::READ_COMMITTED) +@@ -315,6 +316,10 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& + + if (m_bIsEmbedded) // Add DocumentEventListener to save the .fdb as needed + { ++ // The database opened without error, so its temporary .fdb is ++ // worth writing back into the .odb on dispose. ++ m_bBackupDataOnDispose = true; ++ + // We need to attach as a document listener in order to be able to store + // the temporary db back into the .odb when saving + uno::Reference xBroadcaster(m_xParentDocument, UNO_QUERY); +@@ -907,7 +912,7 @@ void Connection::disposing() + void Connection::storeDatabase() + { + MutexGuard aGuard(m_aMutex); +- if (m_bIsEmbedded && m_xEmbeddedStorage.is()) ++ if (m_bIsEmbedded && m_bBackupDataOnDispose && m_xEmbeddedStorage.is()) + { + SAL_INFO("connectivity.firebird", "Writing .fbk from running db"); + try +diff --git a/connectivity/source/drivers/firebird/Connection.hxx b/connectivity/source/drivers/firebird/Connection.hxx +index 6ec020374883..a6117f65b173 100644 +--- a/connectivity/source/drivers/firebird/Connection.hxx ++++ b/connectivity/source/drivers/firebird/Connection.hxx +@@ -128,6 +128,11 @@ + /** We are using an external (local) file */ + bool m_bIsFile; + ++ /** When true the embedded database was opened in this session, so the ++ temporary .fdb holds live data that must be written back into the .odb ++ when the connection is disposed. */ ++ bool m_bBackupDataOnDispose; ++ + /* CONNECTION PROPERTIES */ + bool m_bIsAutoCommit; + bool m_bIsReadOnly; diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63267-1.diff libreoffice-25.2.3/debian/patches/CVE-2026-63267-1.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63267-1.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63267-1.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,316 @@ +From 49c3c4e59c4834a692dbfe5a5690e6ceb2e5ba76 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sat, 11 Jul 2026 23:36:15 +0000 +Subject: [PATCH] put calc external data mappings under link update control +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +register each mapping as a LinkManager link, so its refresh goes through +the same update control as sheet links and area links. Wait until after +the infobar-controlled update mode is known to update. + +Signed-off-by: Caolán McNamara +Change-Id: I6710d4bdf3de6e002365d75c911b69076a054da8 +Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/7058 +Tested-by: Jenkins CPCI +Reviewed-by: Miklos Vajna +(cherry picked from commit b72d760465c857eb5dd10cdc45b107c49bb0caec) +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208394 +Tested-by: Christian Lohmaier +Reviewed-by: Christian Lohmaier +--- + sc/inc/datamapper.hxx | 2 +- + sc/inc/document.hxx | 4 ++ + sc/qa/uitest/calc_tests8/dataProvider.py | 2 + + .../data/dataprovider/csv/mappinggate.csv | 1 + + sc/qa/unit/data/dataprovider/mappinggate.fods | 19 ++++++ + sc/qa/unit/dataproviders_test.cxx | 40 +++++++++++++ + sc/source/core/data/document10.cxx | 5 ++ + sc/source/core/tool/ddelink.cxx | 6 ++ + sc/source/core/tool/webservicelink.cxx | 6 ++ + sc/source/filter/xml/xmlmappingi.cxx | 10 ---- + sc/source/filter/xml/xmlmappingi.hxx | 2 - + sc/source/ui/dataprovider/dataprovider.cxx | 59 ++++++++++++++++++- + sc/source/ui/docshell/docsh4.cxx | 1 + + sc/source/ui/docshell/tablink.cxx | 4 ++ + sc/source/ui/view/tabvwsh4.cxx | 3 +- + 15 files changed, 148 insertions(+), 16 deletions(-) + create mode 100644 sc/qa/unit/data/dataprovider/csv/mappinggate.csv + create mode 100644 sc/qa/unit/data/dataprovider/mappinggate.fods + +diff --git a/sc/inc/datamapper.hxx b/sc/inc/datamapper.hxx +index 984e6cc81219..32d610ac3c9b 100644 +--- a/sc/inc/datamapper.hxx ++++ b/sc/inc/datamapper.hxx +@@ -96,7 +96,7 @@ public: + + class SC_DLLPUBLIC ExternalDataMapper + { +- //ScDocument& mrDoc; ++ ScDocument& mrDoc; + std::vector maDataSources; + + public: +diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx +index 743c642fcf51..7230b67c8e9b 100644 +--- a/sc/inc/document.hxx ++++ b/sc/inc/document.hxx +@@ -899,6 +899,10 @@ public: + SC_DLLPUBLIC ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); + void RefreshDirtyTableColumnNames(); + SC_DLLPUBLIC sc::ExternalDataMapper& GetExternalDataMapper(); ++ /** True when the document holds at least one external data mapping. Checks ++ without creating the mapper, so it stays cheap for documents that have ++ none. */ ++ SC_DLLPUBLIC bool HasDataProviderMappings() const; + + SC_DLLPUBLIC const ScRangeData* GetRangeAtBlock( const ScRange& rBlock, OUString& rName, + bool* pSheetLocal = nullptr ) const; +diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx +index e9edef8c98a6..eda82a7b62bb 100644 +--- a/sc/source/core/data/document10.cxx ++++ b/sc/source/core/data/document10.cxx +@@ -1038,6 +1038,11 @@ sc::ExternalDataMapper& ScDocument::GetExternalDataMapper() + return *mpDataMapper; + } + ++bool ScDocument::HasDataProviderMappings() const ++{ ++ return mpDataMapper && !mpDataMapper->getDataSources().empty(); ++} ++ + void ScDocument::StoreTabToCache(SCTAB nTab, SvStream& rStrm) const + { + const ScTable* pTab = FetchTable(nTab); +diff --git a/sc/source/core/tool/ddelink.cxx b/sc/source/core/tool/ddelink.cxx +index 6d9eab0775d0..fcfed762c61e 100644 +--- a/sc/source/core/tool/ddelink.cxx ++++ b/sc/source/core/tool/ddelink.cxx +@@ -17,6 +17,7 @@ + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + ++#include + #include + #include + #include +@@ -29,6 +30,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -125,6 +127,10 @@ void ScDdeLink::Store( SvStream& rStream, ScMultipleWriteHeader& rHdr ) const + sfx2::SvBaseLink::UpdateResult ScDdeLink::DataChanged( + const OUString& rMimeType, const css::uno::Any & rValue ) + { ++ if (rDoc.GetDocumentShell() ++ && !rDoc.GetDocumentShell()->GetEmbeddedObjectContainer().getUserAllowsLinkUpdate()) ++ return SUCCESS; ++ + // we only master strings... + if ( SotClipboardFormatId::STRING != SotExchange::GetFormatIdFromMimeType( rMimeType )) + return SUCCESS; +diff --git a/sc/source/core/tool/webservicelink.cxx b/sc/source/core/tool/webservicelink.cxx +index fb5d81afc87b..cbb226e240a8 100644 +--- a/sc/source/core/tool/webservicelink.cxx ++++ b/sc/source/core/tool/webservicelink.cxx +@@ -7,6 +7,7 @@ + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + ++#include + #include + #include + #include +@@ -21,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -36,6 +38,10 @@ ScWebServiceLink::~ScWebServiceLink() {} + + sfx2::SvBaseLink::UpdateResult ScWebServiceLink::DataChanged(const OUString&, const css::uno::Any&) + { ++ if (pDoc && pDoc->GetDocumentShell() ++ && !pDoc->GetDocumentShell()->GetEmbeddedObjectContainer().getUserAllowsLinkUpdate()) ++ return SUCCESS; ++ + aResult.clear(); + bHasResult = false; + +diff --git a/sc/source/filter/xml/xmlmappingi.cxx b/sc/source/filter/xml/xmlmappingi.cxx +index a917991945d4..809a3cd72560 100644 +--- a/sc/source/filter/xml/xmlmappingi.cxx ++++ b/sc/source/filter/xml/xmlmappingi.cxx +@@ -111,15 +111,6 @@ ScXMLMappingContext::ScXMLMappingContext( ScXMLImport& rImport, + } + } + +-ScXMLMappingContext::~ScXMLMappingContext() +-{ +- ScDocument* pDoc = GetScImport().GetDocument(); +- auto& rDataMapper = pDoc->GetExternalDataMapper(); +- auto& rDataSources = rDataMapper.getDataSources(); +- if(!rDataSources.empty()) +- rDataSources[0].refresh(pDoc, true); +-} +- + uno::Reference + SAL_CALL ScXMLMappingContext::createFastChildContext( + sal_Int32 nElement, const uno::Reference& /*xAttrList*/) +diff --git a/sc/source/filter/xml/xmlmappingi.hxx b/sc/source/filter/xml/xmlmappingi.hxx +index cc38d40dbe93..98a74a7eff31 100644 +--- a/sc/source/filter/xml/xmlmappingi.hxx ++++ b/sc/source/filter/xml/xmlmappingi.hxx +@@ -34,8 +34,6 @@ public: + ScXMLMappingContext( ScXMLImport& rImport, + const rtl::Reference& rAttrList ); + +- virtual ~ScXMLMappingContext() override; +- + virtual css::uno::Reference SAL_CALL createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference& xAttrList) override; +diff --git a/sc/source/ui/dataprovider/dataprovider.cxx b/sc/source/ui/dataprovider/dataprovider.cxx +index 274f01e264dd..bea50ee0f817 100644 +--- a/sc/source/ui/dataprovider/dataprovider.cxx ++++ b/sc/source/ui/dataprovider/dataprovider.cxx +@@ -26,6 +26,10 @@ + #include + #include + #include ++#include ++#include ++#include ++#include + #include + + using namespace com::sun::star; +@@ -194,8 +198,46 @@ const std::vector>& ExternalDataSource:: + return maDataTransformations; + } + +-ExternalDataMapper::ExternalDataMapper(ScDocument& /*rDoc*/) +- //mrDoc(rDoc) ++namespace { ++ ++// A data mapping fetches external data (CSV, HTML, XML) into a sheet. It is ++// registered in the LinkManager so it passes through the same link update ++// control as sheet links, area links, and external references. The link holds ++// the index of its data source in the mapper. That index is stable because ++// data sources are only ever appended, never removed. ++class ScDataProviderLink final : public sfx2::SvBaseLink ++{ ++ ScDocShell& mrDocShell; ++ size_t mnSourceIndex; ++ ++public: ++ ScDataProviderLink(ScDocShell& rDocShell, size_t nSourceIndex) ++ : sfx2::SvBaseLink(SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SIMPLE_FILE) ++ , mrDocShell(rDocShell) ++ , mnSourceIndex(nSourceIndex) ++ { ++ } ++ ++ virtual sfx2::SvBaseLink::UpdateResult DataChanged(const OUString&, ++ const css::uno::Any&) override ++ { ++ if (!mrDocShell.GetEmbeddedObjectContainer().getUserAllowsLinkUpdate()) ++ return SUCCESS; ++ ++ ScDocument& rDoc = mrDocShell.GetDocument(); ++ std::vector& rSources ++ = rDoc.GetExternalDataMapper().getDataSources(); ++ if (mnSourceIndex < rSources.size()) ++ rSources[mnSourceIndex].refresh(&rDoc, true); ++ ++ return SUCCESS; ++ } ++}; ++ ++} ++ ++ExternalDataMapper::ExternalDataMapper(ScDocument& rDoc) ++ : mrDoc(rDoc) + { + } + +@@ -206,6 +248,19 @@ ExternalDataMapper::~ExternalDataMapper() + void ExternalDataMapper::insertDataSource(const sc::ExternalDataSource& rSource) + { + maDataSources.push_back(rSource); ++ ++ ScDocShell* pDocShell = mrDoc.GetDocumentShell(); ++ if (!pDocShell) ++ return; ++ ++ sfx2::LinkManager* pLinkManager = mrDoc.GetLinkManager(); ++ if (!pLinkManager) ++ return; ++ ++ ScDataProviderLink* pLink = new ScDataProviderLink(*pDocShell, maDataSources.size() - 1); ++ const OUString& rProvider = rSource.getProvider(); ++ pLinkManager->InsertFileLink(*pLink, sfx2::SvBaseLinkObjectType::ClientFile, ++ rSource.getURL(), &rProvider, nullptr); + } + + const std::vector& ExternalDataMapper::getDataSources() const +diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx +index 91195ba79a8f..33563857efff 100644 +--- a/sc/source/ui/docshell/docsh4.cxx ++++ b/sc/source/ui/docshell/docsh4.cxx +@@ -501,6 +501,7 @@ void ScDocShell::Execute( SfxRequest& rReq ) + rHelpBtn.set_label(GetStandardText(StandardButtonType::Help).replaceFirst("~", "")); + rHelpBtn.connect_clicked(LINK(nullptr, LinkHelp, DispatchHelpLinksHdl)); + weld::Button& rBtn = pInfoBar->addButton(); ++ rBtn.set_buildable_name(u"allowupdating"_ustr); + rBtn.set_label(ScResId(STR_ENABLE_CONTENT)); + rBtn.set_tooltip_text(ScResId(STR_ENABLE_CONTENT_TOOLTIP)); + rBtn.connect_clicked(LINK(this, ScDocShell, ReloadAllLinksHdl)); +diff --git a/sc/source/ui/docshell/tablink.cxx b/sc/source/ui/docshell/tablink.cxx +index 4babed2103ed..27e8631a8678 100644 +--- a/sc/source/ui/docshell/tablink.cxx ++++ b/sc/source/ui/docshell/tablink.cxx +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + #include + + #include +#@@ -139,6 +140,9 @@ bool ScTableLink::Refresh(const OUString& rNewFile, const OUString& rNewFilter, +# if (rNewFile.isEmpty() || rNewFilter.isEmpty()) +# return false; +# +#+ if (!m_rDocSh.GetEmbeddedObjectContainer().getUserAllowsLinkUpdate()) +#+ return false; +#+ +# OUString aNewUrl = ScGlobal::GetAbsDocName(rNewFile, &m_rDocSh); +# bool bNewUrlName = aFileName != aNewUrl; +# +diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx +index 8e2551a9f02d..164f3dfd8b55 100644 +--- a/sc/source/ui/view/tabvwsh4.cxx ++++ b/sc/source/ui/view/tabvwsh4.cxx +@@ -1632,7 +1632,8 @@ void ScTabViewShell::Construct( TriState nForceDesignMode ) + if (!bLink) + { + const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager(); +- if (rDoc.HasLinkFormulaNeedingCheck() || rDoc.HasAreaLinks() || rMgr.hasExternalLinks()) ++ if (rDoc.HasLinkFormulaNeedingCheck() || rDoc.HasAreaLinks() ++ || rDoc.HasDataProviderMappings() || rMgr.hasExternalLinks()) + bLink = true; + } + if (bLink) +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63267-2.diff libreoffice-25.2.3/debian/patches/CVE-2026-63267-2.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63267-2.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63267-2.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,55 @@ +From 88d9cca9ca0ab1eeb0ba063b8fedb63e92c7578a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sat, 11 Jul 2026 23:43:49 +0000 +Subject: [PATCH] sc: check the host when fetching an external data range +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +checked only the file path allowlist. reject hosts outside it +too, like ScExternalRefManager and ScWebServiceLink. + +Signed-off-by: Caolán McNamara +Change-Id: I85baf17e028b8773a886945cfccd0482e5ae2b34 +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/6935 +Reviewed-by: Miklos Vajna +Tested-by: Jenkins CPCI +(cherry picked from commit 29b5cb45a18ca79b28ce3a02be22803d94a36368) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208197 +Reviewed-by: Dan Williams +Tested-by: Christian Lohmaier +Reviewed-by: Christian Lohmaier +Reviewed-by: Ilmari Lauhakangas +Reviewed-by: Xisco Fauli +--- + sc/source/ui/dataprovider/dataprovider.cxx | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/sc/source/ui/dataprovider/dataprovider.cxx b/sc/source/ui/dataprovider/dataprovider.cxx +index 2cde3d3d93d0..274f01e264dd 100644 +--- a/sc/source/ui/dataprovider/dataprovider.cxx ++++ b/sc/source/ui/dataprovider/dataprovider.cxx +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + + #include "htmldataprovider.hxx" +@@ -40,6 +41,12 @@ std::unique_ptr DataProvider::FetchStreamFromURL(const OUString& rURL, + return nullptr; + } + ++ if (HostFilter::isForbidden(aURLObject.GetHost())) ++ { ++ SAL_WARN("sc.ui", "DataProvider::FetchStreamFromURL: blocked host: \"" << rURL << "\""); ++ return nullptr; ++ } ++ + try + { + uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess = ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ); +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63268-1.diff libreoffice-25.2.3/debian/patches/CVE-2026-63268-1.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63268-1.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63268-1.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,57 @@ +From 8df346ce70998c9f6f1caebf0134a920fc270f68 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sun, 12 Jul 2026 18:29:50 +0000 +Subject: [PATCH] sc: quote the table name in the sql data provider query +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Caolán McNamara +Change-Id: I27a52fe9b3a3d9a9703589b74df259baf2312c46 +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/6707 +Reviewed-by: Miklos Vajna +Tested-by: Jenkins CPCI +(cherry picked from commit 1d24f1b1937995936011f61b6c1436d821f66faf) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208009 +Reviewed-by: Xisco Fauli +Tested-by: Jenkins +(cherry picked from commit d7712feea1d1992c62f72aeeec32c2053556898b) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208033 +Reviewed-by: Ilmari Lauhakangas +Tested-by: Ilmari Lauhakangas +Reviewed-by: Michael Weghorn +--- + sc/source/ui/dataprovider/sqldataprovider.cxx | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/sc/source/ui/dataprovider/sqldataprovider.cxx b/sc/source/ui/dataprovider/sqldataprovider.cxx +index e4610c6dcea1..7929754e9b68 100644 +--- a/sc/source/ui/dataprovider/sqldataprovider.cxx ++++ b/sc/source/ui/dataprovider/sqldataprovider.cxx +@@ -16,6 +16,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -80,10 +82,13 @@ void SQLFetchThread::execute() + + uno::Reference xConnection = xSource->connectWithCompletion(xHandler); + ++ const OUString aQuote = xConnection->getMetaData()->getIdentifierQuoteString(); ++ const OUString aQuotedTable = ::dbtools::quoteName(aQuote, aTable); ++ + uno::Reference xStatement = xConnection->createStatement(); + + uno::Reference xResult +- = xStatement->executeQuery("SELECT * FROM " + aTable); ++ = xStatement->executeQuery("SELECT * FROM " + aQuotedTable); + + if (xResult.is()) + { +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63268-2.diff libreoffice-25.2.3/debian/patches/CVE-2026-63268-2.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63268-2.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63268-2.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,65 @@ +From a6fb1b10bb1aaeab6044fea6c68fdd2e9e471482 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sun, 12 Jul 2026 18:57:00 +0000 +Subject: [PATCH] sc: only build the supported data providers when loading a + document +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Build a data mapping only for the csv, html and xml providers. Any +other provider name in the document is ignored. + +The sql provider is not included. It never worked and was dropped from +the Data Provider dialog in tdf#169079. + +Signed-off-by: Caolán McNamara +Change-Id: Iaa8b5ae4f37693d82938c12b725ee05a3b115732 +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/6708 +Tested-by: Jenkins CPCI +Reviewed-by: Miklos Vajna +(cherry picked from commit 9b6d7ec607e68c79ce685f126139ef826776e783) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208149 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +(cherry picked from commit 104d2b4f5dae917661b20b18d5d2043fca4407e4) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208159 +Tested-by: Ilmari Lauhakangas +Reviewed-by: Hossein +Reviewed-by: Ilmari Lauhakangas +--- + sc/source/filter/xml/xmlmappingi.cxx | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/sc/source/filter/xml/xmlmappingi.cxx b/sc/source/filter/xml/xmlmappingi.cxx +index 5ce0967762ff..a917991945d4 100644 +--- a/sc/source/filter/xml/xmlmappingi.cxx ++++ b/sc/source/filter/xml/xmlmappingi.cxx +@@ -14,6 +14,7 @@ + #include + #include + ++#include + #include + #include + +@@ -102,6 +103,16 @@ ScXMLMappingContext::ScXMLMappingContext( ScXMLImport& rImport, + + if (!aProvider.isEmpty()) + { ++ // Only build the data providers we support. The sql provider is left ++ // out: it was never finished and was dropped from the dialog in tdf#169079. ++ if (aProvider != "org.libreoffice.calc.csv" ++ && aProvider != "org.libreoffice.calc.html" ++ && aProvider != "org.libreoffice.calc.xml") ++ { ++ SAL_WARN("sc", "ignoring document data mapping for provider \"" << aProvider << "\""); ++ return; ++ } ++ + ScDocument* pDoc = GetScImport().GetDocument(); + auto& rDataMapper = pDoc->GetExternalDataMapper(); + sc::ExternalDataSource aSource(aURL, aProvider, pDoc); +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63269-1.diff libreoffice-25.2.3/debian/patches/CVE-2026-63269-1.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63269-1.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63269-1.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,83 @@ +From 98b05de11f4e56aebc257137d5d8c7255f674c28 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 13 Jul 2026 22:42:37 +0000 +Subject: [PATCH] limit the gstreamer backend to simple self-contained media +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The adaptive-streaming cases follow a more complicated indirect route of +a manifest to further resources which is atypical for our use. + +Change-Id: I1a3e51d23cc4e8e2912304d5d1c3337c71c1029e +Signed-off-by: Caolán McNamara +Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/7008 +Tested-by: Jenkins CPCI +Reviewed-by: Miklos Vajna +(cherry picked from commit c7eada5bc2233369e196f2c93e7606b56e3acc62) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208333 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208392 +Reviewed-by: Hossein +Tested-by: Ilmari Lauhakangas +Reviewed-by: Ilmari Lauhakangas +--- + avmedia/source/gstreamer/gstplayer.cxx | 33 ++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/avmedia/source/gstreamer/gstplayer.cxx b/avmedia/source/gstreamer/gstplayer.cxx +index d63b8e809bf7..965981c648f2 100644 +--- a/avmedia/source/gstreamer/gstplayer.cxx ++++ b/avmedia/source/gstreamer/gstplayer.cxx +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -329,6 +330,38 @@ Player::Player() : + + mbInitialized = gst_init_check( &argc, &argv, &pError ); + ++ if (mbInitialized) ++ { ++ // Drop the "Adaptive" ones to rank none as a crude but simple way to ++ // drop the cases that take a manifest to further resources that it ++ // names. Otherwise an option is to follow more closely what browsers ++ // probably do here and register a handler for fetching data. ++ GstRegistry* pRegistry = gst_registry_get(); ++ GList* pFactories = gst_registry_get_feature_list(pRegistry, GST_TYPE_ELEMENT_FACTORY); ++ for (GList* pItem = pFactories; pItem; pItem = pItem->next) ++ { ++ GstElementFactory* pFactory = GST_ELEMENT_FACTORY(pItem->data); ++ const gchar* pKlass = gst_element_factory_get_metadata(pFactory, GST_ELEMENT_METADATA_KLASS); ++ if (!pKlass) ++ continue; ++ ++ OString aKlass(pKlass); ++ bool bAdaptive = false; ++ for (sal_Int32 nIndex = 0; nIndex >= 0;) ++ { ++ if (o3tl::getToken(aKlass, 0, '/', nIndex) == "Adaptive") ++ { ++ bAdaptive = true; ++ break; ++ } ++ } ++ ++ if (bAdaptive) ++ gst_plugin_feature_set_rank(GST_PLUGIN_FEATURE(pFactory), GST_RANK_NONE); ++ } ++ gst_plugin_feature_list_free(pFactories); ++ } ++ + SAL_INFO( "avmedia.gstreamer", AVVERSION << this << " Player::Player" ); + + if (pError != nullptr) +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63269-2.diff libreoffice-25.2.3/debian/patches/CVE-2026-63269-2.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63269-2.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63269-2.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,393 @@ +From d8fa9ff8432320a144de0710175555edd777b9b4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 13 Jul 2026 22:42:07 +0000 +Subject: [PATCH] put media files under link update control +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A media object whose content lives at an external URL, rather than +inside the document, is registered with the link manager like a linked +graphic. So it then shares the usual link update mechanism. + +Media copied into the document is extracted to a temp file and is not a +link, so that's left alone. + +Change-Id: I59dadaf05567ee9d9c0492b13cbc7174aca953da +Signed-off-by: Caolán McNamara +Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/6980 +Tested-by: Jenkins CPCI +Reviewed-by: Miklos Vajna +(cherry picked from commit 1ea4fc54036587c7eb4d4cea74e776de9e6baaf3) +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208393 +Reviewed-by: Hossein +Tested-by: Ilmari Lauhakangas +Reviewed-by: Ilmari Lauhakangas +--- + include/svx/svdomedia.hxx | 13 +++ + sd/source/ui/docshell/docshel4.cxx | 2 + + svx/qa/unit/data/media-link.fodp | 19 ++++ + svx/qa/unit/sdr.cxx | 35 +++++++ + svx/source/svdraw/svdomedia.cxx | 154 ++++++++++++++++++++++++++--- + 5 files changed, 209 insertions(+), 14 deletions(-) + create mode 100644 svx/qa/unit/data/media-link.fodp + +diff --git a/include/svx/svdomedia.hxx b/include/svx/svdomedia.hxx +index b1c5959f4b91..ad1c6ba3604e 100644 +--- a/include/svx/svdomedia.hxx ++++ b/include/svx/svdomedia.hxx +@@ -29,10 +29,12 @@ class Graphic; + namespace sdr::contact { class ViewContactOfSdrMediaObj; } + namespace com::sun::star::graphic { class XGraphic; } + ++class SdrMediaLink; + + class SVXCORE_DLLPUBLIC SdrMediaObj final : public SdrRectObj + { + friend class sdr::contact::ViewContactOfSdrMediaObj; ++ friend class SdrMediaLink; + + private: + // protected destructor - due to final, make private +@@ -78,6 +80,17 @@ public: + private: + SAL_DLLPRIVATE void mediaPropertiesChanged( const ::avmedia::MediaItem& rNewState ); + SAL_DLLPRIVATE virtual std::unique_ptr CreateObjectSpecificViewContact() override; ++ SAL_DLLPRIVATE virtual void handlePageChange(SdrPage* pOldPage, SdrPage* pNewPage) override; ++ ++ // Register an external media reference as a document link, so it takes ++ // part in the normal link update permission just like a linked graphic. ++ // Media stored inside the document is not a link and is left alone. ++ SAL_DLLPRIVATE void ImpRegisterLink(); ++ SAL_DLLPRIVATE void ImpDeregisterLink(); ++ ++ // Fetch a snapshot frame from the media URL. The caller decides ++ // whether a fetch is allowed. ++ SAL_DLLPRIVATE void grabSnapshot(const OUString& rRealURL) const; + + struct Impl; + std::unique_ptr m_xImpl; +diff --git a/sd/source/ui/docshell/docshel4.cxx b/sd/source/ui/docshell/docshel4.cxx +index dca885bcd2cd..f615de240aa5 100644 +--- a/sd/source/ui/docshell/docshel4.cxx ++++ b/sd/source/ui/docshell/docshel4.cxx +@@ -452,6 +452,8 @@ bool DrawDocShell::ImportFrom(SfxMedium &rMedium, + } + else // initial loading of the document + { ++ comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer(); ++ rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); + mpDoc->EnableUndo(false); + } + +--- a/svx/qa/unit/data/media-link.fodp 2026-09-06 11:55:41.811378198 +0200 ++++ b/svx/qa/unit/data/media-link.fodp 2026-10-03 08:11:50.266823566 +0200 +@@ -0,0 +1,19 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/svx/qa/unit/sdr.cxx b/svx/qa/unit/sdr.cxx +index 3b7139acb3e8..7352bb0ef762 100644 +--- a/svx/qa/unit/sdr.cxx ++++ b/svx/qa/unit/sdr.cxx +@@ -7,6 +7,8 @@ + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + ++#include ++ + #include + + #include +@@ -14,9 +16,11 @@ + + #include + #include ++#include + #include + #include + #include ++#include + #include + #include + #include +@@ -189,6 +193,38 @@ CPPUNIT_TEST_FIXTURE(SdrTest, testSlideBackground) + // i.e. the rendering did not find the bitmap. + assertXPath(pDocument, "//bitmap", 1); + } ++ ++CPPUNIT_TEST_FIXTURE(SdrTest, testMediaLinkNotFetchedWhenUpdatesDisallowed) ++{ ++ // A media object referenced by an external xlink:href, with no copy of ++ // the media stored inside the document. ++ loadFromFile(u"media-link.fodp"); ++ uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); ++ uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), ++ uno::UNO_QUERY); ++ auto* pSvxDrawPage = dynamic_cast(xDrawPage.get()); ++ CPPUNIT_ASSERT(pSvxDrawPage); ++ auto* pMedia = dynamic_cast(pSvxDrawPage->GetSdrPage()->GetObj(0)); ++ CPPUNIT_ASSERT(pMedia); ++ ++ // With link updates disallowed, as when loading or converting a document ++ // without a user present to approve them, asking for the placeholder image ++ // must not reach out to the external URL. Without the fix the snapshot is ++ // generated (an empty placeholder bitmap even where no media backend is built, ++ // and the referenced content where one is), so the returned graphic is set. ++ SfxObjectShell* pShell = SfxObjectShell::GetShellFromComponent(mxComponent); ++ CPPUNIT_ASSERT(pShell); ++ pShell->getEmbeddedObjectContainer().setUserAllowsLinkUpdate(false); ++ CPPUNIT_ASSERT(!pMedia->getSnapshot().is()); ++ ++#if HAVE_FEATURE_AVMEDIA ++ // Once updates are allowed the same request produces a graphic, so it was ++ // the permission alone that blocked the fetch above. ++ pShell->getEmbeddedObjectContainer().setUserAllowsLinkUpdate(true); ++ CPPUNIT_ASSERT(pMedia->getSnapshot().is()); ++#endif ++} ++ + } + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/svx/source/svdraw/svdomedia.cxx b/svx/source/svdraw/svdomedia.cxx +index 2f702adba3d4..32603bd76634 100644 +--- a/svx/source/svdraw/svdomedia.cxx ++++ b/svx/source/svdraw/svdomedia.cxx +@@ -22,6 +22,7 @@ + #include + + #include ++#include + + #include + #include +@@ -38,10 +39,29 @@ + #include + #include + #include ++#include ++#include ++#include ++#include + + using namespace ::com::sun::star; + + ++// A media object that points at an external URL is a document link. Registering ++// it with the link manager lets it share the normal link update permission: the ++// snapshot is only fetched from the URL once the user has allowed link updates. ++class SdrMediaLink final : public sfx2::SvBaseLink ++{ ++ SdrMediaObj& mrMediaObj; ++ ++public: ++ explicit SdrMediaLink(SdrMediaObj& rObj); ++ ++ virtual void Closed() override; ++ virtual ::sfx2::SvBaseLink::UpdateResult DataChanged( ++ const OUString& rMimeType, const css::uno::Any& rValue) override; ++}; ++ + struct SdrMediaObj::Impl + { + ::avmedia::MediaItem m_MediaProperties; +@@ -54,8 +74,41 @@ struct SdrMediaObj::Impl + uno::Reference< graphic::XGraphic > m_xCachedSnapshot; + rtl::Reference m_xPlayerListener; + OUString m_LastFailedPkgURL; ++ // owned by the link manager while registered, null otherwise ++ SdrMediaLink* m_pMediaLink = nullptr; + }; + ++SdrMediaLink::SdrMediaLink(SdrMediaObj& rObj) ++ : ::sfx2::SvBaseLink(::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SIMPLE_FILE) ++ , mrMediaObj(rObj) ++{ ++ SetSynchron(false); ++} ++ ++::sfx2::SvBaseLink::UpdateResult SdrMediaLink::DataChanged( ++ const OUString&, const css::uno::Any&) ++{ ++ // Reached only after a link update was allowed, so drop the placeholder ++ // and fetch a fresh snapshot now, like a linked graphic refetches. ++ mrMediaObj.m_xImpl->m_xCachedSnapshot.clear(); ++#if HAVE_FEATURE_AVMEDIA ++ mrMediaObj.m_xImpl->m_xPlayerListener.clear(); ++ OUString aRealURL = mrMediaObj.m_xImpl->m_MediaProperties.getTempURL(); ++ if (aRealURL.isEmpty()) ++ aRealURL = mrMediaObj.m_xImpl->m_MediaProperties.getURL(); ++ if (!aRealURL.isEmpty()) ++ mrMediaObj.grabSnapshot(aRealURL); ++#endif ++ mrMediaObj.ActionChanged(); ++ return SUCCESS; ++} ++ ++void SdrMediaLink::Closed() ++{ ++ mrMediaObj.m_xImpl->m_pMediaLink = nullptr; ++ SvBaseLink::Closed(); ++} ++ + SdrMediaObj::SdrMediaObj(SdrModel& rSdrModel) + : SdrRectObj(rSdrModel) + ,m_xImpl( new Impl ) +@@ -91,6 +144,7 @@ SdrMediaObj::SdrMediaObj( + + SdrMediaObj::~SdrMediaObj() + { ++ ImpDeregisterLink(); + } + + bool SdrMediaObj::HasTextEdit() const +@@ -182,26 +236,47 @@ uno::Reference< graphic::XGraphic > const & SdrMediaObj::getSnapshot() const + + OUString aRealURL = m_xImpl->m_MediaProperties.getTempURL(); + if( aRealURL.isEmpty() ) ++ { ++ // No extracted copy inside the document, so the media is reached ++ // through its URL. Treat it like a linked graphic and only fetch ++ // once the user has allowed link updates, so opening or converting ++ // a document never silently fetches the referenced content. A ++ // model with no document shell has no user to ask, so it does not ++ // fetch either. ++ sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager()); ++ SfxObjectShell* pShell = pLinkManager ? pLinkManager->GetPersist() : nullptr; ++ if (!pShell || !pShell->getEmbeddedObjectContainer().getUserAllowsLinkUpdate()) ++ return m_xImpl->m_xCachedSnapshot; + aRealURL = m_xImpl->m_MediaProperties.getURL(); +- OUString sReferer = m_xImpl->m_MediaProperties.getReferer(); +- OUString sMimeType = m_xImpl->m_MediaProperties.getMimeType(); +- uno::Reference xCachedSnapshot = m_xImpl->m_xCachedSnapshot; +- +- m_xImpl->m_xPlayerListener.set(new avmedia::PlayerListener( +- [this, xCachedSnapshot, aRealURL, sReferer, sMimeType](const css::uno::Reference& rPlayer){ +- SolarMutexGuard g; +- uno::Reference xGraphic +- = m_xImpl->m_MediaProperties.getGraphic().GetXGraphic(); +- m_xImpl->m_xCachedSnapshot = avmedia::MediaWindow::grabFrame(rPlayer, xGraphic); +- ActionChanged(); +- })); +- +- avmedia::MediaWindow::grabFrame(aRealURL, sReferer, sMimeType, m_xImpl->m_xPlayerListener); ++ } ++ grabSnapshot(aRealURL); + } + #endif + return m_xImpl->m_xCachedSnapshot; + } + ++void SdrMediaObj::grabSnapshot(const OUString& rRealURL) const ++{ ++#if HAVE_FEATURE_AVMEDIA ++ OUString sReferer = m_xImpl->m_MediaProperties.getReferer(); ++ OUString sMimeType = m_xImpl->m_MediaProperties.getMimeType(); ++ uno::Reference xCachedSnapshot = m_xImpl->m_xCachedSnapshot; ++ ++ m_xImpl->m_xPlayerListener.set(new avmedia::PlayerListener( ++ [this, xCachedSnapshot, rRealURL, sReferer, sMimeType](const css::uno::Reference& rPlayer){ ++ SolarMutexGuard g; ++ uno::Reference xGraphic ++ = m_xImpl->m_MediaProperties.getGraphic().GetXGraphic(); ++ m_xImpl->m_xCachedSnapshot = avmedia::MediaWindow::grabFrame(rPlayer, xGraphic); ++ ActionChanged(); ++ })); ++ ++ avmedia::MediaWindow::grabFrame(rRealURL, sReferer, sMimeType, m_xImpl->m_xPlayerListener); ++#else ++ (void)rRealURL; ++#endif ++} ++ + void SdrMediaObj::AdjustToMaxRect( const tools::Rectangle& rMaxRect, bool bShrinkOnly /* = false */ ) + { + Size aSize( Application::GetDefaultDevice()->PixelToLogic( +@@ -400,6 +475,8 @@ void SdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewProper + { + m_xImpl->m_xCachedSnapshot.clear(); + m_xImpl->m_xPlayerListener.clear(); ++ // the URL is changing, so any link registered for the old one is stale ++ ImpDeregisterLink(); + m_xImpl->m_MediaProperties.setFallbackURL( rNewProperties.getFallbackURL() ); + OUString const& url(rNewProperties.getURL()); + if (url.startsWithIgnoreAsciiCase("vnd.sun.star.Package:")) +@@ -441,6 +518,7 @@ void SdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewProper + m_xImpl->m_pTempFile.reset(); + m_xImpl->m_MediaProperties.setURL(url, u""_ustr, rNewProperties.getReferer()); + } ++ ImpRegisterLink(); + bBroadcastChanged = true; + } + +@@ -466,4 +544,52 @@ void SdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewProper + } + } + ++void SdrMediaObj::ImpRegisterLink() ++{ ++ sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager()); ++ if (!pLinkManager || m_xImpl->m_pMediaLink) ++ return; ++ ++#if HAVE_FEATURE_AVMEDIA ++ // Media copied into the document is extracted to a temporary file and is ++ // not a link. Only an external reference gets registered. ++ if (m_xImpl->m_pTempFile) ++ return; ++#endif ++ const OUString& rURL = m_xImpl->m_MediaProperties.getURL(); ++ if (rURL.isEmpty() || rURL.startsWithIgnoreAsciiCase("vnd.sun.star.Package:")) ++ return; ++ ++ // Registration happens even in a build without media playback, so the ++ // external reference stays visible to the user as a document link. ++ m_xImpl->m_pMediaLink = new SdrMediaLink(*this); ++ pLinkManager->InsertFileLink(*m_xImpl->m_pMediaLink, ++ sfx2::SvBaseLinkObjectType::ClientFile, rURL); ++} ++ ++void SdrMediaObj::ImpDeregisterLink() ++{ ++ sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager()); ++ if (pLinkManager && m_xImpl->m_pMediaLink) ++ { ++ // Remove implicitly deletes the link object ++ pLinkManager->Remove(m_xImpl->m_pMediaLink); ++ m_xImpl->m_pMediaLink = nullptr; ++ } ++} ++ ++void SdrMediaObj::handlePageChange(SdrPage* pOldPage, SdrPage* pNewPage) ++{ ++ const bool bRemove(pNewPage == nullptr && pOldPage != nullptr); ++ const bool bInsert(pNewPage != nullptr && pOldPage == nullptr); ++ ++ if (bRemove) ++ ImpDeregisterLink(); ++ ++ SdrRectObj::handlePageChange(pOldPage, pNewPage); ++ ++ if (bInsert) ++ ImpRegisterLink(); ++} ++ + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63269-3.diff libreoffice-25.2.3/debian/patches/CVE-2026-63269-3.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63269-3.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63269-3.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,82 @@ +From a60fb2e252841830162b79fa553cc12b23212847 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 14 Jul 2026 19:12:01 +0100 +Subject: [PATCH] put slideshow media links under link control + +Change-Id: I22b8e5577e2a450d0d4043db891eec4617dcb2fe +Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/7009 +Tested-by: Jenkins CPCI +Reviewed-by: Miklos Vajna +(cherry picked from commit f0768394c14f928d47547408fc1195368be81f86) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208332 +Reviewed-by: Xisco Fauli +Tested-by: Jenkins +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208391 +Tested-by: Ilmari Lauhakangas +Reviewed-by: Ilmari Lauhakangas +Reviewed-by: Hossein +--- + .../source/engine/shapes/viewmediashape.cxx | 19 ++++++++++++++++++- + .../source/engine/shapes/viewmediashape.hxx | 1 + + 2 files changed, 19 insertions(+), 1 deletion(-) + +diff --git a/slideshow/source/engine/shapes/viewmediashape.cxx b/slideshow/source/engine/shapes/viewmediashape.cxx +index 310bc42800ca..1bf1cb41d590 100644 +--- a/slideshow/source/engine/shapes/viewmediashape.cxx ++++ b/slideshow/source/engine/shapes/viewmediashape.cxx +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -267,6 +268,21 @@ namespace slideshow::internal + } + + ++ bool ViewMediaShape::implMediaLinkAllowed() const ++ { ++ SdrObject* pObj = SdrObject::getSdrObjectFromXShape(mxShape); ++ if (!pObj) ++ return false; ++ uno::Reference xModelProps( ++ pObj->getSdrModelFromSdrObject().getUnoModel(), uno::UNO_QUERY); ++ if (!xModelProps.is()) ++ return false; ++ bool bAllow = false; ++ xModelProps->getPropertyValue(u"AllowLinkUpdate"_ustr) >>= bAllow; ++ return bAllow; ++ } ++ ++ + bool ViewMediaShape::implInitialize( const ::basegfx::B2DRectangle& rBounds ) + { + if( !mxPlayer.is() && mxShape.is() ) +@@ -294,7 +310,8 @@ namespace slideshow::internal + { + implInitializeMediaPlayer( aURL, sMimeType ); + } +- else if (xPropSet->getPropertyValue(u"MediaURL"_ustr) >>= aURL) ++ else if ((xPropSet->getPropertyValue(u"MediaURL"_ustr) >>= aURL) ++ && implMediaLinkAllowed()) + { + if ( maFallbackDir.getLength() && + aURL.startsWith("file:///") && +diff --git a/slideshow/source/engine/shapes/viewmediashape.hxx b/slideshow/source/engine/shapes/viewmediashape.hxx +index 34be8536b73b..3631e35b1ec9 100644 +--- a/slideshow/source/engine/shapes/viewmediashape.hxx ++++ b/slideshow/source/engine/shapes/viewmediashape.hxx +@@ -144,6 +144,7 @@ namespace slideshow::internal + private: + + bool implInitialize( const ::basegfx::B2DRectangle& rBounds ); ++ bool implMediaLinkAllowed() const; + void implSetMediaProperties( const css::uno::Reference< css::beans::XPropertySet >& rxProps ); + void implInitializeMediaPlayer( const OUString& rMediaURL, const OUString& rMimeType ); + void implInitializePlayerWindow( const ::basegfx::B2DRectangle& rBounds, +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63277.diff libreoffice-25.2.3/debian/patches/CVE-2026-63277.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63277.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63277.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,53 @@ +From e2a2f4e407130c108a731aaffc930191e3b9cfc7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 12 Jun 2026 19:17:25 +0000 +Subject: [PATCH] translate only file URLs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Change-Id: I41076b8af670d673bf29b14c02db0c66744feb0b +Signed-off-by: Caolán McNamara +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/4409 +Tested-by: Jenkins CPCI +Reviewed-by: Stephan Bergmann +(cherry picked from commit 478eb7de0d14a05e6501bd44851f73ec0df5c59a) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/206635 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +(cherry picked from commit e663f8baed49976fd4d4d6d1c277ab036cd28736) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/206672 +--- + jvmaccess/source/classpath.cxx | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/jvmaccess/source/classpath.cxx b/jvmaccess/source/classpath.cxx +index 95915196bad9..bb0b16bc0220 100644 +--- a/jvmaccess/source/classpath.cxx ++++ b/jvmaccess/source/classpath.cxx +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -76,6 +77,14 @@ jobjectArray jvmaccess::ClassPath::translateToUrls( + nullptr, anyEx ); + } + } ++ css::uno::Reference< css::uri::XUriReference > uriRef( ++ css::uri::UriReferenceFactory::create(context)->parse(url)); ++ if (!uriRef.is() || !uriRef->getScheme().equalsIgnoreAsciiCase("file")) ++ { ++ throw css::lang::IllegalArgumentException( ++ "non-local Java class path entry: " + url, ++ css::uno::Reference< css::uno::XInterface >(), 0); ++ } + jvalue arg; + arg.l = environment->NewString( + reinterpret_cast< jchar const * >(url.getStr()), +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/Show-infobar-for-calc-graphics-with-remote-content-too.diff libreoffice-25.2.3/debian/patches/Show-infobar-for-calc-graphics-with-remote-content-too.diff --- libreoffice-25.2.3/debian/patches/Show-infobar-for-calc-graphics-with-remote-content-too.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/Show-infobar-for-calc-graphics-with-remote-content-too.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,120 @@ +From 728a7015ee921465b6b43fa19dd0c88ef1c3e434 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 1 Apr 2026 20:19:19 +0000 +Subject: [PATCH] Show infobar for calc graphics with remote content too + +Change-Id: I8ed0482344bb06afa6079540ea2a3854930da225 +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/2383 +Tested-by: Jenkins CPCI +Reviewed-by: Miklos Vajna +(cherry picked from commit 1f51bbee0e7661d5607efe2603c59d83f410dd3d) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205492 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208405 +Tested-by: Christian Lohmaier +Reviewed-by: Christian Lohmaier +--- + sc/inc/documentlinkmgr.hxx | 4 ++-- + sc/source/ui/docshell/docsh4.cxx | 7 +++++++ + sc/source/ui/docshell/documentlinkmgr.cxx | 10 ++++++---- + sc/source/ui/view/tabvwsh4.cxx | 2 +- + 4 files changed, 16 insertions(+), 7 deletions(-) + +diff --git a/sc/inc/documentlinkmgr.hxx b/sc/inc/documentlinkmgr.hxx +index de36ec40fa81..36369a5d04ba 100644 +--- a/sc/inc/documentlinkmgr.hxx ++++ b/sc/inc/documentlinkmgr.hxx +@@ -53,7 +53,7 @@ public: + bool idleCheckLinks(); + + bool hasDdeLinks() const; +- bool hasDdeOrOleOrWebServiceLinks() const; ++ bool hasExternalLinks() const; + bool hasExternalRefLinks() const; + + bool updateDdeOrOleOrWebServiceLinks(weld::Window* pWin); +@@ -63,7 +63,7 @@ public: + size_t getDdeLinkCount() const; + + private: +- bool hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const; ++ bool hasExternalLinks(bool bDde, bool bOle, bool bWebService, bool bGraphic) const; + }; + + } +diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx +index a518a06c1a78..91195ba79a8f 100644 +--- a/sc/source/ui/docshell/docsh4.cxx ++++ b/sc/source/ui/docshell/docsh4.cxx +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -210,6 +211,12 @@ void ScDocShell::ReloadAllLinks() + } + + m_pDocument->UpdateAreaLinks(); ++ ++ // update linked graphics from the draw layer ++ if (sfx2::LinkManager* pLinkMgr = m_pDocument->GetDocLinkManager().getLinkManager(false)) ++ { ++ pLinkMgr->UpdateAllLinks(false, false, nullptr, u""_ustr); ++ } + } + + IMPL_LINK( ScDocShell, ReloadAllLinksHdl, weld::Button&, rButton, void ) +diff --git a/sc/source/ui/docshell/documentlinkmgr.cxx b/sc/source/ui/docshell/documentlinkmgr.cxx +index 0fb89cfa0d18..d098631bc214 100644 +--- a/sc/source/ui/docshell/documentlinkmgr.cxx ++++ b/sc/source/ui/docshell/documentlinkmgr.cxx +@@ -125,15 +125,15 @@ bool DocumentLinkManager::idleCheckLinks() + + bool DocumentLinkManager::hasDdeLinks() const + { +- return hasDdeOrOleOrWebServiceLinks(true, false, false); ++ return hasExternalLinks(true, false, false, false); + } + +-bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks() const ++bool DocumentLinkManager::hasExternalLinks() const + { +- return hasDdeOrOleOrWebServiceLinks(true, true, true); ++ return hasExternalLinks(true, true, true, true); + } + +-bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const ++bool DocumentLinkManager::hasExternalLinks(bool bDde, bool bOle, bool bWebService, bool bGraphic) const + { + sfx2::LinkManager* pMgr = mpImpl->mpLinkManager; + if (!pMgr) +@@ -149,6 +149,8 @@ bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, boo + return true; + if (bWebService && dynamic_cast(pBase)) + return true; ++ if (bGraphic && pBase->GetObjType() == sfx2::SvBaseLinkObjectType::ClientGraphic) ++ return true; + } + + return false; +diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx +index 8610ba8eb37a..8e2551a9f02d 100644 +--- a/sc/source/ui/view/tabvwsh4.cxx ++++ b/sc/source/ui/view/tabvwsh4.cxx +@@ -1632,7 +1632,7 @@ void ScTabViewShell::Construct( TriState nForceDesignMode ) + if (!bLink) + { + const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager(); +- if (rDoc.HasLinkFormulaNeedingCheck() || rDoc.HasAreaLinks() || rMgr.hasDdeOrOleOrWebServiceLinks()) ++ if (rDoc.HasLinkFormulaNeedingCheck() || rDoc.HasAreaLinks() || rMgr.hasExternalLinks()) + bLink = true; + } + if (bLink) +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/do-not-load-exotic-protocols-for-document-supplied-data.diff libreoffice-25.2.3/debian/patches/do-not-load-exotic-protocols-for-document-supplied-data.diff --- libreoffice-25.2.3/debian/patches/do-not-load-exotic-protocols-for-document-supplied-data.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/do-not-load-exotic-protocols-for-document-supplied-data.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,128 @@ +From c3355f20dcd5956116819ae4f2f843014407cf4d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sat, 11 Jul 2026 23:43:39 +0000 +Subject: [PATCH] don't bother loading exotic protocols for document-supplied + data +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Caolán McNamara +Change-Id: I5415f4f1804a85a04ff6396d71b7a61b230e1685 +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/6686 +Tested-by: Jenkins CPCI +Reviewed-by: Miklos Vajna +(cherry picked from commit 0274803ae273fa6bdbd1124cedf37395ce847148) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208193 +Reviewed-by: Xisco Fauli +Tested-by: Ilmari Lauhakangas +Reviewed-by: Ilmari Lauhakangas +Reviewed-by: Hossein +--- + forms/source/xforms/model.cxx | 8 ++++++++ + sc/source/core/tool/webservicelink.cxx | 7 +++++++ + sc/source/ui/dataprovider/dataprovider.cxx | 8 ++++++++ + sc/source/ui/dataprovider/sqldataprovider.cxx | 9 +++++++++ + 4 files changed, 32 insertions(+) + +diff --git a/forms/source/xforms/model.cxx b/forms/source/xforms/model.cxx +index 105f7f449963..27844c6398d5 100644 +--- a/forms/source/xforms/model.cxx ++++ b/forms/source/xforms/model.cxx +@@ -32,7 +32,9 @@ + + #include + #include ++#include + #include ++#include + + #include + #include +@@ -318,6 +320,12 @@ void Model::loadInstance( sal_Int32 nInstance ) + if( sURL.isEmpty() ) + return; + ++ if( INetURLObject( sURL ).IsExoticProtocol() ) ++ { ++ SAL_WARN("forms.xforms", "Model::loadInstance: blocked exotic protocol: \"" << sURL << "\""); ++ return; ++ } ++ + try + { + Reference xInput = +diff --git a/sc/source/core/tool/webservicelink.cxx b/sc/source/core/tool/webservicelink.cxx +index c30f34300edf..fb5d81afc87b 100644 +--- a/sc/source/core/tool/webservicelink.cxx ++++ b/sc/source/core/tool/webservicelink.cxx +@@ -40,6 +40,13 @@ sfx2::SvBaseLink::UpdateResult ScWebServiceLink::DataChanged(const OUString&, co + bHasResult = false; + + INetURLObject aURLObject(aURL); ++ if (aURLObject.IsExoticProtocol()) ++ { ++ SAL_WARN("sc.ui", ++ "ScWebServiceLink::DataChanged: blocked exotic protocol: \"" << aURL << "\""); ++ return ERROR_GENERAL; ++ } ++ + const OUString sHost = aURLObject.GetHost(); + if (HostFilter::isForbidden(sHost)) + { +diff --git a/sc/source/ui/dataprovider/dataprovider.cxx b/sc/source/ui/dataprovider/dataprovider.cxx +index 1a31a1afddaf..2cde3d3d93d0 100644 +--- a/sc/source/ui/dataprovider/dataprovider.cxx ++++ b/sc/source/ui/dataprovider/dataprovider.cxx +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + + #include "htmldataprovider.hxx" + #include "xmldataprovider.hxx" +@@ -32,6 +33,13 @@ namespace sc { + + std::unique_ptr DataProvider::FetchStreamFromURL(const OUString& rURL, OStringBuffer& rBuffer) + { ++ INetURLObject aURLObject(rURL); ++ if (aURLObject.IsExoticProtocol()) ++ { ++ SAL_WARN("sc.ui", "DataProvider::FetchStreamFromURL: blocked exotic protocol: \"" << rURL << "\""); ++ return nullptr; ++ } ++ + try + { + uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess = ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ); +diff --git a/sc/source/ui/dataprovider/sqldataprovider.cxx b/sc/source/ui/dataprovider/sqldataprovider.cxx +index 7929754e9b68..ac61a8dc53f0 100644 +--- a/sc/source/ui/dataprovider/sqldataprovider.cxx ++++ b/sc/source/ui/dataprovider/sqldataprovider.cxx +@@ -9,6 +9,8 @@ + + #include "sqldataprovider.hxx" + #include ++#include ++#include + #include + #include + #include +@@ -65,6 +67,13 @@ void SQLFetchThread::execute() + OUString aTable = maID.copy(0, nIndex); + OUString aDatabase = maID.copy(nIndex + 1); + ++ if (INetURLObject(aDatabase).IsExoticProtocol()) ++ { ++ SAL_WARN("sc.ui", ++ "SQLFetchThread::execute: blocked exotic protocol: \"" << aDatabase << "\""); ++ return; ++ } ++ + try + { + uno::Reference xContext +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/firebird-call-writeFile-outside-the-SAL_WARN_IF-cond.patch libreoffice-25.2.3/debian/patches/firebird-call-writeFile-outside-the-SAL_WARN_IF-cond.patch --- libreoffice-25.2.3/debian/patches/firebird-call-writeFile-outside-the-SAL_WARN_IF-cond.patch 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/firebird-call-writeFile-outside-the-SAL_WARN_IF-cond.patch 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,71 @@ +From 1bc0bd3c732e840cf6c5b35eed4e8da0d74b48fc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 30 Jul 2026 13:17:54 +0000 +Subject: [PATCH] firebird: call writeFile outside the SAL_WARN_IF condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +a product build doesn't evaluate the condition, so none of the conf +files were written there. + +since: + +commit b8407b18adf3c6d552d54d7b6657539e2769afd6 +Date: Tue Jul 28 17:08:38 2026 +0000 + + firebird: name the modules of a system firebird by absolute path + +and: + +commit 6ab71a109bd8a8335208c9faa37a3cfa94523148 +Date: Tue Jul 28 11:05:37 2026 +0000 + + Resolves: tdf#172935 Connection from Base to external firebird database refused + +Change-Id: I8c66ae59774a161c8c135b2dea772810d92495dd +Signed-off-by: Caolán McNamara +--- + connectivity/source/drivers/firebird/Driver.cxx | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/connectivity/source/drivers/firebird/Driver.cxx b/connectivity/source/drivers/firebird/Driver.cxx +index 2f63e3270431..3a9c31e37da4 100644 +--- a/connectivity/source/drivers/firebird/Driver.cxx ++++ b/connectivity/source/drivers/firebird/Driver.cxx +@@ -227,8 +227,8 @@ void writeSystemFirebirdPluginsConf(std::u16string_view rDataDirURL) + + const OUString sURL = OUString::Concat(rDataDirURL) + "/" + our_sPluginsConfName; + const OString sContent = aContent.makeStringAndClear(); +- SAL_WARN_IF(!writeFile(sURL, std::string_view(sContent)), "connectivity.firebird", +- "could not write " << sURL); ++ const bool bWritten = writeFile(sURL, std::string_view(sContent)); ++ SAL_WARN_IF(!bWritten, "connectivity.firebird", "could not write " << sURL); + } + + // Copy the conf files of the international modules into an intl subdirectory of the directory the +@@ -274,8 +274,8 @@ void writeSystemFirebirdIntlConfs(std::u16string_view rDataDirURL) + continue; + + const OUString sURL = sTargetURL + "/" + sName; +- SAL_WARN_IF(!writeFile(sURL, std::string_view(sContent)), "connectivity.firebird", +- "could not write " << sURL); ++ const bool bWritten = writeFile(sURL, std::string_view(sContent)); ++ SAL_WARN_IF(!bWritten, "connectivity.firebird", "could not write " << sURL); + } + } + +@@ -430,8 +430,8 @@ void FirebirdDriver::writeExternalDatabaseNames() + const OString sContent = aContent.makeStringAndClear(); + + const OUString sURL = m_firebirdDataDirectory.GetURL() + "/" + our_sDatabasesConfName; +- SAL_WARN_IF(!writeFile(sURL, std::string_view(sContent)), "connectivity.firebird", +- "could not write " << sURL); ++ const bool bWritten = writeFile(sURL, std::string_view(sContent)); ++ SAL_WARN_IF(!bWritten, "connectivity.firebird", "could not write " << sURL); + } + + void FirebirdDriver::disposing() +-- +2.55.0 + diff -Nru libreoffice-25.2.3/debian/patches/firebird-db-connection.diff libreoffice-25.2.3/debian/patches/firebird-db-connection.diff --- libreoffice-25.2.3/debian/patches/firebird-db-connection.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/firebird-db-connection.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,418 @@ +commit 16cf06caff90c0e4d9fe2fc24eac378ed533c48d +Author: Caolán McNamara +Date: Tue Jul 28 11:05:37 2026 +0000 + + Resolves: tdf#172935 Connection from Base to external firebird database refused + + there is one firebird engine per process and it reads its configuration once + from the directory we set up, so a .fdb the user picked somewhere else could + not be attached. firebird resolves a name in databases.conf before it treats + it as a path, so give the file a name there and pass firebird that name, + dropped again when the connection is disposed. + + since: + + commit 520d8173cef39a4da85b3ba21bdaaa3150384c25 + Date: Sun Jul 12 12:10:41 2026 +0000 + + firebird: keep each embedded database's files in one directory + + Change-Id: I4872a4e2165c4701bfb20be5dcd8c119b1723125 + Signed-off-by: Caolán McNamara + Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/7990 + Tested-by: Jenkins CPCI + Reviewed-by: Michael Stahl + (cherry picked from commit 6ab71a109bd8a8335208c9faa37a3cfa94523148) + Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208773 + Tested-by: Jenkins + Reviewed-by: Xisco Fauli + (cherry picked from commit 99bf5222896886d062b6a6a67377e7671de1446a) + Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208855 + +diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx +index 3b918e696d87..c4b9126cd0c9 100644 +--- a/connectivity/source/drivers/firebird/Connection.cxx ++++ b/connectivity/source/drivers/firebird/Connection.cxx +@@ -22,6 +22,7 @@ + #include "Clob.hxx" + #include "Connection.hxx" + #include "DatabaseMetaData.hxx" ++#include "Driver.hxx" + #include "PreparedStatement.hxx" + #include "Statement.hxx" + #include "Util.hxx" +@@ -156,13 +157,14 @@ bool databaseHeaderHasBackupState(const OUString& rDatabasePath) + } + + void Connection::construct(const OUString& url, const Sequence< PropertyValue >& info, +- const OUString& rDatabaseDataDirectoryURL) ++ FirebirdDriver& rDriver) + { + ConnectionGuard aGuard(m_refCount); + + try + { + m_sConnectionURL = url; ++ m_xDriver = &rDriver; + + bool bIsNewDatabase = false; + // the database may be stored as an +@@ -193,7 +195,8 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& + + bIsNewDatabase = !m_xEmbeddedStorage->hasElements(); + +- m_pDatabaseFileDir.reset(new ::utl::TempFileNamed(&rDatabaseDataDirectoryURL, true)); ++ const OUString sDatabaseDataDirectoryURL = rDriver.getDatabaseDataDirectoryURL(); ++ m_pDatabaseFileDir.reset(new ::utl::TempFileNamed(&sDatabaseDataDirectoryURL, true)); + m_pDatabaseFileDir->EnableKillingFile(); + m_sFirebirdURL = m_pDatabaseFileDir->GetFileName() + "/firebird.fdb"; + m_sFBKPath = m_pDatabaseFileDir->GetFileName() + "/firebird.fbk"; +@@ -247,6 +250,10 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& + bIsNewDatabase = true; + + osl::FileBase::getSystemPathFromFileURL(m_sFirebirdURL, m_sFirebirdURL); ++ ++ // The user picked this file, so it is outside the directory firebird is ++ // restricted to. Reach it by the name the driver gives us for it. ++ m_sExternalDatabaseName = rDriver.addExternalDatabaseName(m_sFirebirdURL); + } + } + +@@ -324,12 +331,13 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& + + ISC_STATUS_ARRAY status; /* status vector */ + ISC_STATUS aErr; +- const OString sFirebirdURL = OUStringToOString(m_sFirebirdURL, RTL_TEXTENCODING_UTF8); ++ const OString sDatabaseName ++ = OUStringToOString(getFirebirdDatabaseName(), RTL_TEXTENCODING_UTF8); + if (bIsNewDatabase) + { + aErr = isc_create_database(status, +- sFirebirdURL.getLength(), +- sFirebirdURL.getStr(), ++ sDatabaseName.getLength(), ++ sDatabaseName.getStr(), + &m_aDBHandle, + dpbBuffer.size(), + dpbBuffer.c_str(), +@@ -347,8 +355,8 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >& + } + + aErr = isc_attach_database(status, +- sFirebirdURL.getLength(), +- sFirebirdURL.getStr(), ++ sDatabaseName.getLength(), ++ sDatabaseName.getStr(), + &m_aDBHandle, + dpbBuffer.size(), + dpbBuffer.c_str()); +@@ -948,6 +956,12 @@ void Connection::disposing() + + storeDatabase(); + ++ if (!m_sExternalDatabaseName.isEmpty()) ++ { ++ m_xDriver->removeExternalDatabaseName(m_sExternalDatabaseName); ++ m_sExternalDatabaseName.clear(); ++ } ++ + cppu::WeakComponentImplHelperBase::disposing(); + + m_pDatabaseFileDir.reset(); +diff --git a/connectivity/source/drivers/firebird/Connection.hxx b/connectivity/source/drivers/firebird/Connection.hxx +index a6117f65b173..5d8555a394a1 100644 +--- a/connectivity/source/drivers/firebird/Connection.hxx ++++ b/connectivity/source/drivers/firebird/Connection.hxx +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -128,6 +129,21 @@ + /** We are using an external (local) file */ + bool m_bIsFile; + ++ /** The driver that made this connection, and owns the directory firebird works in. */ ++ rtl::Reference m_xDriver; ++ ++ /** ++ * The name firebird was given for a database outside its own directory, empty when the ++ * database is inside it and its path was handed over directly. ++ */ ++ OUString m_sExternalDatabaseName; ++ ++ /** The name or path this connection hands to firebird to reach its database. */ ++ const OUString& getFirebirdDatabaseName() const ++ { ++ return m_sExternalDatabaseName.isEmpty() ? m_sFirebirdURL : m_sExternalDatabaseName; ++ } ++ + /** When true the embedded database was opened in this session, so the + temporary .fdb holds live data that must be written back into the .odb + when the connection is disposed. */ +@@ -169,7 +185,7 @@ + /// @throws css::uno::RuntimeException + void construct( const OUString& url, + const css::uno::Sequence< css::beans::PropertyValue >& info, +- const OUString& rDatabaseDataDirectoryURL); ++ FirebirdDriver& rDriver); + + const OUString& getConnectionURL() const {return m_sConnectionURL;} + bool isEmbedded() const {return m_bIsEmbedded;} +diff --git a/connectivity/source/drivers/firebird/Driver.cxx b/connectivity/source/drivers/firebird/Driver.cxx +index 3d0b8db41642..134a2ccb3eac 100644 +--- a/connectivity/source/drivers/firebird/Driver.cxx ++++ b/connectivity/source/drivers/firebird/Driver.cxx +@@ -25,13 +25,37 @@ + #include + #include + ++#include ++ ++// firebird's own header has functions with parameters it does not use ++#if defined __GNUC__ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wunused-parameter" ++#endif ++#if defined _MSC_VER ++#pragma warning(push) ++#pragma warning(disable: 4100) // unreferenced formal parameter ++#endif ++#include ++#if defined _MSC_VER ++#pragma warning(pop) ++#endif ++#if defined __GNUC__ ++#pragma GCC diagnostic pop ++#endif ++ + #include + #include + #include + #include ++#include + #include ++#include ++#include + #include + ++#include ++ + using namespace com::sun::star; + using namespace com::sun::star::uno; + using namespace com::sun::star::lang; +@@ -52,6 +76,66 @@ constexpr OUString our_sFirebirdRootVar = u"FIREBIRD"_ustr; + #ifdef MACOSX + constexpr OUString our_sFirebirdLibVar = u"LIBREOFFICE_FIREBIRD_LIB"_ustr; + #endif ++ ++// The name of the file in the firebird directory that maps a name to the absolute path of a ++// database. firebird looks a name up here before it treats it as a path, and re-reads the file ++// whenever it has changed. ++constexpr OUString our_sDatabasesConfName = u"databases.conf"_ustr; ++ ++// Put rContent in the file at rURL, discarding whatever was there before. ++bool writeFile(const OUString& rURL, std::string_view aContent) ++{ ++ ::osl::File aFile(rURL); ++ if (aFile.open(osl_File_OpenFlag_Create | osl_File_OpenFlag_Write) != ::osl::FileBase::E_None) ++ { ++ if (aFile.open(osl_File_OpenFlag_Write) != ::osl::FileBase::E_None) ++ return false; ++ if (aFile.setSize(0) != ::osl::FileBase::E_None) ++ { ++ aFile.close(); ++ return false; ++ } ++ } ++ ++ bool bWholeContentWritten = true; ++ if (!aContent.empty()) ++ { ++ sal_uInt64 nWritten = 0; ++ bWholeContentWritten ++ = aFile.write(aContent.data(), aContent.size(), nWritten) == ::osl::FileBase::E_None ++ && nWritten == aContent.size(); ++ } ++ aFile.close(); ++ return bWholeContentWritten; ++} ++ ++// firebird takes its root directory from the FIREBIRD variable on its first use, and reads the ++// firebird.conf that confines it to that directory only from there. Ask firebird which directory ++// it settled on and treat anything but our own as unconfined. ++bool isFirebirdRootedAt(const OUString& rDataDirPath) ++{ ++ Firebird::IMaster* pMaster = Firebird::fb_get_master_interface(); ++ if (!pMaster) ++ return false; ++ ++ Firebird::IConfigManager* pConfigManager = pMaster->getConfigManager(); ++ if (!pConfigManager) ++ return false; ++ ++ const char* pRootDirectory = pConfigManager->getRootDirectory(); ++ if (!pRootDirectory) ++ return false; ++ ++ OUString sRootPath = OStringToOUString(pRootDirectory, osl_getThreadTextEncoding()); ++ if (sRootPath.endsWith("/") || sRootPath.endsWith("\\")) ++ sRootPath = sRootPath.copy(0, sRootPath.getLength() - 1); ++ ++#if defined(_WIN32) ++ return sRootPath.equalsIgnoreAsciiCase(rDataDirPath); ++#else ++ return sRootPath == rDataDirPath; ++#endif ++} + }; + + FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentContext >& _rxContext) +@@ -90,25 +174,25 @@ FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentCo + sDataDirPath = sDataDirPath.toAsciiUpperCase(); + #endif + ++ // ExternalFileAccess is already None by default. Saying so here keeps a database firebird ++ // opens from reading databases.conf back out of the directory it shares with it. + OString sConf = "DatabaseAccess = Restrict " +- + OUStringToOString(sDataDirPath, RTL_TEXTENCODING_UTF8) + "\n"; ++ + OUStringToOString(sDataDirPath, RTL_TEXTENCODING_UTF8) ++ + "\nExternalFileAccess = None\n"; + + OUString sConfURL = m_firebirdDataDirectory.GetURL() + "/firebird.conf"; +- ::osl::File aConfFile(sConfURL); +- if (aConfFile.open(osl_File_OpenFlag_Create | osl_File_OpenFlag_Write) == ::osl::FileBase::E_None) ++ if (writeFile(sConfURL, std::string_view(sConf)) ++ // An empty databases.conf, so that firebird has the file in hand from its first use and ++ // notices the names added to it later. ++ && writeFile(m_firebirdDataDirectory.GetURL() + "/" + our_sDatabasesConfName, ++ std::string_view())) + { +- sal_uInt64 nWritten = 0; +- if (aConfFile.write(sConf.getStr(), sConf.getLength(), nWritten) == ::osl::FileBase::E_None +- && nWritten == static_cast(sConf.getLength())) +- { +- osl_setEnvironment(our_sFirebirdRootVar.pData, sDataDirPath.pData); +- m_bConfined = true; +- } +- aConfFile.close(); ++ osl_setEnvironment(our_sFirebirdRootVar.pData, sDataDirPath.pData); ++ m_bConfined = isFirebirdRootedAt(sDataDirPath); + } + + SAL_WARN_IF(!m_bConfined, "connectivity.firebird", +- "could not write " << sConfURL << ", firebird connections will be refused"); ++ "firebird is not confined to " << sDataDirPath << ", connections will be refused"); + + #ifndef SYSTEM_FIREBIRD + // Overrides firebird's hardcoded default of /usr/local/firebird on *nix, +@@ -132,6 +216,51 @@ FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentCo + + FirebirdDriver::~FirebirdDriver() = default; + ++OUString FirebirdDriver::addExternalDatabaseName(const OUString& rDatabasePath) ++{ ++ MutexGuard aGuard(m_aMutex); ++ ++ sal_uInt8 aUuid[16]; ++ rtl_createUuid(aUuid, nullptr, false); ++ ++ OUStringBuffer aName(u"database"); ++ for (const sal_uInt8 nByte : aUuid) ++ { ++ aName.append(OUString::number(nByte >> 4, 16) + OUString::number(nByte & 0x0F, 16)); ++ } ++ const OUString sName = aName.makeStringAndClear(); ++ ++ m_aExternalDatabaseNames.emplace(sName, rDatabasePath); ++ writeExternalDatabaseNames(); ++ ++ return sName; ++} ++ ++void FirebirdDriver::removeExternalDatabaseName(const OUString& rName) ++{ ++ MutexGuard aGuard(m_aMutex); ++ ++ if (m_aExternalDatabaseNames.erase(rName) != 0) ++ writeExternalDatabaseNames(); ++} ++ ++void FirebirdDriver::writeExternalDatabaseNames() ++{ ++ MutexGuard aGuard(m_aMutex); ++ ++ OStringBuffer aContent; ++ for (const auto& [rName, rPath] : m_aExternalDatabaseNames) ++ { ++ aContent.append(OUStringToOString(rName, RTL_TEXTENCODING_UTF8) + " = " ++ + OUStringToOString(rPath, RTL_TEXTENCODING_UTF8) + "\n"); ++ } ++ const OString sContent = aContent.makeStringAndClear(); ++ ++ const OUString sURL = m_firebirdDataDirectory.GetURL() + "/" + our_sDatabasesConfName; ++ SAL_WARN_IF(!writeFile(sURL, std::string_view(sContent)), "connectivity.firebird", ++ "could not write " << sURL); ++} ++ + void FirebirdDriver::disposing() + { + MutexGuard aGuard(m_aMutex); +@@ -199,7 +199,7 @@ + } + + rtl::Reference pCon = new Connection(); +- pCon->construct(url, info, getDatabaseDataDirectoryURL()); ++ pCon->construct(url, info, *this); + + m_xConnections.emplace_back(*pCon); + +diff --git a/connectivity/source/drivers/firebird/Driver.hxx b/connectivity/source/drivers/firebird/Driver.hxx +index 122fa1fc5f3d..14e9d04c3697 100644 +--- a/connectivity/source/drivers/firebird/Driver.hxx ++++ b/connectivity/source/drivers/firebird/Driver.hxx +@@ -28,6 +28,8 @@ + #include + #include + ++#include ++ + namespace connectivity::firebird + { + // The SQL dialect in use +@@ -50,6 +52,14 @@ + ::utl::TempFileNamed m_firebirdDataDirectory; + bool m_bConfined; + ++ // The names firebird may use for a database that lies outside its own directory, each ++ // mapped to that database's absolute path. The names are random, and only the databases ++ // the user picked in this session are in here. ++ std::map m_aExternalDatabaseNames; ++ ++ // Write m_aExternalDatabaseNames out as the databases.conf of the firebird directory. ++ void writeExternalDatabaseNames(); ++ + protected: + ::osl::Mutex m_aMutex; // mutex is need to control member access + OWeakRefArray m_xConnections; // vector containing a list +@@ -67,6 +77,17 @@ + // associated files it creates for them under this directory as well. + OUString getDatabaseDataDirectoryURL() const { return m_firebirdDataDirectory.GetURL(); } + ++ // Give firebird a name for a database that lies outside its own directory, and return ++ // that name. firebird resolves a name it finds in databases.conf without applying the ++ // DatabaseAccess restriction, while every path it is handed elsewhere, a difference file ++ // or a shadow, is still checked against that restriction. The name is random so that a ++ // database firebird opens cannot ask for another database by guessing the name. ++ OUString addExternalDatabaseName(const OUString& rDatabasePath); ++ ++ // Take back a name from addExternalDatabaseName. Any database already attached through ++ // it stays open. ++ void removeExternalDatabaseName(const OUString& rName); ++ + // OComponentHelper + virtual void SAL_CALL disposing() override; + diff -Nru libreoffice-25.2.3/debian/patches/firebird-module-path.diff libreoffice-25.2.3/debian/patches/firebird-module-path.diff --- libreoffice-25.2.3/debian/patches/firebird-module-path.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/firebird-module-path.diff 2026-10-03 10:46:08.000000000 +0000 @@ -0,0 +1,291 @@ +From e741778199ba90e964cccb636049ed3c14155281 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 28 Jul 2026 17:08:38 +0000 +Subject: [PATCH] firebird: name the modules of a system firebird by absolute + path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Debian patches firebird to resolve its plugins, intl and conf +directories under the FIREBIRD variable (instead of where it was built) +and we want point that variable at a private directory. But then the +modules aren't loaded and no database opens. + +So write a replacement plugins.conf that lists the absolute path of each +plugin module (and the intl conf files) with their macros expanded. + +each lib.so (otherwise found by default) with no entry names gets +an entry of its own. + +Change-Id: I2696d7197394b7fe9b7739732deadd2cb2e01acc +Signed-off-by: Caolán McNamara +Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/7989 +Tested-by: Jenkins CPCI +Reviewed-by: Michael Stahl +(cherry picked from commit b8407b18adf3c6d552d54d7b6657539e2769afd6) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208882 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +(cherry picked from commit 09dbbe16b04add973ab04fe5937c12478e52451c) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208893 +--- + config_host/config_firebird.h.in | 12 ++ + configure.ac | 14 ++ + .../source/drivers/firebird/Driver.cxx | 173 ++++++++++++++++++ + 3 files changed, 199 insertions(+) + +diff --git a/config_host/config_firebird.h.in b/config_host/config_firebird.h.in +index edfbb2df62b4..e1d7bcce6fc3 100644 +--- a/config_host/config_firebird.h.in ++++ b/config_host/config_firebird.h.in +@@ -7,4 +7,16 @@ Settings for Firebird + + #define ENABLE_FIREBIRD_SDBC 0 + ++/* The directory a system firebird has its plugin modules in, empty for a bundled firebird or when it ++ could not be determined. */ ++#define SYSTEM_FIREBIRD_PLUGINS_DIRECTORY "" ++ ++/* The directory a system firebird has its international modules in, empty for a bundled firebird or ++ when it could not be determined. */ ++#define SYSTEM_FIREBIRD_INTL_DIRECTORY "" ++ ++/* The directory a system firebird has its own configuration files in, empty for a bundled firebird ++ or when it could not be determined. */ ++#define SYSTEM_FIREBIRD_CONF_DIRECTORY "" ++ + #endif +diff --git a/configure.ac b/configure.ac +index 59c3deea2a01..a477ee76fa43 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -11280,6 +11280,12 @@ if test "$enable_firebird_sdbc" = "yes" ; then + FIREBIRD_LIBS=`$FIREBIRDCONFIG --embedlibs` + FilterLibs "${FIREBIRD_LIBS}" + FIREBIRD_LIBS="${filteredlibs}" ++ dnl The directories chosen when firebird was built. A firebird patched to resolve them ++ dnl under the FIREBIRD variable instead needs to be told where its plugin modules and ++ dnl its international modules are. ++ FIREBIRD_CONFDIR=`$FIREBIRDCONFIG --confdir` ++ FIREBIRD_PLUGINSDIR=`$FIREBIRDCONFIG --pluginsdir` ++ FIREBIRD_INTLDIR=`$FIREBIRDCONFIG --intldir` + fi + AC_MSG_RESULT([includes `$FIREBIRD_CFLAGS', libraries `$FIREBIRD_LIBS']) + AC_MSG_CHECKING([Firebird version]) +@@ -11301,6 +11307,14 @@ int fb_api_is_30(void) { return 0; } + #endif]])],AC_MSG_RESULT([OK]),AC_MSG_ERROR([Ensure firebird 3.0.x is installed])) + CFLAGS="$save_CFLAGS" + fi ++ if test -z "$FIREBIRD_PLUGINSDIR"; then ++ AC_MSG_WARN([Firebird plugins directory unknown, so a firebird that looks for its plugins ++ under the FIREBIRD variable cannot be told where they are, and will not open ++ a database. Install fb_config to get the directory.]) ++ fi ++ AC_DEFINE_UNQUOTED([SYSTEM_FIREBIRD_PLUGINS_DIRECTORY],["$FIREBIRD_PLUGINSDIR"]) ++ AC_DEFINE_UNQUOTED([SYSTEM_FIREBIRD_INTL_DIRECTORY],["$FIREBIRD_INTLDIR"]) ++ AC_DEFINE_UNQUOTED([SYSTEM_FIREBIRD_CONF_DIRECTORY],["$FIREBIRD_CONFDIR"]) + ENABLE_FIREBIRD_SDBC=TRUE + AC_DEFINE([ENABLE_FIREBIRD_SDBC],1) + elif test "$enable_database_connectivity" = no; then +diff --git a/connectivity/source/drivers/firebird/Driver.cxx b/connectivity/source/drivers/firebird/Driver.cxx +index 134a2ccb3eac..e8b6a1cd2ae2 100644 +--- a/connectivity/source/drivers/firebird/Driver.cxx ++++ b/connectivity/source/drivers/firebird/Driver.cxx +@@ -82,6 +82,9 @@ constexpr OUString our_sFirebirdLibVar = u"LIBREOFFICE_FIREBIRD_LIB"_ustr; + // whenever it has changed. + constexpr OUString our_sDatabasesConfName = u"databases.conf"_ustr; + ++// The file that gives a plugin the module to load it from. ++constexpr OUString our_sPluginsConfName = u"plugins.conf"_ustr; ++ + // Put rContent in the file at rURL, discarding whatever was there before. + bool writeFile(const OUString& rURL, std::string_view aContent) + { +@@ -109,6 +112,173 @@ bool writeFile(const OUString& rURL, std::string_view aContent) + return bWholeContentWritten; + } + ++// The whole content of the file at rURL, empty when it cannot be read. ++OString readFile(const OUString& rURL) ++{ ++ ::osl::File aFile(rURL); ++ if (aFile.open(osl_File_OpenFlag_Read) != ::osl::FileBase::E_None) ++ return OString(); ++ ++ OStringBuffer aContent; ++ for (;;) ++ { ++ char aBuffer[4096]; ++ sal_uInt64 nRead = 0; ++ if (aFile.read(aBuffer, sizeof(aBuffer), nRead) != ::osl::FileBase::E_None || nRead == 0) ++ break; ++ aContent.append(std::string_view(aBuffer, nRead)); ++ } ++ aFile.close(); ++ return aContent.makeStringAndClear(); ++} ++ ++// The directories of the firebird installation, empty for a bundled firebird, which resolves them ++// where it was built. ++constexpr OUString our_sSystemPluginsPath = u"" SYSTEM_FIREBIRD_PLUGINS_DIRECTORY ""_ustr; ++constexpr OUString our_sSystemIntlPath = u"" SYSTEM_FIREBIRD_INTL_DIRECTORY ""_ustr; ++constexpr OUString our_sSystemConfPath = u"" SYSTEM_FIREBIRD_CONF_DIRECTORY ""_ustr; ++ ++OString toBytes(std::u16string_view rPath) ++{ ++ return OUStringToOString(rPath, osl_getThreadTextEncoding()); ++} ++ ++// Put the directories of the installation in place of the macros that name them. rThisPath is the ++// directory the file was read from, which is what the this macro means. plugins and intl under the ++// root are the plugins and international module directories. ++OString expandFirebirdDirectoryMacros(const OString& rContent, const OString& rThisPath) ++{ ++ const OString sPlugins = toBytes(our_sSystemPluginsPath); ++ const OString sIntl = toBytes(our_sSystemIntlPath); ++ ++ OString sExpanded = rContent.replaceAll("$(this)"_ostr, rThisPath); ++ sExpanded = sExpanded.replaceAll("$(dir_plugins)"_ostr, sPlugins); ++ sExpanded = sExpanded.replaceAll("$(root)/plugins"_ostr, sPlugins); ++ sExpanded = sExpanded.replaceAll("$(dir_intl)"_ostr, sIntl); ++ sExpanded = sExpanded.replaceAll("$(root)/intl"_ostr, sIntl); ++ sExpanded = sExpanded.replaceAll("$(dir_conf)"_ostr, toBytes(our_sSystemConfPath)); ++ return sExpanded; ++} ++ ++// The file at rSourceURL with the macros expanded, empty when one is left that we have no directory ++// for. A leftover macro leaves a relative path, resolved under the root we are writing for. ++OString getExpandedConf(const OUString& rSourceURL, const OUString& rSourcePath) ++{ ++ const OString sContent ++ = expandFirebirdDirectoryMacros(readFile(rSourceURL), toBytes(rSourcePath)); ++ if (sContent.indexOf("$(") == -1) ++ return sContent; ++ ++ SAL_WARN("connectivity.firebird", "unexpanded macro in " << rSourcePath); ++ return OString(); ++} ++ ++// Write a plugins.conf into the directory the FIREBIRD variable names, giving every plugin of the ++// installation the absolute path of its module. A plugin no entry names is looked for by its own ++// name in the plugins directory firebird resolves, which Debian patches to sit under that variable. ++void writeSystemFirebirdPluginsConf(std::u16string_view rDataDirURL) ++{ ++ if (our_sSystemPluginsPath.isEmpty()) ++ return; ++ ++ OUString sPluginsURL; ++ if (::osl::FileBase::getFileURLFromSystemPath(our_sSystemPluginsPath, sPluginsURL) ++ != ::osl::FileBase::E_None) ++ return; ++ ++ // The installation's own file names the plugins that need more than their module. ++ OString sSystemConf; ++ OUString sConfURL; ++ if (!our_sSystemConfPath.isEmpty() ++ && ::osl::FileBase::getFileURLFromSystemPath(our_sSystemConfPath, sConfURL) ++ == ::osl::FileBase::E_None) ++ { ++ sSystemConf = getExpandedConf(sConfURL + "/" + our_sPluginsConfName, our_sSystemConfPath); ++ } ++ ++ ::osl::Directory aPluginsDirectory(sPluginsURL); ++ if (aPluginsDirectory.open() != ::osl::FileBase::E_None) ++ { ++ SAL_WARN("connectivity.firebird", "could not read " << our_sSystemPluginsPath); ++ return; ++ } ++ ++ const OString sPluginsPath = toBytes(our_sSystemPluginsPath); ++ OStringBuffer aContent(sSystemConf); ++ ::osl::DirectoryItem aItem; ++ while (aPluginsDirectory.getNextItem(aItem) == ::osl::FileBase::E_None) ++ { ++ ::osl::FileStatus aStatus(osl_FileStatus_Mask_FileName); ++ if (aItem.getFileStatus(aStatus) != ::osl::FileBase::E_None) ++ continue; ++ ++ // The module libEngine13.so holds the plugin Engine13. ++ const OUString sName = aStatus.getFileName(); ++ if (!sName.startsWith("lib") || !sName.endsWith(".so") || sName.getLength() <= 6) ++ continue; ++ const OString sPlugin = toBytes(sName.subView(3, sName.getLength() - 6)); ++ ++ if (sSystemConf.indexOf(Concat2View("= " + sPlugin + " ")) != -1) ++ continue; ++ ++ aContent.append("\nPlugin = " + sPlugin + " {\n Module = " + sPluginsPath + "/" + sPlugin ++ + "\n}\n"); ++ } ++ ++ const OUString sURL = OUString::Concat(rDataDirURL) + "/" + our_sPluginsConfName; ++ const OString sContent = aContent.makeStringAndClear(); ++ SAL_WARN_IF(!writeFile(sURL, std::string_view(sContent)), "connectivity.firebird", ++ "could not write " << sURL); ++} ++ ++// Copy the conf files of the international modules into an intl subdirectory of the directory the ++// FIREBIRD variable names, with the absolute path of each module in place of the macros. Without ++// them only the character sets and collations built into the engine work. ++void writeSystemFirebirdIntlConfs(std::u16string_view rDataDirURL) ++{ ++ if (our_sSystemIntlPath.isEmpty()) ++ return; ++ ++ OUString sIntlURL; ++ if (::osl::FileBase::getFileURLFromSystemPath(our_sSystemIntlPath, sIntlURL) ++ != ::osl::FileBase::E_None) ++ return; ++ ++ ::osl::Directory aIntlDirectory(sIntlURL); ++ if (aIntlDirectory.open() != ::osl::FileBase::E_None) ++ { ++ SAL_WARN("connectivity.firebird", "could not read " << our_sSystemIntlPath); ++ return; ++ } ++ ++ const OUString sTargetURL = OUString::Concat(rDataDirURL) + "/intl"; ++ if (::osl::Directory::create(sTargetURL) != ::osl::FileBase::E_None) ++ { ++ SAL_WARN("connectivity.firebird", "could not create " << sTargetURL); ++ return; ++ } ++ ++ ::osl::DirectoryItem aItem; ++ while (aIntlDirectory.getNextItem(aItem) == ::osl::FileBase::E_None) ++ { ++ ::osl::FileStatus aStatus(osl_FileStatus_Mask_FileName); ++ if (aItem.getFileStatus(aStatus) != ::osl::FileBase::E_None) ++ continue; ++ ++ const OUString sName = aStatus.getFileName(); ++ if (!sName.endsWith(".conf")) ++ continue; ++ ++ const OString sContent = getExpandedConf(sIntlURL + "/" + sName, our_sSystemIntlPath); ++ if (sContent.isEmpty()) ++ continue; ++ ++ const OUString sURL = sTargetURL + "/" + sName; ++ SAL_WARN_IF(!writeFile(sURL, std::string_view(sContent)), "connectivity.firebird", ++ "could not write " << sURL); ++ } ++} ++ + // firebird takes its root directory from the FIREBIRD variable on its first use, and reads the + // firebird.conf that confines it to that directory only from there. Ask firebird which directory + // it settled on and treat anything but our own as unconfined. +@@ -168,6 +338,9 @@ FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentCo + OUString sDataDirPath; + ::osl::FileBase::getSystemPathFromFileURL(m_firebirdDataDirectory.GetURL(), sDataDirPath); + ++ writeSystemFirebirdPluginsConf(m_firebirdDataDirectory.GetURL()); ++ writeSystemFirebirdIntlConfs(m_firebirdDataDirectory.GetURL()); ++ + #if defined(_WIN32) + // firebird upper-cases the database path before the exact-match + // DatabaseAccess check, so match that here. +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/series libreoffice-25.2.3/debian/patches/series --- libreoffice-25.2.3/debian/patches/series 2026-07-21 16:41:22.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/series 2026-10-03 10:46:08.000000000 +0000 @@ -70,3 +70,23 @@ CVE-2026-63276.diff CVE-2026-63278.diff CVE-2026-63279.diff +CVE-2026-63277.diff +do-not-load-exotic-protocols-for-document-supplied-data.diff # first part of CVE-2026-63267/CVE-2026-63268, too +CVE-2026-63269-1.diff +CVE-2026-63269-2.diff +CVE-2026-63269-3.diff +# prereq for CVE-2026-63267 +Show-infobar-for-calc-graphics-with-remote-content-too.diff +CVE-2026-63267-1.diff +CVE-2026-63267-2.diff +CVE-2026-63268-1.diff +CVE-2026-63268-2.diff # also contains a part of CVE-2026-63266 +# order as in the commits to help applying +CVE-2026-63266-2.diff +CVE-2026-63266-4.diff +CVE-2026-63266-1.diff +CVE-2026-63266-3.diff +firebird-db-connection.diff # regression after CVE-2026-63266, also prereq of the following +firebird-module-path.diff +firebird-call-writeFile-outside-the-SAL_WARN_IF-cond.patch + diff -Nru libreoffice-25.2.3/debian/source/include-binaries libreoffice-25.2.3/debian/source/include-binaries --- libreoffice-25.2.3/debian/source/include-binaries 2026-03-19 20:19:56.000000000 +0000 +++ libreoffice-25.2.3/debian/source/include-binaries 2026-10-03 10:46:08.000000000 +0000 @@ -6,3 +6,5 @@ tarballs/dtoa-20180411.tgz tarballs/Java-WebSocket-1.6.0.tar.gz tarballs/26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz +dbaccess/qa/unit/data/firebird_integer_ods12.odb +dbaccess/qa/unit/data/tdf132924.odb