LCOV - code coverage report
Current view: top level - svl/source/misc - urihelper.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 255 312 81.7 %
Date: 2012-08-25 Functions: 14 15 93.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 426 836 51.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : #include <svl/urihelper.hxx>
      21                 :            : #include <com/sun/star/beans/XPropertySet.hpp>
      22                 :            : #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
      23                 :            : #include "com/sun/star/lang/XMultiComponentFactory.hpp"
      24                 :            : #include "com/sun/star/ucb/Command.hpp"
      25                 :            : #include <com/sun/star/ucb/FileSystemNotation.hpp>
      26                 :            : #include "com/sun/star/ucb/IllegalIdentifierException.hpp"
      27                 :            : #include "com/sun/star/ucb/UnsupportedCommandException.hpp"
      28                 :            : #include "com/sun/star/ucb/XCommandEnvironment.hpp"
      29                 :            : #include "com/sun/star/ucb/XCommandProcessor.hpp"
      30                 :            : #include "com/sun/star/ucb/XContent.hpp"
      31                 :            : #include "com/sun/star/ucb/XContentIdentifierFactory.hpp"
      32                 :            : #include "com/sun/star/ucb/XContentProvider.hpp"
      33                 :            : #include <com/sun/star/ucb/XContentProviderManager.hpp>
      34                 :            : #include "com/sun/star/uno/Any.hxx"
      35                 :            : #include "com/sun/star/uno/Exception.hpp"
      36                 :            : #include "com/sun/star/uno/Reference.hxx"
      37                 :            : #include "com/sun/star/uno/RuntimeException.hpp"
      38                 :            : #include "com/sun/star/uno/Sequence.hxx"
      39                 :            : #include "com/sun/star/uno/XComponentContext.hpp"
      40                 :            : #include "com/sun/star/uno/XInterface.hpp"
      41                 :            : #include "com/sun/star/uri/UriReferenceFactory.hpp"
      42                 :            : #include "com/sun/star/uri/XUriReference.hpp"
      43                 :            : #include "com/sun/star/uri/XUriReferenceFactory.hpp"
      44                 :            : #include "cppuhelper/exc_hlp.hxx"
      45                 :            : #include "comphelper/processfactory.hxx"
      46                 :            : #include "osl/diagnose.h"
      47                 :            : #include "rtl/ustrbuf.hxx"
      48                 :            : #include "rtl/ustring.h"
      49                 :            : #include "rtl/ustring.hxx"
      50                 :            : #include "sal/types.h"
      51                 :            : #include <tools/inetmime.hxx>
      52                 :            : #include <ucbhelper/contentbroker.hxx>
      53                 :            : #include <unotools/charclass.hxx>
      54                 :            : #include "rtl/instance.hxx"
      55                 :            : 
      56                 :            : namespace css = com::sun::star;
      57                 :            : using namespace com::sun::star;
      58                 :            : 
      59                 :            : //============================================================================
      60                 :            : //
      61                 :            : //  SmartRel2Abs
      62                 :            : //
      63                 :            : //============================================================================
      64                 :            : 
      65                 :            : rtl::OUString
      66                 :         34 : URIHelper::SmartRel2Abs(INetURLObject const & rTheBaseURIRef,
      67                 :            :                         rtl::OUString const & rTheRelURIRef,
      68                 :            :                         Link const & rMaybeFileHdl,
      69                 :            :                         bool bCheckFileExists,
      70                 :            :                         bool bIgnoreFragment,
      71                 :            :                         INetURLObject::EncodeMechanism eEncodeMechanism,
      72                 :            :                         INetURLObject::DecodeMechanism eDecodeMechanism,
      73                 :            :                         rtl_TextEncoding eCharset,
      74                 :            :                         bool bRelativeNonURIs,
      75                 :            :                         INetURLObject::FSysStyle eStyle)
      76                 :            : {
      77                 :            :     // Backwards compatibility:
      78 [ +  - ][ -  + ]:         34 :     if (!rTheRelURIRef.isEmpty() && rTheRelURIRef[0] == '#')
                 [ -  + ]
      79                 :          0 :         return rTheRelURIRef;
      80                 :            : 
      81         [ +  - ]:         34 :     INetURLObject aAbsURIRef;
      82         [ +  + ]:         34 :     if (rTheBaseURIRef.HasError())
      83                 :            :         aAbsURIRef.
      84         [ +  - ]:         28 :             SetSmartURL(rTheRelURIRef, eEncodeMechanism, eCharset, eStyle);
      85                 :            :     else
      86                 :            :     {
      87                 :            :         bool bWasAbsolute;
      88                 :            :         aAbsURIRef = rTheBaseURIRef.smartRel2Abs(rTheRelURIRef,
      89                 :            :                                                  bWasAbsolute,
      90                 :            :                                                  bIgnoreFragment,
      91                 :            :                                                  eEncodeMechanism,
      92                 :            :                                                  eCharset,
      93                 :            :                                                  bRelativeNonURIs,
      94 [ +  - ][ +  - ]:          6 :                                                  eStyle);
                 [ +  - ]
      95         [ -  + ]:          6 :         if (bCheckFileExists
           [ #  #  #  # ]
                 [ -  + ]
      96                 :          0 :             && !bWasAbsolute
      97                 :          0 :             && (aAbsURIRef.GetProtocol() == INET_PROT_FILE))
      98                 :            :         {
      99         [ #  # ]:          0 :             INetURLObject aNonFileURIRef;
     100                 :            :             aNonFileURIRef.SetSmartURL(rTheRelURIRef,
     101                 :            :                                        eEncodeMechanism,
     102                 :            :                                        eCharset,
     103         [ #  # ]:          0 :                                        eStyle);
     104   [ #  #  #  # ]:          0 :             if (!aNonFileURIRef.HasError()
                 [ #  # ]
     105                 :          0 :                 && aNonFileURIRef.GetProtocol() != INET_PROT_FILE)
     106                 :            :             {
     107                 :          0 :                 bool bMaybeFile = false;
     108 [ #  # ][ #  # ]:          0 :                 if (rMaybeFileHdl.IsSet())
     109                 :            :                 {
     110         [ #  # ]:          0 :                     UniString aFilePath(rTheRelURIRef);
     111 [ #  # ][ #  # ]:          0 :                     bMaybeFile = rMaybeFileHdl.Call(&aFilePath) != 0;
     112                 :            :                 }
     113         [ #  # ]:          0 :                 if (!bMaybeFile)
     114         [ #  # ]:          0 :                     aAbsURIRef = aNonFileURIRef;
     115         [ #  # ]:          6 :             }
     116                 :            :         }
     117                 :            :     }
     118 [ +  - ][ +  - ]:         34 :     return aAbsURIRef.GetMainURL(eDecodeMechanism, eCharset);
     119                 :            : }
     120                 :            : 
     121                 :            : //============================================================================
     122                 :            : //
     123                 :            : //  SetMaybeFileHdl
     124                 :            : //
     125                 :            : //============================================================================
     126                 :            : 
     127                 :            : namespace { struct MaybeFileHdl : public rtl::Static< Link, MaybeFileHdl > {}; }
     128                 :            : 
     129                 :         66 : void URIHelper::SetMaybeFileHdl(Link const & rTheMaybeFileHdl)
     130                 :            : {
     131                 :         66 :     MaybeFileHdl::get() = rTheMaybeFileHdl;
     132                 :         66 : }
     133                 :            : 
     134                 :            : //============================================================================
     135                 :            : //
     136                 :            : //  GetMaybeFileHdl
     137                 :            : //
     138                 :            : //============================================================================
     139                 :            : 
     140                 :         28 : Link URIHelper::GetMaybeFileHdl()
     141                 :            : {
     142                 :         28 :     return MaybeFileHdl::get();
     143                 :            : }
     144                 :            : 
     145                 :            : namespace {
     146                 :            : 
     147                 :         32 : bool isAbsoluteHierarchicalUriReference(
     148                 :            :     css::uno::Reference< css::uri::XUriReference > const & uriReference)
     149                 :            : {
     150                 :         64 :     return uriReference.is() && uriReference->isAbsolute()
     151 [ +  - ][ +  - ]:         64 :         && uriReference->isHierarchical() && !uriReference->hasRelativePath();
           [ +  -  +  - ]
     152                 :            : }
     153                 :            : 
     154                 :            : // To improve performance, assume that if for any prefix URL of a given
     155                 :            : // hierarchical URL either a UCB content cannot be created, or the UCB content
     156                 :            : // does not support the getCasePreservingURL command, then this will hold for
     157                 :            : // any other prefix URL of the given URL, too:
     158                 :            : enum Result { Success, GeneralFailure, SpecificFailure };
     159                 :            : 
     160                 :         64 : Result normalizePrefix(
     161                 :            :     css::uno::Reference< css::ucb::XContentProvider > const & broker,
     162                 :            :     rtl::OUString const & uri, rtl::OUString * normalized)
     163                 :            : {
     164                 :            :     OSL_ASSERT(broker.is() && normalized != 0);
     165                 :         64 :     css::uno::Reference< css::ucb::XContent > content;
     166                 :            :     try {
     167         [ +  - ]:         64 :         content = broker->queryContent(
     168                 :            :             css::uno::Reference< css::ucb::XContentIdentifierFactory >(
     169         [ +  - ]:        128 :                 broker, css::uno::UNO_QUERY_THROW)->createContentIdentifier(
           [ +  -  #  # ]
     170 [ +  - ][ +  - ]:         64 :                     uri));
                 [ +  - ]
     171         [ #  # ]:          0 :     } catch (css::ucb::IllegalIdentifierException &) {}
     172         [ +  + ]:         64 :     if (!content.is()) {
     173                 :         32 :         return GeneralFailure;
     174                 :            :     }
     175                 :            :     try {
     176                 :            :         #if OSL_DEBUG_LEVEL > 0
     177                 :            :         bool ok =
     178                 :            :         #endif
     179                 :            :             (css::uno::Reference< css::ucb::XCommandProcessor >(
     180 [ +  - ][ +  - ]:         64 :                    content, css::uno::UNO_QUERY_THROW)->execute(
     181                 :            :                        css::ucb::Command("getCasePreservingURL",
     182                 :            :                            -1, css::uno::Any()),
     183                 :            :                        0,
     184                 :         32 :                        css::uno::Reference< css::ucb::XCommandEnvironment >())
     185         [ +  + ]:         32 :                >>= *normalized);
     186                 :            :         OSL_ASSERT(ok);
     187   [ -  -  -  + ]:         16 :     } catch (css::uno::RuntimeException &) {
     188                 :          0 :         throw;
     189         [ #  # ]:          0 :     } catch (css::ucb::UnsupportedCommandException &) {
     190                 :          0 :         return GeneralFailure;
     191         [ +  - ]:         16 :     } catch (css::uno::Exception &) {
     192                 :         16 :         return SpecificFailure;
     193                 :            :     }
     194                 :         64 :     return Success;
     195                 :            : }
     196                 :            : 
     197                 :         48 : rtl::OUString normalize(
     198                 :            :     css::uno::Reference< css::ucb::XContentProvider > const & broker,
     199                 :            :     css::uno::Reference< css::uri::XUriReferenceFactory > const & uriFactory,
     200                 :            :     rtl::OUString const & uriReference)
     201                 :            : {
     202                 :            :     // normalizePrefix can potentially fail (a typically example being a file
     203                 :            :     // URL that denotes a non-existing resource); in such a case, try to
     204                 :            :     // normalize as long a prefix of the given URL as possible (i.e., normalize
     205                 :            :     // all the existing directories within the path):
     206                 :         48 :     rtl::OUString normalized;
     207                 :         48 :     sal_Int32 n = uriReference.indexOf('#');
     208         [ +  + ]:         48 :     normalized = n == -1 ? uriReference : uriReference.copy(0, n);
     209      [ -  +  + ]:         48 :     switch (normalizePrefix(broker, normalized, &normalized)) {
                 [ +  - ]
     210                 :            :     case Success:
     211 [ #  # ][ #  # ]:          0 :         return n == -1 ? normalized : normalized + uriReference.copy(n);
     212                 :            :     case GeneralFailure:
     213                 :         32 :         return uriReference;
     214                 :            :     case SpecificFailure:
     215                 :            :     default:
     216                 :         16 :         break;
     217                 :            :     }
     218                 :            :     css::uno::Reference< css::uri::XUriReference > ref(
     219 [ +  - ][ +  - ]:         16 :         uriFactory->parse(uriReference));
     220 [ +  - ][ -  + ]:         16 :     if (!isAbsoluteHierarchicalUriReference(ref)) {
     221                 :          0 :         return uriReference;
     222                 :            :     }
     223 [ +  - ][ +  - ]:         16 :     sal_Int32 count = ref->getPathSegmentCount();
     224         [ -  + ]:         16 :     if (count < 2) {
     225                 :          0 :         return uriReference;
     226                 :            :     }
     227 [ +  - ][ +  - ]:         16 :     rtl::OUStringBuffer head(ref->getScheme());
                 [ +  - ]
     228         [ +  - ]:         16 :     head.append(static_cast< sal_Unicode >(':'));
     229 [ +  - ][ +  - ]:         16 :     if (ref->hasAuthority()) {
                 [ -  + ]
     230         [ #  # ]:          0 :         head.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
     231 [ #  # ][ #  # ]:          0 :         head.append(ref->getAuthority());
                 [ #  # ]
     232                 :            :     }
     233         [ +  - ]:         32 :     for (sal_Int32 i = count - 1; i > 0; --i) {
     234         [ +  - ]:         16 :         rtl::OUStringBuffer buf(head);
     235         [ +  + ]:         40 :         for (sal_Int32 j = 0; j < i; ++j) {
     236         [ +  - ]:         24 :             buf.append(static_cast< sal_Unicode >('/'));
     237 [ +  - ][ +  - ]:         24 :             buf.append(ref->getPathSegment(j));
                 [ +  - ]
     238                 :            :         }
     239         [ +  - ]:         16 :         normalized = buf.makeStringAndClear();
     240 [ +  - ][ +  - ]:         16 :         if (normalizePrefix(broker, normalized, &normalized) != SpecificFailure)
     241                 :            :         {
     242         [ +  - ]:         16 :             buf.append(normalized);
     243                 :            :             css::uno::Reference< css::uri::XUriReference > preRef(
     244 [ +  - ][ +  - ]:         16 :                 uriFactory->parse(normalized));
     245 [ +  - ][ -  + ]:         16 :             if (!isAbsoluteHierarchicalUriReference(preRef)) {
     246                 :            :                 // This could only happen if something is inconsistent:
     247                 :            :                 break;
     248                 :            :             }
     249 [ +  - ][ +  - ]:         16 :             sal_Int32 preCount = preRef->getPathSegmentCount();
     250                 :            :             // normalizePrefix may have added or removed a final slash:
     251         [ +  + ]:         16 :             if (preCount != i) {
     252         [ +  + ]:          6 :                 if (preCount == i - 1) {
     253         [ +  - ]:          2 :                     buf.append(static_cast< sal_Unicode >('/'));
     254         [ +  - ]:          8 :                 } else if (preCount - 1 == i && buf.getLength() > 0
           [ +  -  +  - ]
                 [ +  - ]
     255                 :          4 :                            && buf[buf.getLength() - 1] == '/')
     256                 :            :                 {
     257         [ +  - ]:          4 :                     buf.setLength(buf.getLength() - 1);
     258                 :            :                 } else {
     259                 :            :                     // This could only happen if something is inconsistent:
     260                 :            :                     break;
     261                 :            :                 }
     262                 :            :             }
     263         [ +  + ]:         32 :             for (sal_Int32 j = i; j < count; ++j) {
     264         [ +  - ]:         16 :                 buf.append(static_cast< sal_Unicode >('/'));
     265 [ +  - ][ +  - ]:         16 :                 buf.append(ref->getPathSegment(j));
                 [ +  - ]
     266                 :            :             }
     267 [ +  - ][ +  - ]:         16 :             if (ref->hasQuery()) {
                 [ -  + ]
     268         [ #  # ]:          0 :                 buf.append(static_cast< sal_Unicode >('?'));
     269 [ #  # ][ #  # ]:          0 :                 buf.append(ref->getQuery());
                 [ #  # ]
     270                 :            :             }
     271 [ +  - ][ +  - ]:         16 :             if (ref->hasFragment()) {
                 [ +  + ]
     272         [ +  - ]:          2 :                 buf.append(static_cast< sal_Unicode >('#'));
     273 [ +  - ][ +  - ]:          2 :                 buf.append(ref->getFragment());
                 [ +  - ]
     274                 :            :             }
     275 [ +  - ][ -  + ]:         16 :             return buf.makeStringAndClear();
     276                 :            :         }
     277      [ -  -  + ]:         16 :     }
     278                 :         48 :     return uriReference;
     279                 :            : }
     280                 :            : 
     281                 :            : }
     282                 :            : 
     283                 :            : css::uno::Reference< css::uri::XUriReference >
     284                 :         24 : URIHelper::normalizedMakeRelative(
     285                 :            :     css::uno::Reference< css::uno::XComponentContext > const & context,
     286                 :            :     rtl::OUString const & baseUriReference, rtl::OUString const & uriReference)
     287                 :            : {
     288                 :            :     OSL_ASSERT(context.is());
     289                 :            :     css::uno::Reference< css::lang::XMultiComponentFactory > componentFactory(
     290 [ +  - ][ +  - ]:         24 :         context->getServiceManager());
     291         [ -  + ]:         24 :     if (!componentFactory.is()) {
     292                 :            :         throw css::uno::RuntimeException("component context has no service manager",
     293         [ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
     294                 :            :     }
     295         [ +  - ]:         24 :     css::uno::Sequence< css::uno::Any > args(2);
     296 [ +  - ][ +  - ]:         24 :     args[0] <<= rtl::OUString("Local");
     297 [ +  - ][ +  - ]:         24 :     args[1] <<= rtl::OUString("Office");
     298                 :         24 :     css::uno::Reference< css::ucb::XContentProvider > broker;
     299                 :            :     try {
     300                 :            :         broker = css::uno::Reference< css::ucb::XContentProvider >(
     301         [ +  - ]:         24 :             componentFactory->createInstanceWithArgumentsAndContext(
     302                 :            :                 "com.sun.star.ucb.UniversalContentBroker",
     303                 :         24 :                 args, context),
     304 [ +  - ][ +  - ]:         24 :             css::uno::UNO_QUERY_THROW);
                 [ +  - ]
     305                 :          0 :     } catch (css::uno::RuntimeException &) {
     306                 :          0 :         throw;
     307      [ #  #  # ]:          0 :     } catch (css::uno::Exception &) {
     308         [ #  # ]:          0 :         css::uno::Any exception(cppu::getCaughtException());
     309                 :            :         throw css::lang::WrappedTargetRuntimeException(
     310                 :            :             "creating com.sun.star.ucb.UniversalContentBroker failed",
     311                 :            :             css::uno::Reference< css::uno::XInterface >(),
     312         [ #  # ]:          0 :             exception);
     313                 :            :     }
     314                 :            :     css::uno::Reference< css::uri::XUriReferenceFactory > uriFactory(
     315         [ +  - ]:         24 :         css::uri::UriReferenceFactory::create(context));
     316         [ +  - ]:         24 :     return uriFactory->makeRelative(
     317         [ +  - ]:         24 :         uriFactory->parse(normalize(broker, uriFactory, baseUriReference)),
     318         [ +  - ]:         24 :         uriFactory->parse(normalize(broker, uriFactory, uriReference)), true,
     319 [ +  - ][ +  - ]:         48 :         true, false);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     320                 :            : }
     321                 :            : 
     322                 :          0 : rtl::OUString URIHelper::simpleNormalizedMakeRelative(
     323                 :            :     rtl::OUString const & baseUriReference, rtl::OUString const & uriReference)
     324                 :            : {
     325                 :            :     com::sun::star::uno::Reference< com::sun::star::uri::XUriReference > rel(
     326                 :            :         URIHelper::normalizedMakeRelative(
     327                 :            :             com::sun::star::uno::Reference<
     328                 :            :             com::sun::star::uno::XComponentContext >(
     329                 :            :                 (com::sun::star::uno::Reference<
     330                 :            :                  com::sun::star::beans::XPropertySet >(
     331                 :            :                     comphelper::getProcessServiceFactory(),
     332 [ #  # ][ #  # ]:          0 :                     com::sun::star::uno::UNO_QUERY_THROW)->
                 [ #  # ]
     333                 :          0 :                  getPropertyValue("DefaultContext")),
     334                 :            :                 com::sun::star::uno::UNO_QUERY_THROW),
     335 [ #  # ][ #  # ]:          0 :             baseUriReference, uriReference));
                 [ #  # ]
     336 [ #  # ][ #  # ]:          0 :     return rel.is() ? rel->getUriReference() : uriReference;
                 [ #  # ]
     337                 :            : }
     338                 :            : 
     339                 :            : //============================================================================
     340                 :            : //
     341                 :            : //  FindFirstURLInText
     342                 :            : //
     343                 :            : //============================================================================
     344                 :            : 
     345                 :            : namespace {
     346                 :            : 
     347                 :       1492 : inline xub_StrLen nextChar(UniString const & rStr, xub_StrLen nPos)
     348                 :            : {
     349                 :       1492 :     return INetMIME::isHighSurrogate(rStr.GetChar(nPos))
     350                 :          0 :            && rStr.Len() - nPos >= 2
     351                 :          0 :            && INetMIME::isLowSurrogate(rStr.GetChar(nPos + 1)) ?
     352   [ -  +  #  #  :       1492 :                nPos + 2 : nPos + 1;
                   #  # ]
     353                 :            : }
     354                 :            : 
     355                 :       1542 : bool isBoundary1(CharClass const & rCharClass, UniString const & rStr,
     356                 :            :                  xub_StrLen nPos, xub_StrLen nEnd)
     357                 :            : {
     358         [ +  + ]:       1542 :     if (nPos == nEnd)
     359                 :         16 :         return true;
     360         [ +  + ]:       1526 :     if (rCharClass.isLetterNumeric(rStr, nPos))
     361                 :       1194 :         return false;
     362         [ +  + ]:        332 :     switch (rStr.GetChar(nPos))
     363                 :            :     {
     364                 :            :     case '$':
     365                 :            :     case '%':
     366                 :            :     case '&':
     367                 :            :     case '-':
     368                 :            :     case '/':
     369                 :            :     case '@':
     370                 :            :     case '\\':
     371                 :         34 :         return false;
     372                 :            :     default:
     373                 :       1542 :         return true;
     374                 :            :     }
     375                 :            : }
     376                 :            : 
     377                 :       1492 : bool isBoundary2(CharClass const & rCharClass, UniString const & rStr,
     378                 :            :                  xub_StrLen nPos, xub_StrLen nEnd)
     379                 :            : {
     380         [ -  + ]:       1492 :     if (nPos == nEnd)
     381                 :          0 :         return true;
     382         [ +  + ]:       1492 :     if (rCharClass.isLetterNumeric(rStr, nPos))
     383                 :       1194 :         return false;
     384         [ +  + ]:        298 :     switch (rStr.GetChar(nPos))
     385                 :            :     {
     386                 :            :     case '!':
     387                 :            :     case '#':
     388                 :            :     case '$':
     389                 :            :     case '%':
     390                 :            :     case '&':
     391                 :            :     case '\'':
     392                 :            :     case '*':
     393                 :            :     case '+':
     394                 :            :     case '-':
     395                 :            :     case '/':
     396                 :            :     case '=':
     397                 :            :     case '?':
     398                 :            :     case '@':
     399                 :            :     case '^':
     400                 :            :     case '_':
     401                 :            :     case '`':
     402                 :            :     case '{':
     403                 :            :     case '|':
     404                 :            :     case '}':
     405                 :            :     case '~':
     406                 :         26 :         return false;
     407                 :            :     default:
     408                 :       1492 :         return true;
     409                 :            :     }
     410                 :            : }
     411                 :            : 
     412                 :        442 : bool checkWChar(CharClass const & rCharClass, UniString const & rStr,
     413                 :            :                 xub_StrLen * pPos, xub_StrLen * pEnd, bool bBackslash = false,
     414                 :            :                 bool bPipe = false)
     415                 :            : {
     416                 :        442 :     sal_Unicode c = rStr.GetChar(*pPos);
     417         [ +  - ]:        442 :     if (INetMIME::isUSASCII(c))
     418                 :            :     {
     419                 :            :         static sal_uInt8 const aMap[128]
     420                 :            :             = { 0, 0, 0, 0, 0, 0, 0, 0,
     421                 :            :                 0, 0, 0, 0, 0, 0, 0, 0,
     422                 :            :                 0, 0, 0, 0, 0, 0, 0, 0,
     423                 :            :                 0, 0, 0, 0, 0, 0, 0, 0,
     424                 :            :                 0, 1, 0, 0, 4, 4, 4, 1,   //  !"#$%&'
     425                 :            :                 1, 1, 1, 1, 1, 4, 1, 4,   // ()*+,-./
     426                 :            :                 4, 4, 4, 4, 4, 4, 4, 4,   // 01234567
     427                 :            :                 4, 4, 1, 1, 0, 1, 0, 1,   // 89:;<=>?
     428                 :            :                 4, 4, 4, 4, 4, 4, 4, 4,   // @ABCDEFG
     429                 :            :                 4, 4, 4, 4, 4, 4, 4, 4,   // HIJKLMNO
     430                 :            :                 4, 4, 4, 4, 4, 4, 4, 4,   // PQRSTUVW
     431                 :            :                 4, 4, 4, 1, 2, 1, 0, 1,   // XYZ[\]^_
     432                 :            :                 0, 4, 4, 4, 4, 4, 4, 4,   // `abcdefg
     433                 :            :                 4, 4, 4, 4, 4, 4, 4, 4,   // hijklmno
     434                 :            :                 4, 4, 4, 4, 4, 4, 4, 4,   // pqrstuvw
     435                 :            :                 4, 4, 4, 0, 3, 0, 1, 0 }; // xyz{|}~
     436   [ +  +  -  +  :        442 :         switch (aMap[c])
                      + ]
     437                 :            :         {
     438                 :            :             default: // not uric
     439                 :          8 :                 return false;
     440                 :            : 
     441                 :            :             case 1: // uric
     442                 :         82 :                 ++(*pPos);
     443                 :         82 :                 return true;
     444                 :            : 
     445                 :            :             case 2: // "\"
     446         [ #  # ]:          0 :                 if (bBackslash)
     447                 :            :                 {
     448                 :          0 :                     *pEnd = ++(*pPos);
     449                 :          0 :                     return true;
     450                 :            :                 }
     451                 :            :                 else
     452                 :          0 :                     return false;
     453                 :            : 
     454                 :            :             case 3: // "|"
     455         [ +  - ]:         10 :                 if (bPipe)
     456                 :            :                 {
     457                 :         10 :                     *pEnd = ++(*pPos);
     458                 :         10 :                     return true;
     459                 :            :                 }
     460                 :            :                 else
     461                 :          0 :                     return false;
     462                 :            : 
     463                 :            :             case 4: // alpha, digit, "$", "%", "&", "-", "/", "@" (see
     464                 :            :                     // isBoundary1)
     465                 :        342 :                 *pEnd = ++(*pPos);
     466                 :        342 :                 return true;
     467                 :            :         }
     468                 :            :     }
     469         [ #  # ]:          0 :     else if (rCharClass.isLetterNumeric(rStr, *pPos))
     470                 :            :     {
     471                 :          0 :         *pEnd = *pPos = nextChar(rStr, *pPos);
     472                 :          0 :         return true;
     473                 :            :     }
     474                 :            :     else
     475                 :        442 :         return false;
     476                 :            : }
     477                 :            : 
     478                 :        270 : sal_uInt32 scanDomain(UniString const & rStr, xub_StrLen * pPos,
     479                 :            :                       xub_StrLen nEnd)
     480                 :            : {
     481                 :        270 :     sal_Unicode const * pBuffer = rStr.GetBuffer();
     482                 :        270 :     sal_Unicode const * p = pBuffer + *pPos;
     483         [ +  - ]:        270 :     sal_uInt32 nLabels = INetURLObject::scanDomain(p, pBuffer + nEnd, false);
     484                 :        270 :     *pPos = sal::static_int_cast< xub_StrLen >(p - pBuffer);
     485                 :        270 :     return nLabels;
     486                 :            : }
     487                 :            : 
     488                 :            : }
     489                 :            : 
     490                 :            : rtl::OUString
     491                 :        144 : URIHelper::FindFirstURLInText(rtl::OUString const & rText,
     492                 :            :                               xub_StrLen & rBegin,
     493                 :            :                               xub_StrLen & rEnd,
     494                 :            :                               CharClass const & rCharClass,
     495                 :            :                               INetURLObject::EncodeMechanism eMechanism,
     496                 :            :                               rtl_TextEncoding eCharset,
     497                 :            :                               INetURLObject::FSysStyle eStyle)
     498                 :            : {
     499 [ +  - ][ -  + ]:        144 :     if (!(rBegin <= rEnd && rEnd <= rText.getLength()))
                 [ -  + ]
     500                 :          0 :         return rtl::OUString();
     501                 :            : 
     502                 :            :     // Search for the first substring of [rBegin..rEnd[ that matches any of the
     503                 :            :     // following productions (for which the appropriate style bit is set in
     504                 :            :     // eStyle, if applicable).
     505                 :            :     //
     506                 :            :     // 1st Production (known scheme):
     507                 :            :     //    \B1 <one of the known schemes, except file> ":" 1*wchar ["#" 1*wchar]
     508                 :            :     //        \B1
     509                 :            :     //
     510                 :            :     // 2nd Production (file):
     511                 :            :     //    \B1 "FILE:" 1*(wchar / "\" / "|") ["#" 1*wchar] \B1
     512                 :            :     //
     513                 :            :     // 3rd Production (ftp):
     514                 :            :     //    \B1 "FTP" 2*("." label) ["/" *wchar] ["#" 1*wchar] \B1
     515                 :            :     //
     516                 :            :     // 4th Production (http):
     517                 :            :     //    \B1 "WWW" 2*("." label) ["/" *wchar] ["#" 1*wchar] \B1
     518                 :            :     //
     519                 :            :     // 5th Production (mailto):
     520                 :            :     //    \B2 local-part "@" domain \B1
     521                 :            :     //
     522                 :            :     // 6th Production (UNC file):
     523                 :            :     //    \B1 "\\" domain "\" *(wchar / "\") \B1
     524                 :            :     //
     525                 :            :     // 7th Production (DOS file):
     526                 :            :     //    \B1 ALPHA ":\" *(wchar / "\") \B1
     527                 :            :     //
     528                 :            :     // 8th Production (Unix-like DOS file):
     529                 :            :     //    \B1 ALPHA ":/" *(wchar / "\") \B1
     530                 :            :     //
     531                 :            :     // The productions use the following auxiliary rules.
     532                 :            :     //
     533                 :            :     //    local-part = atom *("." atom)
     534                 :            :     //    atom = 1*(alphanum / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+"
     535                 :            :     //              / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}"
     536                 :            :     //              / "~")
     537                 :            :     //    domain = label *("." label)
     538                 :            :     //    label = alphanum [*(alphanum / "-") alphanum]
     539                 :            :     //    alphanum = ALPHA / DIGIT
     540                 :            :     //    wchar = <any uric character (ignoring the escaped rule), or "%", or
     541                 :            :     //             a letter or digit (according to rCharClass)>
     542                 :            :     //
     543                 :            :     // "\B1" (boundary 1) stands for the beginning or end of the block of text,
     544                 :            :     // or a character that is neither (a) a letter or digit (according to
     545                 :            :     // rCharClass), nor (b) any of "$", "%", "&", "-", "/", "@", or "\".
     546                 :            :     // (FIXME:  What was the rationale for this set of punctuation characters?)
     547                 :            :     //
     548                 :            :     // "\B2" (boundary 2) stands for the beginning or end of the block of text,
     549                 :            :     // or a character that is neither (a) a letter or digit (according to
     550                 :            :     // rCharClass), nor (b) any of "!", "#", "$", "%", "&", "'", "*", "+", "-",
     551                 :            :     // "/", "=", "?", "@", "^", "_", "`", "{", "|", "}", or "~" (i.e., an RFC
     552                 :            :     // 822 <atom> character, or "@" from \B1's set above).
     553                 :            :     //
     554                 :            :     // Productions 1--4, and 6--8 try to find a maximum-length match, but they
     555                 :            :     // stop at the first <wchar> character that is a "\B1" character which is
     556                 :            :     // only followed by "\B1" characters (taking "\" and "|" characters into
     557                 :            :     // account appropriately).  Production 5 simply tries to find a maximum-
     558                 :            :     // length match.
     559                 :            :     //
     560                 :            :     // Productions 1--4 use the given eMechanism and eCharset.  Productions 5--9
     561                 :            :     // use ENCODE_ALL.
     562                 :            :     //
     563                 :            :     // Productions 6--9 are only applicable if the FSYS_DOS bit is set in
     564                 :            :     // eStyle.
     565                 :            : 
     566                 :        144 :     bool bBoundary1 = true;
     567                 :        144 :     bool bBoundary2 = true;
     568         [ +  + ]:       1636 :     for (xub_StrLen nPos = rBegin; nPos != rEnd; nPos = nextChar(rText, nPos))
     569                 :            :     {
     570                 :       1532 :         sal_Unicode c = rText[nPos];
     571         [ +  + ]:       1532 :         if (bBoundary1)
     572                 :            :         {
     573         [ +  + ]:        324 :             if (INetMIME::isAlpha(c))
     574                 :            :             {
     575                 :        268 :                 xub_StrLen i = nPos;
     576                 :            :                 INetProtocol eScheme
     577                 :            :                     = INetURLObject::CompareProtocolScheme(UniString(rText, i,
     578 [ +  - ][ +  - ]:        268 :                                                                      rEnd));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     579         [ +  + ]:        268 :                 if (eScheme == INET_PROT_FILE) // 2nd
     580                 :            :                 {
     581         [ +  + ]:         50 :                     while (rText[i++] != ':') ;
     582                 :         10 :                     xub_StrLen nPrefixEnd = i;
     583                 :         10 :                     xub_StrLen nUriEnd = i;
     584 [ +  + ][ +  + ]:        156 :                     while (i != rEnd
                 [ +  + ]
     585                 :            :                            && checkWChar(rCharClass, rText, &i, &nUriEnd, true,
     586 [ +  - ][ +  - ]:        146 :                                          true)) ;
         [ +  + ][ +  - ]
                 [ #  # ]
     587 [ +  + ][ +  + ]:         10 :                     if (i != nPrefixEnd && rText[i] == '#')
                 [ +  + ]
     588                 :            :                     {
     589                 :          4 :                         ++i;
     590 [ +  + ][ +  - ]:         40 :                         while (i != rEnd
                 [ +  + ]
     591 [ +  - ][ +  - ]:         36 :                                && checkWChar(rCharClass, rText, &i, &nUriEnd)) ;
         [ +  + ][ +  - ]
                 [ #  # ]
     592                 :            :                     }
     593 [ +  + ][ +  - ]:         28 :                     if (nUriEnd != nPrefixEnd
                 [ +  + ]
     594 [ +  - ][ +  - ]:         18 :                         && isBoundary1(rCharClass, rText, nUriEnd, rEnd))
         [ +  + ][ +  - ]
                 [ #  # ]
     595                 :            :                     {
     596                 :            :                         INetURLObject aUri(UniString(rText, nPos,
     597                 :            :                                                      nUriEnd - nPos),
     598                 :            :                                            INET_PROT_FILE, eMechanism, eCharset,
     599 [ +  - ][ +  - ]:          8 :                                            eStyle);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     600         [ +  - ]:          8 :                         if (!aUri.HasError())
     601                 :            :                         {
     602                 :          8 :                             rBegin = nPos;
     603                 :          8 :                             rEnd = nUriEnd;
     604                 :            :                             return
     605         [ +  - ]:          8 :                                 aUri.GetMainURL(INetURLObject::DECODE_TO_IURI);
     606 [ +  - ][ -  + ]:         10 :                         }
     607                 :            :                     }
     608                 :            :                 }
     609         [ +  + ]:        258 :                 else if (eScheme != INET_PROT_NOT_VALID) // 1st
     610                 :            :                 {
     611         [ +  + ]:       1028 :                     while (rText[i++] != ':') ;
     612                 :        100 :                     xub_StrLen nPrefixEnd = i;
     613                 :        100 :                     xub_StrLen nUriEnd = i;
     614 [ +  + ][ +  - ]:        744 :                     while (i != rEnd
                 [ +  + ]
     615 [ +  - ][ +  - ]:        644 :                            && checkWChar(rCharClass, rText, &i, &nUriEnd)) ;
         [ +  + ][ +  - ]
                 [ #  # ]
     616 [ +  + ][ -  + ]:        100 :                     if (i != nPrefixEnd && rText[i] == '#')
                 [ -  + ]
     617                 :            :                     {
     618                 :          0 :                         ++i;
     619 [ #  # ][ #  # ]:          0 :                         while (i != rEnd
                 [ #  # ]
     620 [ #  # ][ #  # ]:          0 :                                && checkWChar(rCharClass, rText, &i, &nUriEnd)) ;
         [ #  # ][ #  # ]
                 [ #  # ]
     621                 :            :                     }
     622         [ +  + ]:        210 :                     if (nUriEnd != nPrefixEnd
           [ -  +  #  # ]
                 [ +  + ]
     623 [ +  - ][ +  - ]:        110 :                         && (isBoundary1(rCharClass, rText, nUriEnd, rEnd)
         [ +  + ][ +  - ]
                 [ #  # ]
     624                 :          0 :                             || rText[nUriEnd] == '\\'))
     625                 :            :                     {
     626                 :            :                         INetURLObject aUri(UniString(rText, nPos,
     627                 :            :                                                      nUriEnd - nPos),
     628                 :            :                                            INET_PROT_HTTP, eMechanism,
     629 [ +  - ][ +  - ]:         10 :                                            eCharset);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     630         [ +  + ]:         10 :                         if (!aUri.HasError())
     631                 :            :                         {
     632                 :          8 :                             rBegin = nPos;
     633                 :          8 :                             rEnd = nUriEnd;
     634                 :            :                             return
     635         [ +  - ]:         10 :                                 aUri.GetMainURL(INetURLObject::DECODE_TO_IURI);
     636 [ +  - ][ +  + ]:        100 :                         }
     637                 :            :                     }
     638                 :            :                 }
     639                 :            : 
     640                 :            :                 // 3rd, 4th:
     641                 :        252 :                 i = nPos;
     642 [ +  - ][ +  - ]:        252 :                 sal_uInt32 nLabels = scanDomain(rText, &i, rEnd);
                 [ +  - ]
     643   [ +  +  +  +  :        522 :                 if (nLabels >= 3
          +  +  -  +  +  
          +  +  -  +  +  
          -  +  +  +  +  
          +  -  +  #  #  
             -  +  #  # ]
                 [ +  + ]
     644                 :         56 :                     && rText[nPos + 3] == '.'
     645                 :         52 :                     && (((rText[nPos] == 'w'
     646                 :         48 :                           || rText[nPos] == 'W')
     647                 :          4 :                          && (rText[nPos + 1] == 'w'
     648                 :          2 :                              || rText[nPos + 1] == 'W')
     649                 :          4 :                          && (rText[nPos + 2] == 'w'
     650                 :          2 :                              || rText[nPos + 2] == 'W'))
     651                 :         48 :                         || ((rText[nPos] == 'f'
     652                 :         46 :                              || rText[nPos] == 'F')
     653                 :          4 :                             && (rText[nPos + 1] == 't'
     654                 :          0 :                                 || rText[nPos + 1] == 'T')
     655                 :          4 :                             && (rText[nPos + 2] == 'p'
     656                 :          0 :                                 || rText[nPos + 2] == 'P'))))
     657                 :            :                     // (note that rText.GetChar(nPos + 3) is guaranteed to be
     658                 :            :                     // valid)
     659                 :            :                 {
     660                 :          8 :                     xub_StrLen nUriEnd = i;
     661 [ +  - ][ +  + ]:          8 :                     if (i != rEnd && rText[i] == '/')
                 [ +  + ]
     662                 :            :                     {
     663                 :          4 :                         nUriEnd = ++i;
     664 [ +  + ][ +  - ]:         56 :                         while (i != rEnd
                 [ +  + ]
     665 [ +  - ][ +  - ]:         52 :                                && checkWChar(rCharClass, rText, &i, &nUriEnd)) ;
         [ +  + ][ +  - ]
                 [ #  # ]
     666                 :            :                     }
     667 [ +  + ][ -  + ]:          8 :                     if (i != rEnd && rText[i] == '#')
                 [ -  + ]
     668                 :            :                     {
     669                 :          0 :                         ++i;
     670 [ #  # ][ #  # ]:          0 :                         while (i != rEnd
                 [ #  # ]
     671 [ #  # ][ #  # ]:          0 :                                && checkWChar(rCharClass, rText, &i, &nUriEnd)) ;
         [ #  # ][ #  # ]
                 [ #  # ]
     672                 :            :                     }
     673 [ +  - ][ +  - ]:          8 :                     if (isBoundary1(rCharClass, rText, nUriEnd, rEnd)
           [ -  +  #  # ]
         [ +  - ][ +  - ]
           [ +  -  #  # ]
     674                 :          0 :                         || rText[nUriEnd] == '\\')
     675                 :            :                     {
     676                 :            :                         INetURLObject aUri(UniString(rText, nPos,
     677                 :            :                                                      nUriEnd - nPos),
     678                 :            :                                            INET_PROT_HTTP, eMechanism,
     679 [ +  - ][ +  - ]:          8 :                                            eCharset);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     680         [ +  - ]:          8 :                         if (!aUri.HasError())
     681                 :            :                         {
     682                 :          8 :                             rBegin = nPos;
     683                 :          8 :                             rEnd = nUriEnd;
     684                 :            :                             return
     685         [ +  - ]:          8 :                                 aUri.GetMainURL(INetURLObject::DECODE_TO_IURI);
     686 [ +  - ][ -  + ]:          8 :                         }
     687                 :            :                     }
     688                 :            :                 }
     689                 :            : 
     690 [ +  - ][ +  +  :        494 :                 if ((eStyle & INetURLObject::FSYS_DOS) != 0 && rEnd - nPos >= 3
          +  +  +  +  +  
              - ][ +  + ]
     691                 :        242 :                     && rText[nPos + 1] == ':'
     692                 :          6 :                     && (rText[nPos + 2] == '/'
     693                 :          2 :                         || rText[nPos + 2] == '\\')) // 7th, 8th
     694                 :            :                 {
     695                 :          6 :                     i = nPos + 3;
     696                 :          6 :                     xub_StrLen nUriEnd = i;
     697 [ +  + ][ +  + ]:         84 :                     while (i != rEnd
                 [ +  + ]
     698 [ +  - ][ +  - ]:         78 :                            && checkWChar(rCharClass, rText, &i, &nUriEnd)) ;
         [ +  + ][ +  - ]
                 [ #  # ]
     699 [ +  - ][ +  - ]:          6 :                     if (isBoundary1(rCharClass, rText, nUriEnd, rEnd))
         [ +  - ][ +  - ]
     700                 :            :                     {
     701                 :            :                         INetURLObject aUri(UniString(rText, nPos,
     702                 :            :                                                      nUriEnd - nPos),
     703                 :            :                                            INET_PROT_FILE,
     704                 :            :                                            INetURLObject::ENCODE_ALL,
     705                 :            :                                            RTL_TEXTENCODING_UTF8,
     706 [ +  - ][ +  - ]:          6 :                                            INetURLObject::FSYS_DOS);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     707         [ +  - ]:          6 :                         if (!aUri.HasError())
     708                 :            :                         {
     709                 :          6 :                             rBegin = nPos;
     710                 :          6 :                             rEnd = nUriEnd;
     711                 :            :                             return
     712         [ +  - ]:          6 :                                 aUri.GetMainURL(INetURLObject::DECODE_TO_IURI);
     713 [ +  - ][ -  + ]:        268 :                         }
     714                 :            :                     }
     715                 :            :                 }
     716                 :            :             }
     717 [ +  - ][ +  +  :        110 :             else if ((eStyle & INetURLObject::FSYS_DOS) != 0 && rEnd - nPos >= 2
             +  +  +  + ]
                 [ +  + ]
     718                 :         48 :                      && rText[nPos] == '\\'
     719                 :          6 :                      && rText[nPos + 1] == '\\') // 6th
     720                 :            :             {
     721                 :          2 :                 xub_StrLen i = nPos + 2;
     722 [ +  - ][ +  - ]:          2 :                 sal_uInt32 nLabels = scanDomain(rText, &i, rEnd);
                 [ +  - ]
     723 [ +  - ][ +  - ]:          2 :                 if (nLabels >= 1 && i != rEnd && rText[i] == '\\')
         [ +  - ][ +  - ]
     724                 :            :                 {
     725                 :          2 :                     xub_StrLen nUriEnd = ++i;
     726 [ +  + ][ +  - ]:         48 :                     while (i != rEnd
                 [ +  + ]
     727                 :            :                            && checkWChar(rCharClass, rText, &i, &nUriEnd,
     728 [ +  - ][ +  - ]:         46 :                                          true)) ;
         [ +  + ][ +  - ]
                 [ #  # ]
     729 [ +  - ][ +  - ]:          2 :                     if (isBoundary1(rCharClass, rText, nUriEnd, rEnd))
         [ +  - ][ +  - ]
     730                 :            :                     {
     731                 :            :                         INetURLObject aUri(UniString(rText, nPos,
     732                 :            :                                                      nUriEnd - nPos),
     733                 :            :                                            INET_PROT_FILE,
     734                 :            :                                            INetURLObject::ENCODE_ALL,
     735                 :            :                                            RTL_TEXTENCODING_UTF8,
     736 [ +  - ][ +  - ]:          2 :                                            INetURLObject::FSYS_DOS);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     737         [ +  - ]:          2 :                         if (!aUri.HasError())
     738                 :            :                         {
     739                 :          2 :                             rBegin = nPos;
     740                 :          2 :                             rEnd = nUriEnd;
     741                 :            :                             return
     742         [ +  - ]:          2 :                                 aUri.GetMainURL(INetURLObject::DECODE_TO_IURI);
     743 [ +  - ][ -  + ]:          2 :                         }
     744                 :            :                     }
     745                 :            :                 }
     746                 :            :             }
     747                 :            :         }
     748 [ +  + ][ +  + ]:       1500 :         if (bBoundary2 && INetMIME::isAtomChar(c)) // 5th
                 [ +  + ]
     749                 :            :         {
     750                 :        266 :             bool bDot = false;
     751         [ +  + ]:       2472 :             for (xub_StrLen i = nPos + 1; i != rEnd; ++i)
     752                 :            :             {
     753                 :       2214 :                 sal_Unicode c2 = rText[i];
     754 [ +  + ][ +  - ]:       2214 :                 if (INetMIME::isAtomChar(c2))
     755                 :       1760 :                     bDot = false;
     756         [ +  + ]:        454 :                 else if (bDot)
     757                 :         12 :                     break;
     758         [ +  + ]:        442 :                 else if (c2 == '.')
     759                 :        216 :                     bDot = true;
     760                 :            :                 else
     761                 :            :                 {
     762         [ +  + ]:        226 :                     if (c2 == '@')
     763                 :            :                     {
     764                 :         16 :                         ++i;
     765 [ +  - ][ +  - ]:         16 :                         sal_uInt32 nLabels = scanDomain(rText, &i, rEnd);
                 [ +  - ]
     766 [ +  - ][ +  + ]:         48 :                         if (nLabels >= 1
                 [ +  + ]
     767 [ +  - ][ +  - ]:         32 :                             && isBoundary1(rCharClass, rText, i, rEnd))
         [ +  - ][ +  - ]
                 [ #  # ]
     768                 :            :                         {
     769                 :            :                             INetURLObject aUri(UniString(rText, nPos, i - nPos),
     770                 :            :                                                INET_PROT_MAILTO,
     771 [ +  - ][ +  - ]:          8 :                                                INetURLObject::ENCODE_ALL);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     772         [ +  - ]:          8 :                             if (!aUri.HasError())
     773                 :            :                             {
     774                 :          8 :                                 rBegin = nPos;
     775                 :          8 :                                 rEnd = i;
     776                 :            :                                 return aUri.GetMainURL(
     777         [ +  - ]:          8 :                                            INetURLObject::DECODE_TO_IURI);
     778 [ +  - ][ -  + ]:          8 :                             }
     779                 :            :                         }
     780                 :            :                     }
     781                 :        218 :                     break;
     782                 :            :                 }
     783                 :            :             }
     784                 :            :         }
     785         [ +  - ]:       1492 :         bBoundary1 = isBoundary1(rCharClass, rText, nPos, rEnd);
     786         [ +  - ]:       1492 :         bBoundary2 = isBoundary2(rCharClass, rText, nPos, rEnd);
     787                 :            :     }
     788                 :        104 :     rBegin = rEnd;
     789                 :        144 :     return rtl::OUString();
     790                 :            : }
     791                 :            : 
     792                 :            : //============================================================================
     793                 :            : //
     794                 :            : //  removePassword
     795                 :            : //
     796                 :            : //============================================================================
     797                 :            : 
     798                 :            : rtl::OUString
     799                 :         54 : URIHelper::removePassword(rtl::OUString const & rURI,
     800                 :            :                           INetURLObject::EncodeMechanism eEncodeMechanism,
     801                 :            :                           INetURLObject::DecodeMechanism eDecodeMechanism,
     802                 :            :                           rtl_TextEncoding eCharset)
     803                 :            : {
     804         [ +  - ]:         54 :     INetURLObject aObj(rURI, eEncodeMechanism, eCharset);
     805                 :         54 :     return aObj.HasError() ?
     806                 :            :                rURI :
     807 [ +  - ][ +  - ]:         54 :                aObj.GetURLNoPass(eDecodeMechanism, eCharset);
                 [ +  + ]
     808                 :            : }
     809                 :            : 
     810                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10