b24a4d255d
found by tweaking the loplugin:stringview and making it whitelist getLength Change-Id: Ic15d3703d1fb07658e99e1db1c89e2fa5bc70c19 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132771 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
234 lines
7.2 KiB
C++
234 lines
7.2 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
|
|
/**************************************************************************
|
|
TODO
|
|
**************************************************************************
|
|
|
|
*************************************************************************/
|
|
|
|
#include <sal/config.h>
|
|
|
|
#include <string_view>
|
|
|
|
#include <comphelper/storagehelper.hxx>
|
|
|
|
#include "../inc/urihelper.hxx"
|
|
|
|
#include "pkguri.hxx"
|
|
|
|
using namespace package_ucp;
|
|
|
|
|
|
// PackageUri Implementation.
|
|
|
|
|
|
static void normalize( OUString& rURL )
|
|
{
|
|
sal_Int32 nPos = 0;
|
|
do
|
|
{
|
|
nPos = rURL.indexOf( '%', nPos );
|
|
if ( nPos != -1 )
|
|
{
|
|
if ( nPos < ( rURL.getLength() - 2 ) )
|
|
{
|
|
OUString aTmp = rURL.copy( nPos + 1, 2 );
|
|
rURL = rURL.replaceAt( nPos + 1, 2, aTmp.toAsciiUpperCase() );
|
|
nPos++;
|
|
}
|
|
}
|
|
}
|
|
while ( nPos != -1 );
|
|
}
|
|
|
|
|
|
void PackageUri::init() const
|
|
{
|
|
// Already inited?
|
|
if ( m_aUri.isEmpty() || !m_aPath.isEmpty() )
|
|
return;
|
|
|
|
// Note: Maybe it's a re-init, setUri only resets m_aPath!
|
|
m_aPackage.clear();
|
|
m_aParentUri.clear();
|
|
m_aName.clear();
|
|
m_aParam.clear();
|
|
m_aScheme.clear();
|
|
|
|
// URI must match at least: <scheme>://<non_empty_url_to_file>
|
|
if ( m_aUri.getLength() < PACKAGE_URL_SCHEME_LENGTH + 4 )
|
|
{
|
|
// error, but remember that we did an init().
|
|
m_aPath = "/";
|
|
return;
|
|
}
|
|
|
|
// Scheme must be followed by '://'
|
|
if ( ( m_aUri[ PACKAGE_URL_SCHEME_LENGTH ] != ':' )
|
|
||
|
|
( m_aUri[ PACKAGE_URL_SCHEME_LENGTH + 1 ] != '/' )
|
|
||
|
|
( m_aUri[ PACKAGE_URL_SCHEME_LENGTH + 2 ] != '/' ) )
|
|
{
|
|
// error, but remember that we did an init().
|
|
m_aPath = "/";
|
|
return;
|
|
}
|
|
|
|
OUString aPureUri;
|
|
sal_Int32 nParam = m_aUri.indexOf( '?' );
|
|
if( nParam >= 0 )
|
|
{
|
|
m_aParam = m_aUri.copy( nParam );
|
|
aPureUri = m_aUri.copy( 0, nParam );
|
|
}
|
|
else
|
|
aPureUri = m_aUri;
|
|
|
|
// Scheme is case insensitive.
|
|
m_aScheme = aPureUri.copy(
|
|
0, PACKAGE_URL_SCHEME_LENGTH ).toAsciiLowerCase();
|
|
|
|
if ( m_aScheme == PACKAGE_URL_SCHEME || m_aScheme == PACKAGE_ZIP_URL_SCHEME )
|
|
{
|
|
if ( m_aScheme == PACKAGE_ZIP_URL_SCHEME )
|
|
{
|
|
m_aParam +=
|
|
( !m_aParam.isEmpty()
|
|
? std::u16string_view( u"&purezip" )
|
|
: std::u16string_view( u"?purezip" ) );
|
|
}
|
|
|
|
aPureUri = aPureUri.replaceAt( 0,
|
|
m_aScheme.getLength(),
|
|
m_aScheme );
|
|
|
|
sal_Int32 nStart = PACKAGE_URL_SCHEME_LENGTH + 3;
|
|
sal_Int32 nEnd = aPureUri.lastIndexOf( '/' );
|
|
if ( nEnd == PACKAGE_URL_SCHEME_LENGTH + 3 )
|
|
{
|
|
// Only <scheme>:/// - Empty authority
|
|
|
|
// error, but remember that we did an init().
|
|
m_aPath = "/";
|
|
return;
|
|
}
|
|
else if ( nEnd == ( aPureUri.getLength() - 1 ) )
|
|
{
|
|
if ( aPureUri[ aPureUri.getLength() - 2 ] == '/' )
|
|
{
|
|
// Only <scheme>://// or <scheme>://<something>
|
|
|
|
// error, but remember that we did an init().
|
|
m_aPath = "/";
|
|
return;
|
|
}
|
|
|
|
// Remove trailing slash.
|
|
aPureUri = aPureUri.copy( 0, nEnd );
|
|
}
|
|
|
|
|
|
nEnd = aPureUri.indexOf( '/', nStart );
|
|
if ( nEnd == -1 )
|
|
{
|
|
// root folder.
|
|
|
|
OUString aNormPackage = aPureUri.copy( nStart );
|
|
normalize( aNormPackage );
|
|
|
|
aPureUri = aPureUri.replaceAt(
|
|
nStart, aPureUri.getLength() - nStart, aNormPackage );
|
|
m_aPackage
|
|
= ::ucb_impl::urihelper::decodeSegment( aNormPackage );
|
|
m_aPath = "/";
|
|
m_aUri = m_aUri.replaceAt( 0,
|
|
( nParam >= 0 )
|
|
? nParam
|
|
: m_aUri.getLength(), aPureUri );
|
|
|
|
sal_Int32 nLastSlash = m_aPackage.lastIndexOf( '/' );
|
|
if ( nLastSlash != -1 )
|
|
m_aName = ::ucb_impl::urihelper::decodeSegment(
|
|
m_aPackage.copy( nLastSlash + 1 ) );
|
|
else
|
|
m_aName
|
|
= ::ucb_impl::urihelper::decodeSegment( m_aPackage );
|
|
}
|
|
else
|
|
{
|
|
m_aPath = aPureUri.copy( nEnd + 1 );
|
|
|
|
// Unexpected sequences of characters:
|
|
// - empty path segments
|
|
// - encoded slashes
|
|
// - parent folder segments ".."
|
|
// - current folder segments "."
|
|
if ( m_aPath.indexOf( "//" ) != -1
|
|
|| m_aPath.indexOf( "%2F" ) != -1
|
|
|| m_aPath.indexOf( "%2f" ) != -1
|
|
|| ::comphelper::OStorageHelper::PathHasSegment( m_aPath, u".." )
|
|
|| ::comphelper::OStorageHelper::PathHasSegment( m_aPath, u"." ) )
|
|
{
|
|
// error, but remember that we did an init().
|
|
m_aPath = "/";
|
|
return;
|
|
}
|
|
|
|
OUString aNormPackage = aPureUri.copy( nStart, nEnd - nStart );
|
|
normalize( aNormPackage );
|
|
|
|
aPureUri = aPureUri.replaceAt(
|
|
nStart, nEnd - nStart, aNormPackage );
|
|
aPureUri = aPureUri.replaceAt(
|
|
nEnd + 1,
|
|
aPureUri.getLength() - nEnd - 1,
|
|
::ucb_impl::urihelper::encodeURI( m_aPath ) );
|
|
|
|
m_aPackage
|
|
= ::ucb_impl::urihelper::decodeSegment( aNormPackage );
|
|
m_aPath = ::ucb_impl::urihelper::decodeSegment( m_aPath );
|
|
m_aUri = m_aUri.replaceAt( 0,
|
|
( nParam >= 0 )
|
|
? nParam
|
|
: m_aUri.getLength(), aPureUri );
|
|
|
|
sal_Int32 nLastSlash = aPureUri.lastIndexOf( '/' );
|
|
if ( nLastSlash != -1 )
|
|
{
|
|
m_aParentUri = aPureUri.copy( 0, nLastSlash );
|
|
m_aName = ::ucb_impl::urihelper::decodeSegment(
|
|
aPureUri.copy( nLastSlash + 1 ) );
|
|
}
|
|
}
|
|
|
|
// success
|
|
m_bValid = true;
|
|
}
|
|
else
|
|
{
|
|
// error, but remember that we did an init().
|
|
m_aPath = "/";
|
|
}
|
|
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|