LCOV - code coverage report
Current view: top level - ucb/source/ucp/package - pkguri.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 78 92 84.8 %
Date: 2014-04-11 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          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             : 
      21             : /**************************************************************************
      22             :                                 TODO
      23             :  **************************************************************************
      24             : 
      25             :  *************************************************************************/
      26             : 
      27             : #include "rtl/ustrbuf.hxx"
      28             : #include "osl/diagnose.h"
      29             : #include "comphelper/storagehelper.hxx"
      30             : 
      31             : #include "../inc/urihelper.hxx"
      32             : 
      33             : #include "pkguri.hxx"
      34             : 
      35             : using namespace package_ucp;
      36             : 
      37             : 
      38             : 
      39             : 
      40             : 
      41             : // PackageUri Implementation.
      42             : 
      43             : 
      44             : 
      45             : 
      46          66 : static void normalize( OUString& rURL )
      47             : {
      48          66 :     sal_Int32 nPos = 0;
      49         608 :     do
      50             :     {
      51         608 :         nPos = rURL.indexOf( '%', nPos );
      52         608 :         if ( nPos != -1 )
      53             :         {
      54         542 :             if ( nPos < ( rURL.getLength() - 2 ) )
      55             :             {
      56         542 :                 OUString aTmp = rURL.copy( nPos + 1, 2 );
      57         542 :                 rURL = rURL.replaceAt( nPos + 1, 2, aTmp.toAsciiUpperCase() );
      58         542 :                 nPos++;
      59             :             }
      60             :         }
      61             :     }
      62             :     while ( nPos != -1 );
      63          66 : }
      64             : 
      65             : 
      66         420 : void PackageUri::init() const
      67             : {
      68             :     // Already inited?
      69         420 :     if ( !m_aUri.isEmpty() && m_aPath.isEmpty() )
      70             :     {
      71             :         // Note: Maybe it's a re-init, setUri only resets m_aPath!
      72          66 :         m_aPackage = m_aParentUri = m_aName = m_aParam = m_aScheme
      73         132 :             = OUString();
      74             : 
      75             :         // URI must match at least: <sheme>://<non_empty_url_to_file>
      76          66 :         if ( ( m_aUri.getLength() < PACKAGE_URL_SCHEME_LENGTH + 4 ) )
      77             :         {
      78             :             // error, but remember that we did a init().
      79           0 :             m_aPath = "/";
      80           0 :             return;
      81             :         }
      82             : 
      83             :         // Scheme must be followed by '://'
      84         132 :         if ( ( m_aUri[ PACKAGE_URL_SCHEME_LENGTH ] != ':' )
      85          66 :              ||
      86          66 :              ( m_aUri[ PACKAGE_URL_SCHEME_LENGTH + 1 ] != '/' )
      87         132 :              ||
      88          66 :              ( m_aUri[ PACKAGE_URL_SCHEME_LENGTH + 2 ] != '/' ) )
      89             :         {
      90             :             // error, but remember that we did a init().
      91           0 :             m_aPath = "/";
      92           0 :             return;
      93             :         }
      94             : 
      95          66 :         OUString aPureUri;
      96          66 :         sal_Int32 nParam = m_aUri.indexOf( '?' );
      97          66 :         if( nParam >= 0 )
      98             :         {
      99           0 :             m_aParam = m_aUri.copy( nParam );
     100           0 :             aPureUri = m_aUri.copy( 0, nParam );
     101             :         }
     102             :         else
     103          66 :             aPureUri = m_aUri;
     104             : 
     105             :         // Scheme is case insensitive.
     106         132 :         m_aScheme = aPureUri.copy(
     107          66 :             0, PACKAGE_URL_SCHEME_LENGTH ).toAsciiLowerCase();
     108             : 
     109          66 :         if ( m_aScheme == PACKAGE_URL_SCHEME || m_aScheme == PACKAGE_ZIP_URL_SCHEME )
     110             :         {
     111          66 :             if ( m_aScheme == PACKAGE_ZIP_URL_SCHEME )
     112             :             {
     113          76 :                 m_aParam +=
     114          38 :                     ( !m_aParam.isEmpty()
     115             :                       ? OUString( "&purezip" )
     116          76 :                       : OUString( "?purezip" ) );
     117             :             }
     118             : 
     119         132 :             aPureUri = aPureUri.replaceAt( 0,
     120             :                                            m_aScheme.getLength(),
     121          66 :                                            m_aScheme );
     122             : 
     123          66 :             sal_Int32 nStart = PACKAGE_URL_SCHEME_LENGTH + 3;
     124          66 :             sal_Int32 nEnd   = aPureUri.lastIndexOf( '/' );
     125          66 :             if ( nEnd == PACKAGE_URL_SCHEME_LENGTH + 3 )
     126             :             {
     127             :                 // Only <scheme>:/// - Empty authority
     128             : 
     129             :                 // error, but remember that we did a init().
     130           0 :                 m_aPath = "/";
     131           0 :                 return;
     132             :             }
     133          66 :             else if ( nEnd == ( aPureUri.getLength() - 1 ) )
     134             :             {
     135           6 :                 if ( aPureUri[ aPureUri.getLength() - 2 ] == '/' )
     136             :                 {
     137             :                     // Only <scheme>://// or <scheme>://<something>
     138             : 
     139             :                     // error, but remember that we did a init().
     140           0 :                     m_aPath = "/";
     141           0 :                     return;
     142             :                 }
     143             : 
     144             :                 // Remove trailing slash.
     145           6 :                 aPureUri = aPureUri.copy( 0, nEnd );
     146             :             }
     147             : 
     148             : 
     149          66 :             nEnd = aPureUri.indexOf( '/', nStart );
     150          66 :             if ( nEnd == -1 )
     151             :             {
     152             :                 // root folder.
     153             : 
     154          38 :                 OUString aNormPackage = aPureUri.copy( nStart );
     155          38 :                 normalize( aNormPackage );
     156             : 
     157          76 :                 aPureUri = aPureUri.replaceAt(
     158          76 :                     nStart, aPureUri.getLength() - nStart, aNormPackage );
     159             :                 m_aPackage
     160          38 :                     = ::ucb_impl::urihelper::decodeSegment( aNormPackage );
     161          38 :                 m_aPath = "/";
     162         114 :                 m_aUri = m_aUri.replaceAt( 0,
     163             :                                            ( nParam >= 0 )
     164             :                                            ? nParam
     165          76 :                                            : m_aUri.getLength(), aPureUri );
     166             : 
     167          38 :                 sal_Int32 nLastSlash = m_aPackage.lastIndexOf( '/' );
     168          38 :                 if ( nLastSlash != -1 )
     169          76 :                     m_aName = ::ucb_impl::urihelper::decodeSegment(
     170          38 :                         m_aPackage.copy( nLastSlash + 1 ) );
     171             :                 else
     172             :                     m_aName
     173           0 :                         = ::ucb_impl::urihelper::decodeSegment( m_aPackage );
     174             :             }
     175             :             else
     176             :             {
     177          28 :                 m_aPath = aPureUri.copy( nEnd + 1 );
     178             : 
     179             :                 // Unexpected sequences of characters:
     180             :                 // - empty path segments
     181             :                 // - encoded slashes
     182             :                 // - parent folder segments ".."
     183             :                 // - current folder segments "."
     184          84 :                 if ( m_aPath.indexOf( "//" ) != -1
     185          28 :                   || m_aPath.indexOf( "%2F" ) != -1
     186          28 :                   || m_aPath.indexOf( "%2f" ) != -1
     187          84 :                   || ::comphelper::OStorageHelper::PathHasSegment( m_aPath, OUString( ".." ) )
     188         112 :                   || ::comphelper::OStorageHelper::PathHasSegment( m_aPath, OUString( "." ) ) )
     189             :                 {
     190             :                     // error, but remember that we did a init().
     191           0 :                     m_aPath = "/";
     192           0 :                     return;
     193             :                 }
     194             : 
     195          28 :                 OUString aNormPackage = aPureUri.copy( nStart, nEnd - nStart );
     196          28 :                 normalize( aNormPackage );
     197             : 
     198          56 :                 aPureUri = aPureUri.replaceAt(
     199          28 :                     nStart, nEnd - nStart, aNormPackage );
     200          84 :                 aPureUri = aPureUri.replaceAt(
     201             :                     nEnd + 1,
     202          28 :                     aPureUri.getLength() - nEnd - 1,
     203          28 :                     ::ucb_impl::urihelper::encodeURI( m_aPath ) );
     204             : 
     205             :                 m_aPackage
     206          28 :                     = ::ucb_impl::urihelper::decodeSegment( aNormPackage );
     207          28 :                 m_aPath = ::ucb_impl::urihelper::decodeSegment( m_aPath );
     208          84 :                 m_aUri = m_aUri.replaceAt( 0,
     209             :                                            ( nParam >= 0 )
     210             :                                            ? nParam
     211          56 :                                            : m_aUri.getLength(), aPureUri );
     212             : 
     213          28 :                 sal_Int32 nLastSlash = aPureUri.lastIndexOf( '/' );
     214          28 :                 if ( nLastSlash != -1 )
     215             :                 {
     216          28 :                     m_aParentUri = aPureUri.copy( 0, nLastSlash );
     217          56 :                     m_aName = ::ucb_impl::urihelper::decodeSegment(
     218          28 :                         aPureUri.copy( nLastSlash + 1 ) );
     219          28 :                 }
     220             :             }
     221             : 
     222             :             // success
     223          66 :             m_bValid = true;
     224             :         }
     225             :         else
     226             :         {
     227             :             // error, but remember that we did a init().
     228           0 :             m_aPath = "/";
     229          66 :         }
     230             :     }
     231             : }
     232             : 
     233             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10