diff options
Diffstat (limited to 'tools/source/fsys/urlobj.cxx')
-rw-r--r-- | tools/source/fsys/urlobj.cxx | 526 |
1 files changed, 295 insertions, 231 deletions
diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx index 8c3d2845eab2..b1e3073f39b4 100644 --- a/tools/source/fsys/urlobj.cxx +++ b/tools/source/fsys/urlobj.cxx @@ -45,6 +45,7 @@ #include <com/sun/star/uno/Sequence.hxx> #include <comphelper/base64.hxx> +#include <comphelper/string.hxx> using namespace css; @@ -291,7 +292,7 @@ int INetURLObject::SubString::compare(SubString const & rOther, struct INetURLObject::SchemeInfo { - rtl::OUStringConstExpr m_sScheme; + OUString m_sScheme; char const * m_pPrefix; bool m_bAuthority; bool m_bUser; @@ -317,36 +318,37 @@ struct INetURLObject::PrefixInfo inline INetURLObject::SchemeInfo const & INetURLObject::getSchemeInfo(INetProtocol eTheScheme) { - static constexpr OUStringLiteral EMPTY = u""; - static constexpr OUStringLiteral FTP = u"ftp"; - static constexpr OUStringLiteral HTTP = u"http"; - static constexpr OUStringLiteral FILE1 = u"file"; // because FILE is already defined - static constexpr OUStringLiteral MAILTO = u"mailto"; - static constexpr OUStringLiteral VND_WEBDAV = u"vnd.sun.star.webdav"; - static constexpr OUStringLiteral PRIVATE = u"private"; - static constexpr OUStringLiteral VND_HELP = u"vnd.sun.star.help"; - static constexpr OUStringLiteral HTTPS = u"https"; - static constexpr OUStringLiteral SLOT = u"slot"; - static constexpr OUStringLiteral MACRO = u"macro"; - static constexpr OUStringLiteral JAVASCRIPT = u"javascript"; - static constexpr OUStringLiteral DATA = u"data"; - static constexpr OUStringLiteral CID = u"cid"; - static constexpr OUStringLiteral VND_HIER = u"vnd.sun.star.hier"; - static constexpr OUStringLiteral UNO = u".uno"; - static constexpr OUStringLiteral COMPONENT = u".component"; - static constexpr OUStringLiteral VND_PKG = u"vnd.sun.star.pkg"; - static constexpr OUStringLiteral LDAP = u"ldap"; - static constexpr OUStringLiteral DB = u"db"; - static constexpr OUStringLiteral VND_CMD = u"vnd.sun.star.cmd"; - static constexpr OUStringLiteral TELNET = u"telnet"; - static constexpr OUStringLiteral VND_EXPAND = u"vnd.sun.star.expand"; - static constexpr OUStringLiteral VND_TDOC = u"vnd.sun.star.tdoc"; - static constexpr OUStringLiteral SMB = u"smb"; - static constexpr OUStringLiteral HID = u"hid"; - static constexpr OUStringLiteral SFTP = u"sftp"; - static constexpr OUStringLiteral VND_CMIS = u"vnd.libreoffice.cmis"; - - static o3tl::enumarray<INetProtocol, SchemeInfo> const map = { + static constexpr OUString EMPTY = u""_ustr; + static constexpr OUString FTP = u"ftp"_ustr; + static constexpr OUString HTTP = u"http"_ustr; + static constexpr OUString FILE1 = u"file"_ustr; // because FILE is already defined + static constexpr OUString MAILTO = u"mailto"_ustr; + static constexpr OUString VND_WEBDAV = u"vnd.sun.star.webdav"_ustr; + static constexpr OUString PRIVATE = u"private"_ustr; + static constexpr OUString VND_HELP = u"vnd.sun.star.help"_ustr; + static constexpr OUString HTTPS = u"https"_ustr; + static constexpr OUString SLOT = u"slot"_ustr; + static constexpr OUString MACRO = u"macro"_ustr; + static constexpr OUString JAVASCRIPT = u"javascript"_ustr; + static constexpr OUString DATA = u"data"_ustr; + static constexpr OUString CID = u"cid"_ustr; + static constexpr OUString VND_HIER = u"vnd.sun.star.hier"_ustr; + static constexpr OUString UNO = u".uno"_ustr; + static constexpr OUString COMPONENT = u".component"_ustr; + static constexpr OUString VND_PKG = u"vnd.sun.star.pkg"_ustr; + static constexpr OUString LDAP = u"ldap"_ustr; + static constexpr OUString DB = u"db"_ustr; + static constexpr OUString VND_CMD = u"vnd.sun.star.cmd"_ustr; + static constexpr OUString TELNET = u"telnet"_ustr; + static constexpr OUString VND_EXPAND = u"vnd.sun.star.expand"_ustr; + static constexpr OUString VND_TDOC = u"vnd.sun.star.tdoc"_ustr; + static constexpr OUString SMB = u"smb"_ustr; + static constexpr OUString HID = u"hid"_ustr; + static constexpr OUString SFTP = u"sftp"_ustr; + static constexpr OUString VND_CMIS = u"vnd.libreoffice.cmis"_ustr; + + static o3tl::enumarray<INetProtocol, SchemeInfo> constexpr map = { + // [-loplugin:redundantfcast]: SchemeInfo{ EMPTY, "", false, false, false, false, false, false, false, false}, SchemeInfo{ @@ -616,6 +618,7 @@ std::unique_ptr<SvMemoryStream> memoryStream( std::unique_ptr<SvMemoryStream> s( new SvMemoryStream(b.get(), length, StreamMode::READ)); s->ObjectOwnsMemory(true); + // coverity[leaked_storage : FALSE] - belongs to SvMemoryStream s at this point b.release(); return s; } @@ -646,10 +649,10 @@ std::unique_ptr<SvMemoryStream> INetURLObject::getData() const else if (sURLPath.matchIgnoreAsciiCase(";base64,", nCharactersSkipped)) { nCharactersSkipped += strlen(";base64,"); - OUString sBase64Data = sURLPath.copy( nCharactersSkipped ); + std::u16string_view sBase64Data = sURLPath.subView( nCharactersSkipped ); css::uno::Sequence< sal_Int8 > aDecodedData; if (comphelper::Base64::decodeSomeChars(aDecodedData, sBase64Data) - == sBase64Data.getLength()) + == sBase64Data.size()) { return memoryStream( aDecodedData.getArray(), aDecodedData.getLength()); @@ -719,14 +722,14 @@ OUString parseScheme( } -bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, +bool INetURLObject::setAbsURIRef(std::u16string_view rTheAbsURIRef, EncodeMechanism eMechanism, rtl_TextEncoding eCharset, bool bSmart, FSysStyle eStyle) { - sal_Unicode const * pPos = rTheAbsURIRef.getStr(); - sal_Unicode const * pEnd = pPos + rTheAbsURIRef.getLength(); + sal_Unicode const * pPos = rTheAbsURIRef.data(); + sal_Unicode const * pEnd = pPos + rTheAbsURIRef.size(); setInvalid(); @@ -806,6 +809,17 @@ bool INetURLObject::setAbsURIRef(OUString const & 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; @@ -825,6 +839,14 @@ bool INetURLObject::setAbsURIRef(OUString const & 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; @@ -869,8 +891,34 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, aSynScheme = parseScheme(&p1, pEnd, nFragmentDelimiter); if (!aSynScheme.isEmpty()) { - m_eScheme = INetProtocol::Generic; - pPos = p1; + if (bSmart && m_eSmartScheme != m_eScheme && p1 != pEnd && rtl::isAsciiDigit(*p1)) + { + // rTheAbsURIRef doesn't define a known scheme (handled by the "if (pPrefix)" + // branch above); but a known scheme is defined in m_eSmartScheme. If this + // scheme may have a port in authority component, then avoid misinterpreting + // URLs like www.foo.bar:123/baz as using unknown "www.foo.bar" scheme with + // 123/baz rootless path. For now, do not try to handle possible colons in + // user information, require such ambiguous URLs to have explicit scheme part. + // Also ignore possibility of empty port. + const SchemeInfo& rInfo = getSchemeInfo(m_eSmartScheme); + if (rInfo.m_bAuthority && rInfo.m_bPort) + { + // Make sure that all characters from colon to [/?#] or to EOL are digits. + // Or maybe make it simple, and just assume that "xyz:1..." is more likely + // to be host "xyz" and port "1...", than scheme "xyz" and path "1..."? + sal_Unicode const* p2 = p1 + 1; + while (p2 != pEnd && rtl::isAsciiDigit(*p2)) + ++p2; + if (p2 == pEnd || *p2 == '/' || *p2 == '?' || *p2 == '#') + m_eScheme = m_eSmartScheme; + } + } + + if (m_eScheme == INetProtocol::NotValid) + { + m_eScheme = INetProtocol::Generic; + pPos = p1; + } } } @@ -887,7 +935,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, } if (m_eScheme != INetProtocol::Generic) { - aSynScheme = static_cast<const OUString&>(getSchemeInfo().m_sScheme); + aSynScheme = getSchemeInfo().m_sScheme; } m_aScheme.set(m_aAbsURIRef, aSynScheme, m_aAbsURIRef.getLength()); m_aAbsURIRef.append(':'); @@ -930,7 +978,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, PART_AUTHORITY, eCharset, false); } m_aHost.set(m_aAbsURIRef, - aSynAuthority.makeStringAndClear(), + aSynAuthority, m_aAbsURIRef.getLength()); // misusing m_aHost to store the authority break; @@ -966,7 +1014,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, return false; } m_aHost.set(m_aAbsURIRef, - aSynAuthority.makeStringAndClear(), + aSynAuthority, m_aAbsURIRef.getLength()); // misusing m_aHost to store the authority } @@ -1007,7 +1055,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, else { m_aUser.set(m_aAbsURIRef, - aSynUser.makeStringAndClear(), + aSynUser, m_aAbsURIRef.getLength()); m_aAbsURIRef.append("@"); ++pPos; @@ -1030,7 +1078,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, return false; } m_aHost.set(m_aAbsURIRef, - aSynAuthority.makeStringAndClear(), + aSynAuthority, m_aAbsURIRef.getLength()); // misusing m_aHost to store the authority break; @@ -1132,6 +1180,16 @@ bool INetURLObject::setAbsURIRef(OUString const & 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) @@ -1146,7 +1204,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, ) { m_aAbsURIRef.append("//"); - pHostPortBegin = pPos + 2; + pHostPortBegin = pHostPortTentativeBegin; pHostPortEnd = pe; pPos = pe; nSegmentDelimiter = '\\'; @@ -1164,18 +1222,26 @@ bool INetURLObject::setAbsURIRef(OUString const & 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): @@ -1314,8 +1380,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, appendUCS4(aSynUser, nUTF32, eEscapeType, ePart, eCharset, false); } - m_aUser.set(m_aAbsURIRef, aSynUser.makeStringAndClear(), - m_aAbsURIRef.getLength()); + m_aUser.set(m_aAbsURIRef, aSynUser, m_aAbsURIRef.getLength()); if (bHasAuth) { if (bSupportsPassword) @@ -1331,8 +1396,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, appendUCS4(aSynAuth, nUTF32, eEscapeType, ePart, eCharset, false); } - m_aAuth.set(m_aAbsURIRef, aSynAuth.makeStringAndClear(), - m_aAbsURIRef.getLength()); + m_aAuth.set(m_aAbsURIRef, aSynAuth, m_aAbsURIRef.getLength()); } else { @@ -1352,8 +1416,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, appendUCS4(aSynAuth, nUTF32, eEscapeType, ePart, eCharset, false); } - m_aAuth.set(m_aAbsURIRef, aSynAuth.makeStringAndClear(), - m_aAbsURIRef.getLength()); + m_aAuth.set(m_aAbsURIRef, aSynAuth, m_aAbsURIRef.getLength()); } } if (pHostPortBegin) @@ -1444,8 +1507,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, appendUCS4(aSynQuery, nUTF32, eEscapeType, PART_URIC, eCharset, true); } - m_aQuery.set(m_aAbsURIRef, aSynQuery.makeStringAndClear(), - m_aAbsURIRef.getLength()); + m_aQuery.set(m_aAbsURIRef, aSynQuery, m_aAbsURIRef.getLength()); } // Parse #<fragment> @@ -1461,8 +1523,7 @@ bool INetURLObject::setAbsURIRef(OUString const & rTheAbsURIRef, appendUCS4(aSynFragment, nUTF32, eEscapeType, PART_URIC, eCharset, true); } - m_aFragment.set(m_aAbsURIRef, aSynFragment.makeStringAndClear(), - m_aAbsURIRef.getLength()); + m_aFragment.set(m_aAbsURIRef, aSynFragment, m_aAbsURIRef.getLength()); } if (pPos != pEnd) @@ -1557,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] == '?') + { + // "\\?\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) { - bFSys = true; // 1st + 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) @@ -1645,7 +1729,7 @@ bool INetURLObject::convertRelToAbs(OUString const & rTheRelURIRef, // is empty ("") in that case, so take the scheme from m_aAbsURIRef if (m_eScheme != INetProtocol::Generic) { - aSynAbsURIRef.append(getSchemeInfo().m_sScheme.asView()); + aSynAbsURIRef.append(getSchemeInfo().m_sScheme); } else { @@ -1875,7 +1959,7 @@ bool INetURLObject::convertRelToAbs(OUString const & rTheRelURIRef, } } - INetURLObject aNewURI(aSynAbsURIRef.makeStringAndClear()); + INetURLObject aNewURI(aSynAbsURIRef); if (aNewURI.HasError()) { // Detect cases where a relative input could not be made absolute @@ -2038,15 +2122,13 @@ bool INetURLObject::convertAbsToRel(OUString const & rTheAbsURIRef, // to the new relative URL: if (aSubject.m_aQuery.isPresent()) { - aSynRelURIRef.append('?'); - aSynRelURIRef.append(aSubject.decode(aSubject.m_aQuery, - eDecodeMechanism, eCharset)); + aSynRelURIRef.append("?" + + aSubject.decode(aSubject.m_aQuery, eDecodeMechanism, eCharset)); } if (aSubject.m_aFragment.isPresent()) { - aSynRelURIRef.append('#'); - aSynRelURIRef.append(aSubject.decode(aSubject.m_aFragment, - eDecodeMechanism, eCharset)); + aSynRelURIRef.append("#" + + aSubject.decode(aSubject.m_aFragment, eDecodeMechanism, eCharset)); } rTheRelURIRef = aSynRelURIRef.makeStringAndClear(); @@ -2059,8 +2141,9 @@ bool INetURLObject::convertIntToExt(std::u16string_view rTheIntURIRef, DecodeMechanism eDecodeMechanism, rtl_TextEncoding eCharset) { - OUString aSynExtURIRef(encodeText(rTheIntURIRef, PART_VISIBLE, - EncodeMechanism::NotCanonical, eCharset, true)); + OUStringBuffer aSynExtURIRef(256); + encodeText(aSynExtURIRef, rTheIntURIRef, PART_VISIBLE, + EncodeMechanism::NotCanonical, eCharset, true); sal_Unicode const * pBegin = aSynExtURIRef.getStr(); sal_Unicode const * pEnd = pBegin + aSynExtURIRef.getLength(); sal_Unicode const * p = pBegin; @@ -2068,8 +2151,7 @@ bool INetURLObject::convertIntToExt(std::u16string_view rTheIntURIRef, bool bConvert = pPrefix && pPrefix->m_eKind == PrefixInfo::Kind::Internal; if (bConvert) { - aSynExtURIRef = - aSynExtURIRef.replaceAt(0, p - pBegin, + comphelper::string::replaceAt(aSynExtURIRef, 0, p - pBegin, OUString::createFromAscii(pPrefix->m_pTranslatedPrefix)); } rTheExtURIRef = decode(aSynExtURIRef, eDecodeMechanism, eCharset); @@ -2082,8 +2164,9 @@ bool INetURLObject::convertExtToInt(std::u16string_view rTheExtURIRef, DecodeMechanism eDecodeMechanism, rtl_TextEncoding eCharset) { - OUString aSynIntURIRef(encodeText(rTheExtURIRef, PART_VISIBLE, - EncodeMechanism::NotCanonical, eCharset, true)); + OUStringBuffer aSynIntURIRef(256); + encodeText(aSynIntURIRef, rTheExtURIRef, PART_VISIBLE, + EncodeMechanism::NotCanonical, eCharset, true); sal_Unicode const * pBegin = aSynIntURIRef.getStr(); sal_Unicode const * pEnd = pBegin + aSynIntURIRef.getLength(); sal_Unicode const * p = pBegin; @@ -2091,9 +2174,8 @@ bool INetURLObject::convertExtToInt(std::u16string_view rTheExtURIRef, bool bConvert = pPrefix && pPrefix->m_eKind == PrefixInfo::Kind::External; if (bConvert) { - aSynIntURIRef = - aSynIntURIRef.replaceAt(0, p - pBegin, - OUString::createFromAscii(pPrefix->m_pTranslatedPrefix)); + comphelper::string::replaceAt(aSynIntURIRef, 0, p - pBegin, + OUString::createFromAscii(pPrefix->m_pTranslatedPrefix)); } rTheIntURIRef = decode(aSynIntURIRef, eDecodeMechanism, eCharset); return bConvert; @@ -2262,8 +2344,9 @@ bool INetURLObject::setUser(std::u16string_view rTheUser, return false; } - OUString aNewUser(encodeText(rTheUser, PART_USER_PASSWORD, - EncodeMechanism::WasEncoded, eCharset, false)); + OUStringBuffer aNewUser; + encodeText(aNewUser, rTheUser, PART_USER_PASSWORD, + EncodeMechanism::WasEncoded, eCharset, false); sal_Int32 nDelta; if (m_aUser.isPresent()) nDelta = m_aUser.set(m_aAbsURIRef, aNewUser); @@ -2317,8 +2400,9 @@ bool INetURLObject::setPassword(std::u16string_view rThePassword, { if (!getSchemeInfo().m_bPassword) return false; - OUString aNewAuth(encodeText(rThePassword, PART_USER_PASSWORD, - EncodeMechanism::WasEncoded, eCharset, false)); + OUStringBuffer aNewAuth; + encodeText(aNewAuth, rThePassword, PART_USER_PASSWORD, + EncodeMechanism::WasEncoded, eCharset, false); sal_Int32 nDelta; if (m_aAuth.isPresent()) nDelta = m_aAuth.set(m_aAbsURIRef, aNewAuth); @@ -2831,63 +2915,47 @@ bool INetURLObject::parseHostOrNetBiosName( EncodeMechanism eMechanism, rtl_TextEncoding eCharset, bool bNetBiosName, OUStringBuffer* pCanonic) { + if (pBegin >= pEnd) + return true; sal_Int32 nOriginalCanonicLength = pCanonic ? pCanonic->getLength() : 0; - if (pBegin < pEnd) + if (sal_Unicode const* p = pBegin; parseHost(p, pEnd, pCanonic) && p == pEnd) + return true; + if (pCanonic) + pCanonic->setLength(nOriginalCanonicLength); // discard parseHost results + if (!bNetBiosName) + return false; + while (pBegin < pEnd) { - sal_Unicode const * p = pBegin; - if (!parseHost(p, pEnd, pCanonic) || p != pEnd) + EscapeType eEscapeType; + switch (sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd, eMechanism, eCharset, eEscapeType)) { - if (bNetBiosName) - { - OUStringBuffer buf; - while (pBegin < pEnd) + default: + if (INetMIME::isVisible(nUTF32)) { - EscapeType eEscapeType; - sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd, - eMechanism, eCharset, - eEscapeType); - if (!INetMIME::isVisible(nUTF32)) - { - if (pCanonic) - pCanonic->setLength(nOriginalCanonicLength); - return false; - } - if (!rtl::isAsciiAlphanumeric(nUTF32)) - switch (nUTF32) - { - case '"': - case '*': - case '+': - case ',': - case '/': - case ':': - case ';': - case '<': - case '=': - case '>': - case '?': - case '[': - case '\\': - case ']': - case '`': - case '|': - return false; - } - if (pCanonic != nullptr) { - appendUCS4( - buf, nUTF32, eEscapeType, PART_URIC, - eCharset, true); - } + if (pCanonic) + appendUCS4(*pCanonic, nUTF32, eEscapeType, PART_URIC, eCharset, true); + break; } - if (pCanonic) - pCanonic->append(buf); - } - else - { + [[fallthrough]]; + case '"': + case '*': + case '+': + case ',': + case '/': + case ':': + case ';': + case '<': + case '=': + case '>': + case '?': + case '[': + case '\\': + case ']': + case '`': + case '|': if (pCanonic) pCanonic->setLength(nOriginalCanonicLength); return false; - } } } return true; @@ -2904,8 +2972,7 @@ bool INetURLObject::setHost(std::u16string_view rTheHost, { case INetProtocol::File: { - OUString sTemp(aSynHost.toString()); - if (sTemp.equalsIgnoreAsciiCase("localhost")) + if (OUString::unacquired(aSynHost).equalsIgnoreAsciiCase("localhost")) { aSynHost.setLength(0); } @@ -2926,7 +2993,7 @@ bool INetURLObject::setHost(std::u16string_view rTheHost, aSynHost.getStr(), aSynHost.getStr() + aSynHost.getLength(), EncodeMechanism::WasEncoded, eCharset, bNetBiosName, &aSynHost)) return false; - sal_Int32 nDelta = m_aHost.set(m_aAbsURIRef, aSynHost.makeStringAndClear()); + sal_Int32 nDelta = m_aHost.set(m_aAbsURIRef, aSynHost); m_aPort += nDelta; m_aPath += nDelta; m_aQuery += nDelta; @@ -2976,7 +3043,8 @@ bool INetURLObject::parsePath(INetProtocol eScheme, case INetProtocol::Https: case INetProtocol::Smb: case INetProtocol::Cmis: - if (pPos < pEnd && *pPos != '/' && *pPos != nFragmentDelimiter) + if (pPos < pEnd && *pPos != '/' && *pPos != nQueryDelimiter + && *pPos != nFragmentDelimiter) goto failed; while (pPos < pEnd && *pPos != nQueryDelimiter && *pPos != nFragmentDelimiter) @@ -3191,18 +3259,18 @@ failed: return false; } -bool INetURLObject::setPath(OUString const & rThePath, +bool INetURLObject::setPath(std::u16string_view rThePath, EncodeMechanism eMechanism, rtl_TextEncoding eCharset) { OUStringBuffer aSynPath(256); - sal_Unicode const * p = rThePath.getStr(); - sal_Unicode const * pEnd = p + rThePath.getLength(); + sal_Unicode const * p = rThePath.data(); + sal_Unicode const * pEnd = p + rThePath.size(); if (!parsePath(m_eScheme, &p, pEnd, eMechanism, eCharset, false, '/', 0x80000000, 0x80000000, 0x80000000, aSynPath) || p != pEnd) return false; - sal_Int32 nDelta = m_aPath.set(m_aAbsURIRef, aSynPath.makeStringAndClear()); + sal_Int32 nDelta = m_aPath.set(m_aAbsURIRef, aSynPath); m_aQuery += nDelta; m_aFragment += nDelta; return true; @@ -3344,16 +3412,17 @@ bool INetURLObject::insertName(std::u16string_view rTheName, } OUStringBuffer aNewPath(256); - aNewPath.append(pPathBegin, pPrefixEnd - pPathBegin); - aNewPath.append('/'); - aNewPath.append(encodeText(rTheName, PART_PCHAR, - eMechanism, eCharset, true)); + aNewPath.append( + OUString::Concat(std::u16string_view(pPathBegin, pPrefixEnd - pPathBegin)) + + "/"); + encodeText(aNewPath, rTheName, PART_PCHAR, + eMechanism, eCharset, true); if (bInsertSlash) { aNewPath.append('/'); } aNewPath.append(pSuffixBegin, pPathEnd - pSuffixBegin); - return setPath(aNewPath.makeStringAndClear(), EncodeMechanism::NotCanonical, + return setPath(aNewPath, EncodeMechanism::NotCanonical, RTL_TEXTENCODING_UTF8); } @@ -3375,8 +3444,9 @@ bool INetURLObject::setQuery(std::u16string_view rTheQuery, { if (!getSchemeInfo().m_bQuery) return false; - OUString aNewQuery(encodeText(rTheQuery, PART_URIC, - eMechanism, eCharset, true)); + OUStringBuffer aNewQuery; + encodeText(aNewQuery, rTheQuery, PART_URIC, + eMechanism, eCharset, true); sal_Int32 nDelta; if (m_aQuery.isPresent()) nDelta = m_aQuery.set(m_aAbsURIRef, aNewQuery); @@ -3408,8 +3478,9 @@ bool INetURLObject::setFragment(std::u16string_view rTheFragment, { if (HasError()) return false; - OUString aNewFragment(encodeText(rTheFragment, PART_URIC, - eMechanism, eCharset, true)); + OUStringBuffer aNewFragment; + encodeText(aNewFragment, rTheFragment, PART_URIC, + eMechanism, eCharset, true); if (m_aFragment.isPresent()) m_aFragment.set(m_aAbsURIRef, aNewFragment); else @@ -3432,22 +3503,21 @@ bool INetURLObject::hasDosVolume(FSysStyle eStyle) const } // static -OUString INetURLObject::encodeText(sal_Unicode const * pBegin, - sal_Unicode const * pEnd, - Part ePart, EncodeMechanism eMechanism, - rtl_TextEncoding eCharset, - bool bKeepVisibleEscapes) +void INetURLObject::encodeText( OUStringBuffer& rOutputBuffer, + sal_Unicode const * pBegin, + sal_Unicode const * pEnd, + Part ePart, EncodeMechanism eMechanism, + rtl_TextEncoding eCharset, + bool bKeepVisibleEscapes) { - OUStringBuffer aResult(256); while (pBegin < pEnd) { EscapeType eEscapeType; sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd, eMechanism, eCharset, eEscapeType); - appendUCS4(aResult, nUTF32, eEscapeType, ePart, + appendUCS4(rOutputBuffer, nUTF32, eEscapeType, ePart, eCharset, bKeepVisibleEscapes); } - return aResult.makeStringAndClear(); } // static @@ -3536,7 +3606,7 @@ INetURLObject::getAbbreviated( // is empty ("") in that case, so take the scheme from m_aAbsURIRef if (m_eScheme != INetProtocol::Generic) { - aBuffer.append(getSchemeInfo().m_sScheme.asView()); + aBuffer.append(getSchemeInfo().m_sScheme); } else { @@ -3596,9 +3666,7 @@ INetURLObject::getAbbreviated( OUStringBuffer aResult(aBuffer); if (pSuffixEnd != pBegin) aResult.append("..."); - aResult.append(aSegment); - aResult.append(aTrailer); - aResult.append(aRest); + aResult.append(aSegment + aTrailer + aRest); if (rStringWidth-> queryStringWidth(aResult.makeStringAndClear()) <= nWidth) @@ -3633,12 +3701,10 @@ INetURLObject::getAbbreviated( eMechanism, eCharset)); pPrefixBegin = p; - OUStringBuffer aResult(aBuffer); - aResult.append(aSegment); + OUStringBuffer aResult(aBuffer + aSegment); if (pPrefixBegin != pEnd) aResult.append("..."); - aResult.append(aTrailer); - aResult.append(aRest); + aResult.append(aTrailer + aRest); if (rStringWidth-> queryStringWidth(aResult.makeStringAndClear()) <= nWidth) @@ -3670,13 +3736,11 @@ INetURLObject::getAbbreviated( eCharset)); if (m_aQuery.isPresent()) { - aBuffer.append('?'); - aBuffer.append(decode(m_aQuery, eMechanism, eCharset)); + aBuffer.append("?" + decode(m_aQuery, eMechanism, eCharset)); } if (m_aFragment.isPresent()) { - aBuffer.append('#'); - aBuffer.append(decode(m_aFragment, eMechanism, eCharset)); + aBuffer.append("#" + decode(m_aFragment, eMechanism, eCharset)); } if (!aBuffer.isEmpty()) { @@ -3711,7 +3775,7 @@ bool INetURLObject::operator ==(INetURLObject const & rObject) const if (m_eScheme != rObject.m_eScheme) return false; if (m_eScheme == INetProtocol::NotValid) - return m_aAbsURIRef.toString() == rObject.m_aAbsURIRef.toString(); + return std::u16string_view(m_aAbsURIRef) == std::u16string_view(rObject.m_aAbsURIRef); if ((m_aScheme.compare( rObject.m_aScheme, m_aAbsURIRef, rObject.m_aAbsURIRef) != 0) @@ -3764,14 +3828,14 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme, std::u16string_view rThePassword, std::u16string_view rTheHost, sal_uInt32 nThePort, - OUString const & rThePath) + std::u16string_view rThePath) { setInvalid(); m_eScheme = eTheScheme; if (HasError() || m_eScheme == INetProtocol::Generic) return false; m_aAbsURIRef.setLength(0); - m_aAbsURIRef.append(getSchemeInfo().m_sScheme.asView()); + m_aAbsURIRef.append(getSchemeInfo().m_sScheme); m_aAbsURIRef.append(':'); if (getSchemeInfo().m_bAuthority) { @@ -3781,10 +3845,10 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme, { if (!rTheUser.empty()) { - m_aUser.set(m_aAbsURIRef, - encodeText(rTheUser, PART_USER_PASSWORD, - EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, false), - m_aAbsURIRef.getLength()); + OUStringBuffer aNewUser; + encodeText(aNewUser, rTheUser, PART_USER_PASSWORD, + EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, false); + m_aUser.set(m_aAbsURIRef, aNewUser, m_aAbsURIRef.getLength()); bUserInfo = true; } } @@ -3798,10 +3862,10 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme, if (getSchemeInfo().m_bPassword) { m_aAbsURIRef.append(':'); - m_aAuth.set(m_aAbsURIRef, - encodeText(rThePassword, PART_USER_PASSWORD, - EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, false), - m_aAbsURIRef.getLength()); + OUStringBuffer aNewAuth; + encodeText(aNewAuth, rThePassword, PART_USER_PASSWORD, + EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, false); + m_aAuth.set(m_aAbsURIRef, aNewAuth, m_aAbsURIRef.getLength()); bUserInfo = true; } else @@ -3820,8 +3884,7 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme, { case INetProtocol::File: { - OUString sTemp(aSynHost.toString()); - if (sTemp.equalsIgnoreAsciiCase( "localhost" )) + if (OUString::unacquired(aSynHost).equalsIgnoreAsciiCase( "localhost" )) { aSynHost.setLength(0); } @@ -3852,8 +3915,7 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme, setInvalid(); return false; } - m_aHost.set(m_aAbsURIRef, aSynHost.makeStringAndClear(), - m_aAbsURIRef.getLength()); + m_aHost.set(m_aAbsURIRef, aSynHost, m_aAbsURIRef.getLength()); if (nThePort != 0) { if (getSchemeInfo().m_bPort) @@ -3877,8 +3939,8 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme, } } OUStringBuffer aSynPath(256); - sal_Unicode const * p = rThePath.getStr(); - sal_Unicode const * pEnd = p + rThePath.getLength(); + sal_Unicode const * p = rThePath.data(); + sal_Unicode const * pEnd = p + rThePath.size(); if (!parsePath(m_eScheme, &p, pEnd, EncodeMechanism::WasEncoded, RTL_TEXTENCODING_UTF8, false, '/', 0x80000000, 0x80000000, 0x80000000, aSynPath) || p != pEnd) @@ -3886,13 +3948,12 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme, setInvalid(); return false; } - m_aPath.set(m_aAbsURIRef, aSynPath.makeStringAndClear(), - m_aAbsURIRef.getLength()); + m_aPath.set(m_aAbsURIRef, aSynPath, m_aAbsURIRef.getLength()); return true; } // static -OUString INetURLObject::GetAbsURL(OUString const & rTheBaseURIRef, +OUString INetURLObject::GetAbsURL(std::u16string_view rTheBaseURIRef, OUString const & rTheRelURIRef, EncodeMechanism eEncodeMechanism, DecodeMechanism eDecodeMechanism, @@ -3920,7 +3981,7 @@ OUString INetURLObject::getExternalURL() const { OUString aTheExtURIRef; translateToExternal( - m_aAbsURIRef.toString(), aTheExtURIRef); + m_aAbsURIRef, aTheExtURIRef); return aTheExtURIRef; } @@ -3955,11 +4016,10 @@ const OUString & INetURLObject::GetSchemeName(INetProtocol eTheScheme) } // static -INetProtocol INetURLObject::CompareProtocolScheme(OUString const & - rTheAbsURIRef) +INetProtocol INetURLObject::CompareProtocolScheme(std::u16string_view aTheAbsURIRef) { - sal_Unicode const * p = rTheAbsURIRef.getStr(); - PrefixInfo const * pPrefix = getPrefix(p, p + rTheAbsURIRef.getLength()); + sal_Unicode const * p = aTheAbsURIRef.data(); + PrefixInfo const * pPrefix = getPrefix(p, p + aTheAbsURIRef.size()); return pPrefix ? pPrefix->m_eScheme : INetProtocol::NotValid; } @@ -3973,8 +4033,7 @@ OUString INetURLObject::GetHostPort(DecodeMechanism eMechanism, OUStringBuffer aHostPort(decode(m_aHost, eMechanism, eCharset)); if (m_aPort.isPresent()) { - aHostPort.append(':'); - aHostPort.append(decode(m_aPort, eMechanism, eCharset)); + aHostPort.append(":" + decode(m_aPort, eMechanism, eCharset)); } return aHostPort.makeStringAndClear(); } @@ -4049,7 +4108,7 @@ bool INetURLObject::removeSegment(sal_Int32 nIndex, bool bIgnoreFinalSlash) aNewPath.append('/'); } - return setPath(aNewPath.makeStringAndClear(), EncodeMechanism::NotCanonical, + return setPath(aNewPath, EncodeMechanism::NotCanonical, RTL_TEXTENCODING_UTF8); } @@ -4094,12 +4153,11 @@ bool INetURLObject::setName(std::u16string_view rTheName, EncodeMechanism eMecha while (p != pSegEnd && *p != ';') ++p; - return setPath( - std::u16string_view(pPathBegin, pSegBegin - pPathBegin) - + encodeText(rTheName, PART_PCHAR, eMechanism, eCharset, true) - + std::u16string_view(p, pPathEnd - p), - EncodeMechanism::NotCanonical, - RTL_TEXTENCODING_UTF8); + OUStringBuffer aNewPath(256); + aNewPath.append(std::u16string_view(pPathBegin, pSegBegin - pPathBegin)); + encodeText(aNewPath, rTheName, PART_PCHAR, eMechanism, eCharset, true); + aNewPath.append(std::u16string_view(p, pPathEnd - p)); + return setPath(aNewPath, EncodeMechanism::NotCanonical, RTL_TEXTENCODING_UTF8); } bool INetURLObject::hasExtension() @@ -4171,12 +4229,11 @@ bool INetURLObject::setBase(std::u16string_view rTheBase, sal_Int32 nIndex, if (!pExtension) pExtension = p; - return setPath( - std::u16string_view(pPathBegin, pSegBegin - pPathBegin) - + encodeText(rTheBase, PART_PCHAR, eMechanism, eCharset, true) - + std::u16string_view(pExtension, pPathEnd - pExtension), - EncodeMechanism::NotCanonical, - RTL_TEXTENCODING_UTF8); + OUStringBuffer aNewPath(256); + aNewPath.append(std::u16string_view(pPathBegin, pSegBegin - pPathBegin)); + encodeText(aNewPath, rTheBase, PART_PCHAR, eMechanism, eCharset, true); + aNewPath.append(std::u16string_view(pExtension, pPathEnd - pExtension)); + return setPath(aNewPath, EncodeMechanism::NotCanonical, RTL_TEXTENCODING_UTF8); } OUString INetURLObject::getExtension(sal_Int32 nIndex, @@ -4231,12 +4288,11 @@ bool INetURLObject::setExtension(std::u16string_view rTheExtension, if (!pExtension) pExtension = p; - return setPath( - OUString::Concat(std::u16string_view(pPathBegin, pExtension - pPathBegin)) + "." - + encodeText(rTheExtension, PART_PCHAR, EncodeMechanism::WasEncoded, eCharset, true) - + std::u16string_view(p, pPathEnd - p), - EncodeMechanism::NotCanonical, - RTL_TEXTENCODING_UTF8); + OUStringBuffer aNewPath(256); + aNewPath.append(OUString::Concat(std::u16string_view(pPathBegin, pExtension - pPathBegin)) + "."); + encodeText(aNewPath, rTheExtension, PART_PCHAR, EncodeMechanism::WasEncoded, eCharset, true); + aNewPath.append(std::u16string_view(p, pPathEnd - p)); + return setPath(aNewPath, EncodeMechanism::NotCanonical, RTL_TEXTENCODING_UTF8); } bool INetURLObject::removeExtension(sal_Int32 nIndex, bool bIgnoreFinalSlash) @@ -4358,8 +4414,7 @@ OUString INetURLObject::getFSysPath(FSysStyle eStyle, if (pDelimiter) *pDelimiter = '/'; - OUStringBuffer aSynFSysPath; - aSynFSysPath.append("//"); + OUStringBuffer aSynFSysPath("//"); if (m_aHost.isPresent() && m_aHost.getLength() > 0) aSynFSysPath.append(decode(m_aHost, DecodeMechanism::WithCharset, RTL_TEXTENCODING_UTF8)); @@ -4389,10 +4444,9 @@ OUString INetURLObject::getFSysPath(FSysStyle eStyle, OUStringBuffer aSynFSysPath(64); if (m_aHost.isPresent() && m_aHost.getLength() > 0) { - aSynFSysPath.append("\\\\"); - aSynFSysPath.append(decode(m_aHost, DecodeMechanism::WithCharset, - RTL_TEXTENCODING_UTF8)); - aSynFSysPath.append('\\'); + aSynFSysPath.append("\\\\" + + decode(m_aHost, DecodeMechanism::WithCharset, RTL_TEXTENCODING_UTF8) + + "\\"); } sal_Unicode const * p = m_aAbsURIRef.getStr() + m_aPath.getBegin(); @@ -4822,8 +4876,18 @@ void INetURLObject::SetExtension(std::u16string_view rTheExtension) OUString INetURLObject::CutExtension() { OUString aTheExtension(getExtension(LAST_SEGMENT, false)); - return removeExtension(LAST_SEGMENT, false) - ? aTheExtension : OUString(); + if (removeExtension(LAST_SEGMENT, false)) + return aTheExtension; + return OUString(); +} + +bool INetURLObject::IsExoticProtocol() const +{ + return m_eScheme == INetProtocol::Slot || + m_eScheme == INetProtocol::Macro || + m_eScheme == INetProtocol::Uno || + isSchemeEqualTo(u"vnd.sun.star.script") || + isSchemeEqualTo(u"service"); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |