diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2023-11-01 00:37:19 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2023-11-01 10:24:21 +0100 |
commit | 9f1289f1e3c9b4a5f2be7a7187877db6b5015973 (patch) | |
tree | 4e042a908529f291db9321d1849de83b82d548bc /tools | |
parent | d8326f1f54b2f4644b52fbfa7106eeeae6e5bb7b (diff) |
tdf#157820: handle \\?\ prefixes in INetURLObject
They are already handled in osl file URL functions.
Change-Id: Id0c224bdb79963e7ce52abde57bf05b0a6a81ff5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158741
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qa/cppunit/test_urlobj.cxx | 20 | ||||
-rw-r--r-- | tools/source/fsys/urlobj.cxx | 94 |
2 files changed, 97 insertions, 17 deletions
diff --git a/tools/qa/cppunit/test_urlobj.cxx b/tools/qa/cppunit/test_urlobj.cxx index 2c8ae1a36a25..fff77e41f5e7 100644 --- a/tools/qa/cppunit/test_urlobj.cxx +++ b/tools/qa/cppunit/test_urlobj.cxx @@ -332,6 +332,26 @@ namespace tools_urlobj CPPUNIT_ASSERT_EQUAL(OUString(""), obj.GetHost()); CPPUNIT_ASSERT_EQUAL(OUString("80a0/foo"), obj.GetURLPath()); } + { + // Test Windows \\?\C:... long path scheme + INetURLObject base(u"file:///C:/foo"); // set up base path + bool bWasAbsolute = false; + INetURLObject obj + = base.smartRel2Abs(u"\\\\?\\D:\\bar\\baz.ext"_ustr, bWasAbsolute); + CPPUNIT_ASSERT(bWasAbsolute); + CPPUNIT_ASSERT_EQUAL(u"file:///D:/bar/baz.ext"_ustr, + obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + } + { + // Test Windows \\?\UNC\Server... long path scheme + INetURLObject base(u"file://ServerFoo/fooShare"); // set up base path + bool bWasAbsolute = false; + INetURLObject obj = base.smartRel2Abs( + u"\\\\?\\UNC\\ServerBar\\barShare\\baz.ext"_ustr, bWasAbsolute); + CPPUNIT_ASSERT(bWasAbsolute); + CPPUNIT_ASSERT_EQUAL(u"file://ServerBar/barShare/baz.ext"_ustr, + obj.GetMainURL(INetURLObject::DecodeMechanism::NONE)); + } } // Change the following lines only, if you add, remove or rename diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx index 3c54eea3d664..a97af83bad81 100644 --- a/tools/source/fsys/urlobj.cxx +++ b/tools/source/fsys/urlobj.cxx @@ -809,6 +809,17 @@ bool INetURLObject::setAbsURIRef(std::u16string_view rTheAbsURIRef, eMechanism = EncodeMechanism::All; nFragmentDelimiter = 0x80000000; } + else if (eStyle & FSysStyle::Dos + && pEnd - p1 >= 6 + && p1[0] == '\\' && p1[1] == '\\' && p1[2] == '?' && p1[3] == '\\' + && rtl::isAsciiAlpha(p1[4]) + && p1[5] == ':' + && (pEnd - p1 == 6 || p1[6] == '/' || p1[6] == '\\')) + { + m_eScheme = INetProtocol::File; // 8th, 9th + eMechanism = EncodeMechanism::All; + nFragmentDelimiter = 0x80000000; + } else if (pEnd - p1 >= 2 && p1[0] == '/' && p1[1] == '/') { p1 += 2; @@ -828,6 +839,14 @@ bool INetURLObject::setAbsURIRef(std::u16string_view rTheAbsURIRef, && p1[1] == '\\') { p1 += 2; + if (pEnd - p1 >= 6 && p1[0] == '?' && p1[1] == '\\' && p1[5] == '\\' + && rtl::toAsciiLowerCase(p1[2]) == 'u' + && rtl::toAsciiLowerCase(p1[3]) == 'n' + && rtl::toAsciiLowerCase(p1[4]) == 'c') + { + p1 += 6; // "\\?\UNC\Servername\..." + } + sal_Int32 n = rtl_ustr_indexOfChar_WithLength( p1, pEnd - p1, '\\'); sal_Unicode const * pe = n == -1 ? pEnd : p1 + n; @@ -1161,6 +1180,16 @@ bool INetURLObject::setAbsURIRef(std::u16string_view rTheAbsURIRef, && pPos[1] == '\\') { sal_Unicode const * p1 = pPos + 2; + sal_Unicode const * pHostPortTentativeBegin = p1; + if (pEnd - p1 >= 6 && p1[0] == '?' && p1[1] == '\\' && p1[5] == '\\' + && rtl::toAsciiLowerCase(p1[2]) == 'u' + && rtl::toAsciiLowerCase(p1[3]) == 'n' + && rtl::toAsciiLowerCase(p1[4]) == 'c') + { + p1 += 6; // "\\?\UNC\Servername\..." + pHostPortTentativeBegin = p1; + } + sal_Unicode const * pe = p1; while (pe < pEnd && *pe != '\\' && *pe != nFragmentDelimiter) @@ -1175,7 +1204,7 @@ bool INetURLObject::setAbsURIRef(std::u16string_view rTheAbsURIRef, ) { m_aAbsURIRef.append("//"); - pHostPortBegin = pPos + 2; + pHostPortBegin = pHostPortTentativeBegin; pHostPortEnd = pe; pPos = pe; nSegmentDelimiter = '\\'; @@ -1193,18 +1222,26 @@ bool INetURLObject::setAbsURIRef(std::u16string_view rTheAbsURIRef, // becomes // "file:///" ALPHA ":" ["/" *path] ["#" *UCS4] // replacing "\" by "/" within <*path> - if (eStyle & FSysStyle::Dos - && pEnd - pPos >= 2 - && rtl::isAsciiAlpha(pPos[0]) - && pPos[1] == ':' - && (pEnd - pPos == 2 - || pPos[2] == '/' - || pPos[2] == '\\')) + if (eStyle & FSysStyle::Dos) { - m_aAbsURIRef.append("//"); - nAltSegmentDelimiter = '\\'; - bSkippedInitialSlash = true; - break; + sal_Unicode const* p1 = pPos; + if (pEnd - p1 >= 4 && p1[0] == '\\' && p1[1] == '\\' && p1[2] == '?' + && p1[3] == '\\') + p1 += 4; // "\\?\c:\..." + + if (pEnd - p1 >= 2 + && rtl::isAsciiAlpha(p1[0]) + && p1[1] == ':' + && (pEnd - p1 == 2 + || p1[2] == '/' + || p1[2] == '\\')) + { + pPos = p1; + m_aAbsURIRef.append("//"); + nAltSegmentDelimiter = '\\'; + bSkippedInitialSlash = true; + break; + } } // 9th Production (any): @@ -1581,12 +1618,35 @@ bool INetURLObject::convertRelToAbs(OUString const & rTheRelURIRef, q += 2; sal_Int32 n = rtl_ustr_indexOfChar_WithLength( q, pEnd - q, '\\'); - sal_Unicode const * qe = n == -1 ? pEnd : q + n; - if (parseHostOrNetBiosName( - q, qe, EncodeMechanism::All, RTL_TEXTENCODING_DONTKNOW, - true, nullptr)) + if (n == 1 && q[0] == '?') { - bFSys = true; // 1st + // "\\?\c:\..." or "\\?\UNC\servername\..." + q += 2; + if (pEnd - q >= 2 + && rtl::isAsciiAlpha(q[0]) + && q[1] == ':' + && (pEnd - q == 2 || q[2] == '/' || q[2] == '\\')) + { + bFSys = true; // 2nd, 3rd + } + else if (pEnd - q >= 4 + && q[3] == '\\' + && rtl::toAsciiLowerCase(q[0]) == 'u' + && rtl::toAsciiLowerCase(q[1]) == 'n' + && rtl::toAsciiLowerCase(q[2]) == 'c') + { + q += 4; // Check if it's 1st below + } + } + if (!bFSys) + { + sal_Unicode const * qe = n == -1 ? pEnd : q + n; + if (parseHostOrNetBiosName( + q, qe, EncodeMechanism::All, RTL_TEXTENCODING_DONTKNOW, + true, nullptr)) + { + bFSys = true; // 1st + } } } if (bFSys) |