[PATCH] Fix check for further exotic protocols
authorStephan Bergmann <stephan.bergmann@allotropia.de>
Sat, 7 Dec 2024 16:36:22 +0000 (17:36 +0100)
committerDaniel Leidert <dleidert@debian.org>
Sat, 31 May 2025 03:25:27 +0000 (05:25 +0200)
...that were added in 59891cd3985469bc44dbd05c9fc704eeb07f0c78 "look at
'embedded' protocols for protocols that support them"

Change-Id: I42836d6fd27cd99e39ab07e626053f002a2651f5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178047
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
(cherry picked from commit 8075798b22f2188530f57b8747589923bfd419ef)

origin: https://github.com/LibreOffice/core/commit/eab0da77dfb4a54d14968eb72532e045bfffa0fb

Gbp-Pq: Name CVE-2024-12426_4.patch

tools/qa/cppunit/test_urlobj.cxx
tools/source/fsys/urlobj.cxx

index 0e25decab713b9bfdde2ee7dbdc5a0d62ddfb918..7061f1ee78cac64f6b07076a8e3a539b62b6523c 100644 (file)
@@ -294,6 +294,49 @@ namespace tools_urlobj
                 obj.GetMainURL(INetURLObject::DecodeMechanism::NONE));
         }
 
+        void testIsExoticProtocol() {
+            {
+                INetURLObject url(u"vnd.sun.star.pkg://slot%3A0");
+                CPPUNIT_ASSERT_EQUAL(INetProtocol::VndSunStarPkg, url.GetProtocol());
+                CPPUNIT_ASSERT(url.IsExoticProtocol());
+            }
+            {
+                INetURLObject url(u"vnd.sun.star.pkg://vnd.sun.star.pkg%3A%2F%2Fslot%253A0");
+                CPPUNIT_ASSERT_EQUAL(INetProtocol::VndSunStarPkg, url.GetProtocol());
+                CPPUNIT_ASSERT(url.IsExoticProtocol());
+            }
+            {
+                INetURLObject url(u"vnd.sun.star.pkg://http%3A%2F%2Fexample.net");
+                CPPUNIT_ASSERT_EQUAL(INetProtocol::VndSunStarPkg, url.GetProtocol());
+                CPPUNIT_ASSERT(!url.IsExoticProtocol());
+            }
+            {
+                INetURLObject url(u"vnd.sun.star.zip://slot%3A0");
+                CPPUNIT_ASSERT_EQUAL(INetProtocol::Generic, url.GetProtocol());
+                CPPUNIT_ASSERT(url.IsExoticProtocol());
+            }
+            {
+                INetURLObject url(u"vnd.sun.star.zip://slot%3A0/foo");
+                CPPUNIT_ASSERT_EQUAL(INetProtocol::Generic, url.GetProtocol());
+                CPPUNIT_ASSERT(url.IsExoticProtocol());
+            }
+            {
+                INetURLObject url(u"vnd.sun.star.zip://slot%3A0?foo");
+                CPPUNIT_ASSERT_EQUAL(INetProtocol::Generic, url.GetProtocol());
+                CPPUNIT_ASSERT(url.IsExoticProtocol());
+            }
+            {
+                INetURLObject url(u"vnd.sun.star.zip://slot%3A0#foo");
+                CPPUNIT_ASSERT_EQUAL(INetProtocol::Generic, url.GetProtocol());
+                CPPUNIT_ASSERT(url.IsExoticProtocol());
+            }
+            {
+                INetURLObject url(u"vnd.sun.star.zip://http%3A%2F%2Fexample.net");
+                CPPUNIT_ASSERT_EQUAL(INetProtocol::Generic, url.GetProtocol());
+                CPPUNIT_ASSERT(!url.IsExoticProtocol());
+            }
+        }
+
         // Change the following lines only, if you add, remove or rename
         // member functions of the current class,
         // because these macros are need by auto register mechanism.
@@ -308,6 +351,7 @@ namespace tools_urlobj
         CPPUNIT_TEST( urlobjTest_isAnyKnownWebDAVScheme );
         CPPUNIT_TEST( testSetName );
         CPPUNIT_TEST( testSetExtension );
+        CPPUNIT_TEST( testIsExoticProtocol );
         CPPUNIT_TEST_SUITE_END(  );
     };                          // class createPool
 
index ef2345c292319de40183afb10215c283a81814ad..c081bc7cc165828f28ac14fac08c15647689286b 100644 (file)
@@ -4771,10 +4771,21 @@ bool INetURLObject::IsExoticProtocol() const
     {
         return true;
     }
-    if (isSchemeEqualTo(u"vnd.sun.star.pkg") || isSchemeEqualTo(u"vnd.sun.star.zip"))
+    if (m_eScheme == INetProtocol::VndSunStarPkg) {
+        return INetURLObject(GetHost(INetURLObject::DecodeMechanism::WithCharset))
+            .IsExoticProtocol();
+    }
+    if (isSchemeEqualTo(u"vnd.sun.star.zip"))
     {
-        OUString sPayloadURL = GetURLPath(INetURLObject::DecodeMechanism::WithCharset);
-        return sPayloadURL.startsWith(u"//") && INetURLObject(sPayloadURL.subView(2)).IsExoticProtocol();
+        OUString sPayloadURL = GetURLPath(INetURLObject::DecodeMechanism::NONE);
+        if (!sPayloadURL.startsWith(u"//")) {
+            return false;
+        }
+        auto const find = [&sPayloadURL](auto c) {
+            auto const n = sPayloadURL.indexOf(c, 2);
+            return n == -1 ? sPayloadURL.getLength() : n;
+        };
+        return INetURLObject(decode(sPayloadURL.copy(2, std::min(find('/'), find('?')) - 2), INetURLObject::DecodeMechanism::WithCharset)).IsExoticProtocol();
     }
     return false;
 }