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