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 <tools/urlobj.hxx>
21 : : #include <tools/debug.hxx>
22 : : #include <tools/inetmime.hxx>
23 : : #include "com/sun/star/uno/Reference.hxx"
24 : : #include "com/sun/star/util/XStringWidth.hpp"
25 : : #include "osl/diagnose.h"
26 : : #include "osl/file.hxx"
27 : : #include "rtl/string.h"
28 : : #include "rtl/textenc.h"
29 : : #include "rtl/ustring.hxx"
30 : : #include "sal/types.h"
31 : :
32 : : #include <algorithm>
33 : : #include <limits>
34 : :
35 : : #include <string.h>
36 : :
37 : : namespace unnamed_tools_urlobj {} using namespace unnamed_tools_urlobj;
38 : : // unnamed namespaces don't work well yet...
39 : :
40 : : using namespace com::sun;
41 : :
42 : : // INetURLObject
43 : :
44 : : /* The URI grammar (using RFC 2234 conventions).
45 : :
46 : : Constructs of the form
47 : : {reference <rule1> using rule2}
48 : : stand for a rule matching the given rule1 specified in the given reference,
49 : : encoded to URI syntax using rule2 (as specified in this URI grammar).
50 : :
51 : :
52 : : ; RFC 1738, RFC 2396, RFC 2732, private
53 : : login = [user [":" password] "@"] hostport
54 : : user = *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ";" / "=" / "_" / "~")
55 : : password = *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ";" / "=" / "_" / "~")
56 : : hostport = host [":" port]
57 : : host = incomplete-hostname / hostname / IPv4address / IPv6reference
58 : : incomplete-hostname = *(domainlabel ".") domainlabel
59 : : hostname = *(domainlabel ".") toplabel ["."]
60 : : domainlabel = alphanum [*(alphanum / "-") alphanum]
61 : : toplabel = ALPHA [*(alphanum / "-") alphanum]
62 : : IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
63 : : IPv6reference = "[" hexpart [":" IPv4address] "]"
64 : : hexpart = (hexseq ["::" [hexseq]]) / ("::" [hexseq])
65 : : hexseq = hex4 *(":" hex4)
66 : : hex4 = 1*4HEXDIG
67 : : port = *DIGIT
68 : : escaped = "%" HEXDIG HEXDIG
69 : : reserved = "$" / "&" / "+" / "," / "/" / ":" / ";" / "=" / "?" / "@" / "[" / "]"
70 : : mark = "!" / "'" / "(" / ")" / "*" / "-" / "." / "_" / "~"
71 : : alphanum = ALPHA / DIGIT
72 : : unreserved = alphanum / mark
73 : : uric = escaped / reserved / unreserved
74 : : pchar = escaped / unreserved / "$" / "&" / "+" / "," / ":" / "=" / "@"
75 : :
76 : :
77 : : ; RFC 1738, RFC 2396
78 : : ftp-url = "FTP://" login ["/" segment *("/" segment) [";TYPE=" ("A" / "D" / "I")]]
79 : : segment = *pchar
80 : :
81 : :
82 : : ; RFC 1738, RFC 2396
83 : : http-url = "HTTP://" hostport ["/" segment *("/" segment) ["?" *uric]]
84 : : segment = *(pchar / ";")
85 : :
86 : :
87 : : ; RFC 1738, RFC 2396, <http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q188997&>
88 : : file-url = "FILE://" [host / "LOCALHOST" / netbios-name] ["/" segment *("/" segment)]
89 : : segment = *pchar
90 : : netbios-name = 1*{<alphanum / "!" / "#" / "$" / "%" / "&" / "'" / "(" / ")" / "-" / "." / "@" / "^" / "_" / "{" / "}" / "~"> using (escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "-" / "." / "@" / "_" / "~")}
91 : :
92 : :
93 : : ; RFC 2368, RFC 2396
94 : : mailto-url = "MAILTO:" [to] [headers]
95 : : to = {RFC 822 <#mailbox> using *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "@" / "_" / "~")}
96 : : headers = "?" header *("&" header)
97 : : header = hname "=" hvalue
98 : : hname = {RFC 822 <field-name> using *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "@" / "_" / "~")} / "BODY"
99 : : hvalue = {RFC 822 <field-body> using *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "@" / "_" / "~")}
100 : :
101 : :
102 : : ; private (see RFC 1738, RFC 2396)
103 : : vnd-sun-star-webdav-url = "VND.SUN.STAR.WEBDAV://" hostport ["/" segment *("/" segment) ["?" *uric]]
104 : : segment = *(pchar / ";")
105 : :
106 : :
107 : : ; RFC 1738, RFC 2396, RFC 2732
108 : : news-url = "NEWS:" grouppart
109 : : grouppart = "*" / group / article
110 : : group = alpha *(alphanum / "+" / "-" / "." / "_")
111 : : article = 1*(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "?" / "_" / "~") "@" host
112 : :
113 : :
114 : : ; private
115 : : private-url = "PRIVATE:" path ["?" *uric]
116 : : path = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")
117 : :
118 : :
119 : : ; private
120 : : vnd-sun-star-help-url = "VND.SUN.STAR.HELP://" name *("/" segment) ["?" *uric]
121 : : name = *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "@" / "_" / "~")
122 : : segment = *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "@" / "_" / "~")
123 : :
124 : :
125 : : ; private
126 : : https-url = "HTTPS://" hostport ["/" segment *("/" segment) ["?" *uric]]
127 : : segment = *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "@" / "_" / "~")
128 : :
129 : :
130 : : ; private
131 : : slot-url = "SLOT:" path ["?" *uric]
132 : : path = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")
133 : :
134 : :
135 : : ; private
136 : : macro-url = "MACRO:" path ["?" *uric]
137 : : path = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")
138 : :
139 : :
140 : : ; private
141 : : javascript-url = "JAVASCRIPT:" *uric
142 : :
143 : :
144 : : ; private (see RFC 2192)
145 : : imap-url = "IMAP://" user [";AUTH=" auth] "@" hostport "/" segment *("/" segment) ["/;UID=" nz_number]
146 : : user = 1*{RFC 2060 <CHAR8> using (escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "=" / "_" / "~")}
147 : : auth = {RFC 2060 <atom> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "+" / "," / "-" / "." / "=" / "_" / "~")}
148 : : segment = *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / "=" / "@" / "_" / "~")
149 : : nz_number = {RFC 2060 <nz_number> using *DIGIT}
150 : :
151 : :
152 : : ; private
153 : : pop3-url = "POP3://" login ["/" ["<" *uric ">"]]
154 : :
155 : :
156 : : ; RFC 2397
157 : : data-url = "DATA:" [mediatype] [";BASE64"] "," *uric
158 : : mediatype = [type "/" subtype] *(";" attribute "=" value)
159 : : type = {RFC 2045 <type> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / ":" / "?" / "@" / "_" / "~")}
160 : : subtype = {RFC 2045 <subtype> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / ":" / "?" / "@" / "_" / "~")}
161 : : attribute = {RFC 2045 <subtype> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / ":" / "?" / "@" / "_" / "~")}
162 : : value = {RFC 2045 <subtype> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / ":" / "?" / "@" / "_" / "~")}
163 : :
164 : :
165 : : ; RFC 2392, RFC 2396
166 : : cid-url = "CID:" {RFC 822 <addr-spec> using *uric}
167 : :
168 : :
169 : : ; private
170 : : out-url = "OUT:///~" name ["/" *uric]
171 : : name = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "?" / "@" / "_" / "~"
172 : :
173 : :
174 : : ; private
175 : : vnd-sun-star-hier-url = "VND.SUN.STAR.HIER:" ["//"reg_name] *("/" *pchar)
176 : : reg_name = 1*(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "@" / "_" / "~")
177 : :
178 : : ; private
179 : : vim-url = "VIM://" +vimc [":" *vimc] ["/" [("INBOX" message) / ("NEWSGROUPS" ["/" [+vimc message]])]]
180 : : message = ["/" [+vimc [":" +DIGIT "." +DIGIT "." +DIGIT]]]
181 : : vimc = ("=" HEXDIG HEXDIG) / alphanum
182 : :
183 : :
184 : : ; private
185 : : uno-url = ".UNO:" path ["?" *uric]
186 : : path = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")
187 : :
188 : :
189 : : ; private
190 : : component-url = ".COMPONENT:" path ["?" *uric]
191 : : path = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")
192 : :
193 : :
194 : : ; private
195 : : vnd-sun-star-pkg-url = "VND.SUN.STAR.PKG://" reg_name *("/" *pchar) ["?" *uric]
196 : : reg_name = 1*(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "@" / "_" / "~")
197 : :
198 : :
199 : : ; RFC 2255
200 : : ldap-url = "LDAP://" [hostport] ["/" [dn ["?" [attrdesct *("," attrdesc)] ["?" ["base" / "one" / "sub"] ["?" [filter] ["?" extension *("," extension)]]]]]]
201 : : dn = {RFC 2253 <distinguishedName> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")}
202 : : attrdesc = {RFC 2251 <AttributeDescription> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")}
203 : : filter = {RFC 2254 <filter> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")}
204 : : extension = ["!"] ["X-"] extoken ["=" exvalue]
205 : : extoken = {RFC 2252 <oid> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / "/" / ":" / ";" / "@" / "_" / "~")}
206 : : exvalue = {RFC 2251 <LDAPString> using *(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / "/" / ":" / ";" / "=" / "@" / "_" / "~")}
207 : :
208 : :
209 : : ; private
210 : : db-url = "DB:" *uric
211 : :
212 : :
213 : : ; private
214 : : vnd-sun-star-cmd-url = "VND.SUN.STAR.CMD:" opaque_part
215 : : opaque_part = uric_no_slash *uric
216 : : uric_no_slash = unreserved / escaped / ";" / "?" / ":" / "@" / "&" / "=" / "+" / "$" / ","
217 : :
218 : :
219 : : ; private
220 : : vnd-sun-star-url = "VND.SUN.STAR.ODMA:" ["/" *uric_no_slash]
221 : : uric_no_slash = unreserved / escaped / ";" / "?" / ":" / "@" / "&" / "=" / "+" / "$" / ","
222 : :
223 : :
224 : : ; RFC 1738
225 : : telnet-url = "TELNET://" login ["/"]
226 : :
227 : :
228 : : ; private
229 : : vnd-sun-star-expand-url = "VND.SUN.STAR.EXPAND:" opaque_part
230 : : opaque_part = uric_no_slash *uric
231 : : uric_no_slash = unreserved / escaped / ";" / "?" / ":" / "@" / "&" / "=" / "+" / "$" / ","
232 : :
233 : :
234 : : ; private
235 : : vnd-sun-star-tdoc-url = "VND.SUN.STAR.TDOC:/" segment *("/" segment)
236 : : segment = *pchar
237 : :
238 : :
239 : : ; private
240 : : unknown-url = scheme ":" 1*uric
241 : : scheme = ALPHA *(alphanum / "+" / "-" / ".")
242 : :
243 : :
244 : : ; private (http://ubiqx.org/cifs/Appendix-D.html):
245 : : smb-url = "SMB://" login ["/" segment *("/" segment) ["?" *uric]]
246 : : segment = *(pchar / ";")
247 : : */
248 : :
249 : 6831621 : inline sal_Int32 INetURLObject::SubString::clear()
250 : : {
251 : 6831621 : sal_Int32 nDelta = -m_nLength;
252 : 6831621 : m_nBegin = -1;
253 : 6831621 : m_nLength = 0;
254 : 6831621 : return nDelta;
255 : : }
256 : :
257 : 936063 : inline sal_Int32 INetURLObject::SubString::set(rtl::OUStringBuffer & rString,
258 : : rtl::OUString const & rSubString)
259 : : {
260 [ + - ]: 936063 : rtl::OUString sTemp(rString.makeStringAndClear());
261 : 936063 : sal_Int32 nDelta = set(sTemp, rSubString);
262 [ + - ]: 936063 : rString.append(sTemp);
263 : 936063 : return nDelta;
264 : : }
265 : :
266 : 936063 : inline sal_Int32 INetURLObject::SubString::set(rtl::OUString & rString,
267 : : rtl::OUString const & rSubString)
268 : : {
269 : 936063 : sal_Int32 nDelta = rSubString.getLength() - m_nLength;
270 : :
271 : 936063 : rString = rString.replaceAt(m_nBegin, m_nLength, rSubString);
272 : :
273 : 936063 : m_nLength = rSubString.getLength();
274 : 936063 : return nDelta;
275 : : }
276 : :
277 : 916202 : inline sal_Int32 INetURLObject::SubString::set(rtl::OUStringBuffer & rString,
278 : : rtl::OUString const & rSubString,
279 : : sal_Int32 nTheBegin)
280 : : {
281 : 916202 : m_nBegin = nTheBegin;
282 : 916202 : return set(rString, rSubString);
283 : : }
284 : :
285 : 40283 : inline void INetURLObject::SubString::operator +=(sal_Int32 nDelta)
286 : : {
287 [ + + ]: 40283 : if (isPresent())
288 : 198 : m_nBegin = m_nBegin + nDelta;
289 : 40283 : }
290 : :
291 : 2759 : int INetURLObject::SubString::compare(SubString const & rOther,
292 : : rtl::OUStringBuffer const & rThisString,
293 : : rtl::OUStringBuffer const & rOtherString) const
294 : : {
295 : 2759 : sal_Int32 len = std::min(m_nLength, rOther.m_nLength);
296 : 2759 : sal_Unicode const * p1 = rThisString.getStr() + m_nBegin;
297 : 2759 : sal_Unicode const * end = p1 + len;
298 : 2759 : sal_Unicode const * p2 = rOtherString.getStr() + rOther.m_nBegin;
299 [ + + ]: 11011 : while (p1 != end) {
300 [ - + ]: 8252 : if (*p1 < *p2) {
301 : 0 : return -1;
302 [ - + ]: 8252 : } else if (*p1 > *p2) {
303 : 0 : return 1;
304 : : }
305 : 8252 : ++p1;
306 : 8252 : ++p2;
307 : : }
308 : : return m_nLength < rOther.m_nLength ? -1
309 : : : m_nLength > rOther.m_nLength ? 1
310 [ + - ][ - + ]: 2759 : : 0;
311 : : }
312 : :
313 : : struct INetURLObject::SchemeInfo
314 : : {
315 : : sal_Char const * m_pScheme;
316 : : sal_Char const * m_pPrefix;
317 : : sal_uInt16 m_nDefaultPort;
318 : : bool m_bAuthority;
319 : : bool m_bUser;
320 : : bool m_bAuth;
321 : : bool m_bPassword;
322 : : bool m_bHost;
323 : : bool m_bPort;
324 : : bool m_bHierarchical;
325 : : bool m_bQuery;
326 : : };
327 : :
328 : : struct INetURLObject::PrefixInfo
329 : : {
330 : : enum Kind { OFFICIAL, INTERNAL, EXTERNAL, ALIAS }; // order is important!
331 : :
332 : : sal_Char const * m_pPrefix;
333 : : sal_Char const * m_pTranslatedPrefix;
334 : : INetProtocol m_eScheme;
335 : : Kind m_eKind;
336 : : };
337 : :
338 : : static INetURLObject::SchemeInfo const aSchemeInfoMap[INET_PROT_END]
339 : : = { { "", "", 0, false, false, false, false, false, false, false,
340 : : false },
341 : : { "ftp", "ftp://", 21, true, true, false, true, true, true, true,
342 : : false },
343 : : { "http", "http://", 80, true, false, false, false, true, true,
344 : : true, true },
345 : : { "file", "file://", 0, true, false, false, false, true, false,
346 : : true, false },
347 : : { "mailto", "mailto:", 0, false, false, false, false, false,
348 : : false, false, true },
349 : : { "vnd.sun.star.webdav", "vnd.sun.star.webdav://", 80, true, false,
350 : : false, false, true, true, true, true },
351 : : { "news", "news:", 0, false, false, false, false, false, false, false,
352 : : false },
353 : : { "private", "private:", 0, false, false, false, false, false,
354 : : false, false, true },
355 : : { "vnd.sun.star.help", "vnd.sun.star.help://", 0, true, false, false,
356 : : false, false, false, true, true },
357 : : { "https", "https://", 443, true, false, false, false, true, true,
358 : : true, true },
359 : : { "slot", "slot:", 0, false, false, false, false, false, false,
360 : : false, true },
361 : : { "macro", "macro:", 0, false, false, false, false, false, false,
362 : : false, true },
363 : : { "javascript", "javascript:", 0, false, false, false, false,
364 : : false, false, false, false },
365 : : { "imap", "imap://", 143, true, true, true, false, true, true,
366 : : true, false },
367 : : { "pop3", "pop3://", 110, true, true, false, true, true, true,
368 : : false, false },
369 : : { "data", "data:", 0, false, false, false, false, false, false,
370 : : false, false },
371 : : { "cid", "cid:", 0, false, false, false, false, false, false,
372 : : false, false },
373 : : { "out", "out://", 0, true, false, false, false, false, false,
374 : : false, false },
375 : : { "vnd.sun.star.hier", "vnd.sun.star.hier:", 0, true, false, false,
376 : : false, false, false, true, false },
377 : : { "vim", "vim://", 0, true, true, false, true, false, false, true,
378 : : false },
379 : : { ".uno", ".uno:", 0, false, false, false, false, false, false,
380 : : false, true },
381 : : { ".component", ".component:", 0, false, false, false, false,
382 : : false, false, false, true },
383 : : { "vnd.sun.star.pkg", "vnd.sun.star.pkg://", 0, true, false, false,
384 : : false, false, false, true, true },
385 : : { "ldap", "ldap://", 389, true, false, false, false, true, true,
386 : : false, true },
387 : : { "db", "db:", 0, false, false, false, false, false, false, false,
388 : : false },
389 : : { "vnd.sun.star.cmd", "vnd.sun.star.cmd:", 0, false, false, false,
390 : : false, false, false, false, false },
391 : : { "vnd.sun.star.odma", "vnd.sun.star.odma:", 0, false, false, false,
392 : : false, false, false, true, false },
393 : : { "telnet", "telnet://", 23, true, true, false, true, true, true, true,
394 : : false },
395 : : { "vnd.sun.star.expand", "vnd.sun.star.expand:", 0, false, false, false,
396 : : false, false, false, false, false },
397 : : { "vnd.sun.star.tdoc", "vnd.sun.star.tdoc:", 0, false, false, false,
398 : : false, false, false, true, false },
399 : : { "", "", 0, false, false, false, false, true, true, true, false },
400 : : { "smb", "smb://", 139, true, true, false, true, true, true, true,
401 : : true },
402 : : { "hid", "hid:", 0, false, false, false, false, false, false,
403 : : false, true },
404 : : { "sftp", "sftp://", 22, true, true, false, true, true, true, true,
405 : : true },
406 : : { "vnd.libreoffice.cmis+atom", "vnd.libreoffice.cmis+atom://", 0, true, true, false,
407 : : false, true, false, true, true } };
408 : :
409 : : // static
410 : : inline INetURLObject::SchemeInfo const &
411 : 4531240 : INetURLObject::getSchemeInfo(INetProtocol eTheScheme)
412 : : {
413 : 4531240 : return aSchemeInfoMap[eTheScheme];
414 : : };
415 : :
416 : 3977593 : inline INetURLObject::SchemeInfo const & INetURLObject::getSchemeInfo() const
417 : : {
418 : 3977593 : return getSchemeInfo(m_eScheme);
419 : : }
420 : :
421 : : // static
422 : 4283 : inline void INetURLObject::appendEscape(rtl::OUStringBuffer & rTheText,
423 : : sal_Char cEscapePrefix,
424 : : sal_uInt32 nOctet)
425 : : {
426 : 4283 : rTheText.append(sal_Unicode(cEscapePrefix));
427 : 4283 : rTheText.append(sal_Unicode(INetMIME::getHexDigit(int(nOctet >> 4))));
428 : 4283 : rTheText.append(sal_Unicode(INetMIME::getHexDigit(int(nOctet & 15))));
429 : 4283 : }
430 : :
431 : : namespace unnamed_tools_urlobj {
432 : :
433 : : enum
434 : : {
435 : : PA = INetURLObject::PART_OBSOLETE_NORMAL,
436 : : PB = INetURLObject::PART_OBSOLETE_FILE,
437 : : PC = INetURLObject::PART_OBSOLETE_PARAM,
438 : : PD = INetURLObject::PART_USER_PASSWORD,
439 : : PE = INetURLObject::PART_IMAP_ACHAR,
440 : : PF = INetURLObject::PART_VIM,
441 : : PG = INetURLObject::PART_HOST_EXTRA,
442 : : PH = INetURLObject::PART_FPATH,
443 : : PI = INetURLObject::PART_AUTHORITY,
444 : : PJ = INetURLObject::PART_PATH_SEGMENTS_EXTRA,
445 : : PK = INetURLObject::PART_REL_SEGMENT_EXTRA,
446 : : PL = INetURLObject::PART_URIC,
447 : : PM = INetURLObject::PART_HTTP_PATH,
448 : : PN = INetURLObject::PART_FILE_SEGMENT_EXTRA,
449 : : PO = INetURLObject::PART_MESSAGE_ID,
450 : : PP = INetURLObject::PART_MESSAGE_ID_PATH,
451 : : PQ = INetURLObject::PART_MAILTO,
452 : : PR = INetURLObject::PART_PATH_BEFORE_QUERY,
453 : : PS = INetURLObject::PART_PCHAR,
454 : : PT = INetURLObject::PART_FRAGMENT,
455 : : PU = INetURLObject::PART_VISIBLE,
456 : : PV = INetURLObject::PART_VISIBLE_NONSPECIAL,
457 : : PW = INetURLObject::PART_CREATEFRAGMENT,
458 : : PX = INetURLObject::PART_UNO_PARAM_VALUE,
459 : : PY = INetURLObject::PART_UNAMBIGUOUS,
460 : : PZ = INetURLObject::PART_URIC_NO_SLASH,
461 : : P1 = INetURLObject::PART_HTTP_QUERY,
462 : : P2 = INetURLObject::PART_NEWS_ARTICLE_LOCALPART
463 : : };
464 : :
465 : : static sal_uInt32 const aMustEncodeMap[128]
466 : : = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
467 : : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
468 : : /* */ PY,
469 : : /* ! */ PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
470 : : /* " */ PU+PV +PY,
471 : : /* # */ PU,
472 : : /* $ */ PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
473 : : /* % */ PU,
474 : : /* & */ PA+PB+PC+PD+PE +PH+PI+PJ+PK+PL+PM+PN+PO+PP +PR+PS+PT+PU+PV+PW+PX +PZ+P1+P2,
475 : : /* ' */ PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
476 : : /* ( */ PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
477 : : /* ) */ PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
478 : : /* * */ PA+PB+PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
479 : : /* + */ PA+PB+PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX +PZ+P1+P2,
480 : : /* , */ PA+PB+PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW +PZ+P1+P2,
481 : : /* - */ PA+PB+PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
482 : : /* . */ PA+PB+PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
483 : : /* / */ PA+PB+PC +PH +PJ +PL+PM +PP+PQ+PR +PT+PU+PV +PX +P2,
484 : : /* 0 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
485 : : /* 1 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
486 : : /* 2 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
487 : : /* 3 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
488 : : /* 4 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
489 : : /* 5 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
490 : : /* 6 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
491 : : /* 7 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
492 : : /* 8 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
493 : : /* 9 */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
494 : : /* : */ PB+PC +PH+PI+PJ +PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX +PZ+P1+P2,
495 : : /* ; */ PC+PD +PI+PJ+PK+PL+PM +PO+PP+PQ+PR +PT+PU +PW +PZ+P1+P2,
496 : : /* < */ PC +PO+PP +PU+PV +PY,
497 : : /* = */ PA+PB+PC+PD+PE +PH+PI+PJ+PK+PL+PM+PN +PR+PS+PT+PU+PV+PW +PZ+P1+P2,
498 : : /* > */ PC +PO+PP +PU+PV +PY,
499 : : /* ? */ PC +PL +PT+PU +PW+PX +PZ +P2,
500 : : /* @ */ PC +PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1,
501 : : /* A */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
502 : : /* B */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
503 : : /* C */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
504 : : /* D */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
505 : : /* E */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
506 : : /* F */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
507 : : /* G */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
508 : : /* H */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
509 : : /* I */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
510 : : /* J */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
511 : : /* K */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
512 : : /* L */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
513 : : /* M */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
514 : : /* N */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
515 : : /* O */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
516 : : /* P */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
517 : : /* Q */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
518 : : /* R */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
519 : : /* S */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
520 : : /* T */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
521 : : /* U */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
522 : : /* V */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
523 : : /* W */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
524 : : /* X */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
525 : : /* Y */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
526 : : /* Z */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
527 : : /* [ */ PL +PU+PV +PX,
528 : : /* \ */ PB +PU+PV +PY,
529 : : /* ] */ PL +PU+PV +PX,
530 : : /* ^ */ PU+PV +PY,
531 : : /* _ */ PA+PB+PC+PD+PE +PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
532 : : /* ` */ PU+PV +PY,
533 : : /* a */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
534 : : /* b */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
535 : : /* c */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
536 : : /* d */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
537 : : /* e */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
538 : : /* f */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
539 : : /* g */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
540 : : /* h */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
541 : : /* i */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
542 : : /* j */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
543 : : /* k */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
544 : : /* l */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
545 : : /* m */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
546 : : /* n */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
547 : : /* o */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
548 : : /* p */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
549 : : /* q */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
550 : : /* r */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
551 : : /* s */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
552 : : /* t */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
553 : : /* u */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
554 : : /* v */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
555 : : /* w */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
556 : : /* x */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
557 : : /* y */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
558 : : /* z */ PA+PB+PC+PD+PE+PF+PG+PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ+P1+P2,
559 : : /* { */ PU+PV +PY,
560 : : /* | */ PB+PC +PN +PT+PU+PV +PY,
561 : : /* } */ PU+PV +PY,
562 : : /* ~ */ PA+PB+PC+PD+PE +PH+PI+PJ+PK+PL+PM+PN+PO+PP+PQ+PR+PS+PT+PU+PV+PW+PX+PY+PZ +P2,
563 : : 0 };
564 : :
565 : 15732343 : inline bool mustEncode(sal_uInt32 nUTF32, INetURLObject::Part ePart)
566 : : {
567 [ + - ][ + + ]: 15732343 : return !INetMIME::isUSASCII(nUTF32) || !(aMustEncodeMap[nUTF32] & ePart);
568 : : }
569 : :
570 : : }
571 : :
572 : 853952 : void INetURLObject::setInvalid()
573 : : {
574 : 853952 : m_aAbsURIRef.setLength(0);
575 : 853952 : m_eScheme = INET_PROT_NOT_VALID;
576 : 853952 : m_aScheme.clear();
577 : 853952 : m_aUser.clear();
578 : 853952 : m_aAuth.clear();
579 : 853952 : m_aHost.clear();
580 : 853952 : m_aPort.clear();
581 : 853952 : m_aPath.clear();
582 : 853952 : m_aQuery.clear();
583 : 853952 : m_aFragment.clear();
584 : 853952 : }
585 : :
586 : : namespace unnamed_tools_urlobj {
587 : :
588 : 423 : INetURLObject::FSysStyle guessFSysStyleByCounting(sal_Unicode const * pBegin,
589 : : sal_Unicode const * pEnd,
590 : : INetURLObject::FSysStyle eStyle)
591 : : {
592 : : DBG_ASSERT(eStyle
593 : : & (INetURLObject::FSYS_UNX
594 : : | INetURLObject::FSYS_DOS
595 : : | INetURLObject::FSYS_MAC),
596 : : "guessFSysStyleByCounting(): Bad style");
597 : : DBG_ASSERT(std::numeric_limits< sal_Int32 >::min() < pBegin - pEnd
598 : : && pEnd - pBegin <= std::numeric_limits< sal_Int32 >::max(),
599 : : "guessFSysStyleByCounting(): Too big");
600 : : sal_Int32 nSlashCount
601 : : = eStyle & INetURLObject::FSYS_UNX ?
602 [ - + ]: 423 : 0 : std::numeric_limits< sal_Int32 >::min();
603 : : sal_Int32 nBackslashCount
604 : : = eStyle & INetURLObject::FSYS_DOS ?
605 [ - + ]: 423 : 0 : std::numeric_limits< sal_Int32 >::min();
606 : : sal_Int32 nColonCount
607 : : = eStyle & INetURLObject::FSYS_MAC ?
608 [ + - ]: 423 : 0 : std::numeric_limits< sal_Int32 >::min();
609 [ + + ]: 4132 : while (pBegin != pEnd)
610 [ - - - + ]: 3709 : switch (*pBegin++)
611 : : {
612 : : case '/':
613 : 0 : ++nSlashCount;
614 : 0 : break;
615 : :
616 : : case '\\':
617 : 0 : ++nBackslashCount;
618 : 0 : break;
619 : :
620 : : case ':':
621 : 0 : ++nColonCount;
622 : 0 : break;
623 : : }
624 : : return nSlashCount >= nBackslashCount ?
625 : : nSlashCount >= nColonCount ?
626 : : INetURLObject::FSYS_UNX : INetURLObject::FSYS_MAC :
627 : : nBackslashCount >= nColonCount ?
628 [ + - ][ + - ]: 423 : INetURLObject::FSYS_DOS : INetURLObject::FSYS_MAC;
[ # # ]
629 : : }
630 : :
631 : 28253 : rtl::OUString parseScheme(
632 : : sal_Unicode const ** begin, sal_Unicode const * end,
633 : : sal_uInt32 fragmentDelimiter)
634 : : {
635 : 28253 : sal_Unicode const * p = *begin;
636 [ + + ][ + + ]: 28253 : if (p != end && INetMIME::isAlpha(*p)) {
[ + + ]
637 [ + + + + ]: 8619 : do {
[ + - ][ + - ]
[ + + ][ + + ]
638 : 7442 : ++p;
639 : : } while (p != end
640 : 6703 : && (INetMIME::isAlphanumeric(*p) || *p == '+' || *p == '-'
641 : : || *p == '.'));
642 : : // #i34835# To avoid problems with Windows file paths like "C:\foo",
643 : : // do not accept generic schemes that are only one character long:
644 [ + + ][ + + ]: 1177 : if (end - p > 1 && p[0] == ':' && p[1] != fragmentDelimiter
[ + - ][ + - ]
645 : : && p - *begin >= 2)
646 : : {
647 : : rtl::OUString scheme(
648 : 382 : rtl::OUString(*begin, p - *begin).toAsciiLowerCase());
649 : 382 : *begin = p + 1;
650 : 382 : return scheme;
651 : : }
652 : : }
653 : 28253 : return rtl::OUString();
654 : : }
655 : :
656 : : }
657 : :
658 : 826557 : bool INetURLObject::setAbsURIRef(rtl::OUString const & rTheAbsURIRef,
659 : : bool bOctets,
660 : : EncodeMechanism eMechanism,
661 : : rtl_TextEncoding eCharset,
662 : : bool bSmart,
663 : : FSysStyle eStyle)
664 : : {
665 : 826557 : sal_Unicode const * pPos = rTheAbsURIRef.getStr();
666 : 826557 : sal_Unicode const * pEnd = pPos + rTheAbsURIRef.getLength();
667 : :
668 [ + - ]: 826557 : setInvalid();
669 : :
670 : 826557 : sal_uInt32 nFragmentDelimiter = '#';
671 : :
672 : 826557 : rtl::OUStringBuffer aSynAbsURIRef;
673 : :
674 : : // Parse <scheme>:
675 : 826557 : sal_Unicode const * p = pPos;
676 : 826557 : PrefixInfo const * pPrefix = getPrefix(p, pEnd);
677 [ + + ]: 826557 : if (pPrefix)
678 : : {
679 : 797896 : pPos = p;
680 : 797896 : m_eScheme = pPrefix->m_eScheme;
681 : :
682 : : rtl::OUString sTemp(rtl::OUString::createFromAscii(pPrefix->m_eKind
683 : : >= PrefixInfo::EXTERNAL ?
684 : : pPrefix->m_pTranslatedPrefix :
685 [ - + ]: 797896 : pPrefix->m_pPrefix));
686 [ + - ]: 797896 : aSynAbsURIRef.append(sTemp);
687 : 797896 : m_aScheme = SubString( 0, sTemp.indexOf(static_cast< sal_Unicode >(':')) );
688 : : }
689 : : else
690 : : {
691 [ + + ]: 28661 : if (bSmart)
692 : : {
693 : : // For scheme detection, the first (if any) of the following
694 : : // productions that matches the input string (and for which the
695 : : // appropriate style bit is set in eStyle, if applicable)
696 : : // determines the scheme. The productions use the auxiliary rules
697 : : //
698 : : // domain = label *("." label)
699 : : // label = alphanum [*(alphanum / "-") alphanum]
700 : : // alphanum = ALPHA / DIGIT
701 : : // IPv6reference = "[" IPv6address "]"
702 : : // IPv6address = hexpart [":" IPv4address]
703 : : // IPv4address = 1*3DIGIT 3("." 1*3DIGIT)
704 : : // hexpart = (hexseq ["::" [hexseq]]) / ("::" [hexseq])
705 : : // hexseq = hex4 *(":" hex4)
706 : : // hex4 = 1*4HEXDIG
707 : : // UCS4 = <any UCS4 character>
708 : : //
709 : : // 1st Production (known scheme):
710 : : // <one of the known schemes, ignoring case> ":" *UCS4
711 : : // 2nd Production (mailto):
712 : : // domain "@" domain
713 : : // 3rd Production (ftp):
714 : : // "FTP" 2*("." label) ["/" *UCS4]
715 : : // 4th Production (http):
716 : : // label 2*("." label) ["/" *UCS4]
717 : : // 5th Production (file):
718 : : // "//" (domain / IPv6reference) ["/" *UCS4]
719 : : // 6th Production (Unix file):
720 : : // "/" *UCS4
721 : : // 7th Production (UNC file; FSYS_DOS only):
722 : : // "\\" domain ["\" *UCS4]
723 : : // 8th Production (Unix-like DOS file; FSYS_DOS only):
724 : : // ALPHA ":" ["/" *UCS4]
725 : : // 9th Production (DOS file; FSYS_DOS only):
726 : : // ALPHA ":" ["\" *UCS4]
727 : : //
728 : : // For the 'non URL' file productions 6--9, the interpretation of
729 : : // the input as a (degenerate) URI is turned off, i.e., escape
730 : : // sequences and fragments are never detected as such, but are
731 : : // taken as literal characters.
732 : :
733 : 1412 : sal_Unicode const * p1 = pPos;
734 [ + - ]: 2516 : if (eStyle & FSYS_DOS
[ + + + + ]
[ + + ][ + - ]
[ + + ][ + - ]
[ + + ]
735 : : && pEnd - p1 >= 2
736 : 1104 : && INetMIME::isAlpha(p1[0])
737 : 528 : && p1[1] == ':'
738 : 8 : && (pEnd - p1 == 2 || p1[2] == '/' || p1[2] == '\\'))
739 : : {
740 : 6 : m_eScheme = INET_PROT_FILE; // 8th, 9th
741 : 6 : eMechanism = ENCODE_ALL;
742 : 6 : nFragmentDelimiter = 0x80000000;
743 : : }
744 [ + + ][ + + ]: 1406 : else if (pEnd - p1 >= 2 && p1[0] == '/' && p1[1] == '/')
[ - + ]
745 : : {
746 : 0 : p1 += 2;
747 [ # # ][ # # ]: 0 : if ((scanDomain(p1, pEnd) > 0 || scanIPv6reference(p1, pEnd))
[ # # ][ # # ]
[ # # ][ # # ]
748 : : && (p1 == pEnd || *p1 == '/'))
749 : 0 : m_eScheme = INET_PROT_FILE; // 5th
750 : : }
751 [ + + ][ + + ]: 1406 : else if (p1 != pEnd && *p1 == '/')
752 : : {
753 : 570 : m_eScheme = INET_PROT_FILE; // 6th
754 : 570 : eMechanism = ENCODE_ALL;
755 : 570 : nFragmentDelimiter = 0x80000000;
756 : : }
757 [ + - ][ + + ]: 836 : else if (eStyle & FSYS_DOS
[ + + ][ + - ]
758 : : && pEnd - p1 >= 2
759 : 528 : && p1[0] == '\\'
760 : 2 : && p1[1] == '\\')
761 : : {
762 : 2 : p1 += 2;
763 : : sal_Int32 n = rtl_ustr_indexOfChar_WithLength(
764 : 2 : p1, pEnd - p1, '\\');
765 [ + - ]: 2 : sal_Unicode const * pe = n == -1 ? pEnd : p1 + n;
766 [ - + ][ # # ]: 2 : if (
[ # # ][ + - ]
767 : : parseHostOrNetBiosName(
768 : : p1, pe, bOctets, ENCODE_ALL, RTL_TEXTENCODING_DONTKNOW,
769 [ + - ]: 2 : true, NULL) ||
770 [ # # ]: 0 : (scanDomain(p1, pe) > 0 && p1 == pe)
771 : : )
772 : : {
773 : 2 : m_eScheme = INET_PROT_FILE; // 7th
774 : 2 : eMechanism = ENCODE_ALL;
775 : 2 : nFragmentDelimiter = 0x80000000;
776 : 2 : }
777 : : }
778 : : else
779 : : {
780 : 834 : sal_Unicode const * pDomainEnd = p1;
781 [ + - ]: 834 : sal_uInt32 nLabels = scanDomain(pDomainEnd, pEnd);
782 [ + + ][ + + ]: 834 : if (nLabels > 0 && pDomainEnd != pEnd && *pDomainEnd == '@')
[ + + ]
783 : : {
784 : 6 : ++pDomainEnd;
785 [ + - ][ + - ]: 12 : if (scanDomain(pDomainEnd, pEnd) > 0
[ + - ][ + - ]
786 : : && pDomainEnd == pEnd)
787 : 6 : m_eScheme = INET_PROT_MAILTO; // 2nd
788 : : }
789 [ + + ][ + + ]: 828 : else if (nLabels >= 3
[ + + ]
790 : : && (pDomainEnd == pEnd || *pDomainEnd == '/'))
791 : : m_eScheme
792 : : = pDomainEnd - p1 >= 4
793 : 14 : && (p1[0] == 'f' || p1[0] == 'F')
794 : 4 : && (p1[1] == 't' || p1[1] == 'T')
795 : 4 : && (p1[2] == 'p' || p1[2] == 'P')
796 : 4 : && p1[3] == '.' ?
797 [ + - ][ + + ]: 1412 : INET_PROT_FTP : INET_PROT_HTTP; // 3rd, 4th
[ + + ][ - + ]
[ # # ][ - + ]
[ # # ][ + - ]
798 : : }
799 : : }
800 : :
801 : 28661 : rtl::OUString aSynScheme;
802 [ + + ]: 28661 : if (m_eScheme == INET_PROT_NOT_VALID) {
803 : 28069 : sal_Unicode const * p1 = pPos;
804 : 28069 : aSynScheme = parseScheme(&p1, pEnd, nFragmentDelimiter);
805 [ + + ]: 28069 : if (!aSynScheme.isEmpty())
806 : : {
807 : 226 : m_eScheme = INET_PROT_GENERIC;
808 : 28069 : pPos = p1;
809 : : }
810 : : }
811 : :
812 [ + + ][ + + ]: 28661 : if (bSmart && m_eScheme == INET_PROT_NOT_VALID && pPos != pEnd
[ + + ][ + - ]
813 : : && *pPos != nFragmentDelimiter)
814 : : {
815 : 450 : m_eScheme = m_eSmartScheme;
816 : : }
817 : :
818 [ + + ]: 28661 : if (m_eScheme == INET_PROT_NOT_VALID)
819 : : {
820 [ + - ]: 27393 : setInvalid();
821 : 27393 : return false;
822 : : }
823 : :
824 [ + + ]: 1268 : if (m_eScheme != INET_PROT_GENERIC) {
825 : 1042 : aSynScheme = rtl::OUString::createFromAscii(getSchemeInfo().m_pScheme);
826 : : }
827 [ + - ]: 1268 : m_aScheme.set(aSynAbsURIRef, aSynScheme, aSynAbsURIRef.getLength());
828 [ + - ][ + + ]: 28661 : aSynAbsURIRef.append(sal_Unicode(':'));
829 : : }
830 : :
831 : 799164 : sal_Char cEscapePrefix = getEscapePrefix();
832 : 799164 : sal_uInt32 nSegmentDelimiter = '/';
833 : 799164 : sal_uInt32 nAltSegmentDelimiter = 0x80000000;
834 : 799164 : bool bSkippedInitialSlash = false;
835 : :
836 : : // Parse //<user>;AUTH=<auth>@<host>:<port> or
837 : : // //<user>:<password>@<host>:<port> or
838 : : // //<reg_name>
839 [ + + ]: 799164 : if (getSchemeInfo().m_bAuthority)
840 : : {
841 : 112006 : sal_Unicode const * pUserInfoBegin = 0;
842 : 112006 : sal_Unicode const * pUserInfoEnd = 0;
843 : 112006 : sal_Unicode const * pHostPortBegin = 0;
844 : 112006 : sal_Unicode const * pHostPortEnd = 0;
845 : :
846 [ + + + + : 112006 : switch (m_eScheme)
+ ]
847 : : {
848 : : case INET_PROT_VND_SUN_STAR_HELP:
849 : : {
850 [ + - ][ + - ]: 190 : if (pEnd - pPos < 2 || *pPos++ != '/' || *pPos++ != '/')
[ - + ][ - + ]
851 : : {
852 [ # # ]: 0 : setInvalid();
853 : 0 : return false;
854 : : }
855 [ + - ]: 190 : aSynAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
856 : 190 : rtl::OUStringBuffer aSynAuthority;
857 [ + - ][ + + ]: 1516 : while (pPos < pEnd
[ + - ][ + - ]
[ + + ]
858 : : && *pPos != '/' && *pPos != '?'
859 : : && *pPos != nFragmentDelimiter)
860 : : {
861 : : EscapeType eEscapeType;
862 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
863 : : cEscapePrefix, eMechanism,
864 [ + - ]: 1326 : eCharset, eEscapeType);
865 : : appendUCS4(aSynAuthority, nUTF32, eEscapeType, bOctets,
866 : : PART_AUTHORITY, cEscapePrefix, eCharset,
867 [ + - ]: 1326 : false);
868 : : }
869 : : m_aHost.set(aSynAbsURIRef,
870 : : aSynAuthority.makeStringAndClear(),
871 [ + - ][ + - ]: 190 : aSynAbsURIRef.getLength());
872 : : // misusing m_aHost to store the authority
873 : 190 : break;
874 : : }
875 : :
876 : : case INET_PROT_VND_SUN_STAR_HIER:
877 : : {
878 [ + - ][ + - ]: 122 : if (pEnd - pPos >= 2 && pPos[0] == '/' && pPos[1] == '/')
[ + + ]
879 : : {
880 : 44 : pPos += 2;
881 : : aSynAbsURIRef.
882 [ + - ]: 44 : appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
883 : 44 : rtl::OUStringBuffer aSynAuthority;
884 [ + - ][ + + ]: 1936 : while (pPos < pEnd
[ + - ][ + - ]
[ + + ]
885 : : && *pPos != '/' && *pPos != '?'
886 : : && *pPos != nFragmentDelimiter)
887 : : {
888 : : EscapeType eEscapeType;
889 : : sal_uInt32 nUTF32 = getUTF32(pPos,
890 : : pEnd,
891 : : bOctets,
892 : : cEscapePrefix,
893 : : eMechanism,
894 : : eCharset,
895 [ + - ]: 1892 : eEscapeType);
896 : : appendUCS4(aSynAuthority,
897 : : nUTF32,
898 : : eEscapeType,
899 : : bOctets,
900 : : PART_AUTHORITY,
901 : : cEscapePrefix,
902 : : eCharset,
903 [ + - ]: 1892 : false);
904 : : }
905 [ - + ]: 44 : if (aSynAuthority.getLength() == 0)
906 : : {
907 [ # # ]: 0 : setInvalid();
908 : 0 : return false;
909 : : }
910 : : m_aHost.set(aSynAbsURIRef,
911 : : aSynAuthority.makeStringAndClear(),
912 [ + - ][ + - ]: 44 : aSynAbsURIRef.getLength());
[ + - ]
913 : : // misusing m_aHost to store the authority
914 : : }
915 : 122 : break;
916 : : }
917 : :
918 : : case INET_PROT_VND_SUN_STAR_PKG:
919 : : case INET_PROT_CMIS_ATOM:
920 : : {
921 [ + - ][ + - ]: 91 : if (pEnd - pPos < 2 || *pPos++ != '/' || *pPos++ != '/')
[ - + ][ - + ]
922 : : {
923 [ # # ]: 0 : setInvalid();
924 : 0 : return false;
925 : : }
926 [ + - ]: 91 : aSynAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
927 : 91 : rtl::OUStringBuffer aSynUser;
928 : :
929 : 91 : bool bHasUser = false;
930 [ + + ][ + + ]: 2790 : while (pPos < pEnd && *pPos != '@'
[ + + ][ + - ]
[ + - ][ + + ]
931 : : && *pPos != '/' && *pPos != '?'
932 : : && *pPos != nFragmentDelimiter)
933 : : {
934 : : EscapeType eEscapeType;
935 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
936 : : cEscapePrefix, eMechanism,
937 [ + - ]: 2699 : eCharset, eEscapeType);
938 : : appendUCS4(aSynUser, nUTF32, eEscapeType, bOctets,
939 : : PART_USER_PASSWORD, cEscapePrefix, eCharset,
940 [ + - ]: 2699 : false);
941 : :
942 : 2699 : bHasUser = *pPos == '@';
943 : : }
944 : :
945 : 91 : rtl::OUStringBuffer aSynAuthority;
946 [ + + ]: 91 : if ( !bHasUser )
947 : : {
948 [ + - ]: 86 : aSynAuthority = aSynUser;
949 : : }
950 : : else
951 : : {
952 : : m_aUser.set(aSynAbsURIRef,
953 : : aSynUser.makeStringAndClear(),
954 [ + - ][ + - ]: 5 : aSynAbsURIRef.getLength());
955 [ + - ]: 5 : aSynAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("@"));
956 : 5 : ++pPos;
957 : :
958 [ + - ][ + + ]: 265 : while (pPos < pEnd
[ + - ][ + - ]
[ + + ]
959 : : && *pPos != '/' && *pPos != '?'
960 : : && *pPos != nFragmentDelimiter)
961 : : {
962 : : EscapeType eEscapeType;
963 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
964 : : cEscapePrefix, eMechanism,
965 [ + - ]: 260 : eCharset, eEscapeType);
966 : : appendUCS4(aSynAuthority, nUTF32, eEscapeType, bOctets,
967 : : PART_AUTHORITY, cEscapePrefix, eCharset,
968 [ + - ]: 260 : false);
969 : : }
970 : : }
971 [ - + ]: 91 : if (aSynAuthority.getLength() == 0)
972 : : {
973 [ # # ]: 0 : setInvalid();
974 : 0 : return false;
975 : : }
976 : : m_aHost.set(aSynAbsURIRef,
977 : : aSynAuthority.makeStringAndClear(),
978 [ + - ][ + - ]: 91 : aSynAbsURIRef.getLength());
979 : : // misusing m_aHost to store the authority
980 [ - + ][ - + ]: 91 : break;
981 : : }
982 : :
983 : : case INET_PROT_FILE:
984 [ + + ]: 111419 : if (bSmart)
985 : : {
986 : : // The first of the following seven productions that
987 : : // matches the rest of the input string (and for which the
988 : : // appropriate style bit is set in eStyle, if applicable)
989 : : // determines the used notation. The productions use the
990 : : // auxiliary rules
991 : : //
992 : : // domain = label *("." label)
993 : : // label = alphanum [*(alphanum / "-") alphanum]
994 : : // alphanum = ALPHA / DIGIT
995 : : // IPv6reference = "[" IPv6address "]"
996 : : // IPv6address = hexpart [":" IPv4address]
997 : : // IPv4address = 1*3DIGIT 3("." 1*3DIGIT)
998 : : // hexpart = (hexseq ["::" [hexseq]]) / ("::" [hexseq])
999 : : // hexseq = hex4 *(":" hex4)
1000 : : // hex4 = 1*4HEXDIG
1001 : : // path = <any UCS4 character except "#">
1002 : : // UCS4 = <any UCS4 character>
1003 : :
1004 : : // 1st Production (URL):
1005 : : // "//" [domain / IPv6reference] ["/" *path]
1006 : : // ["#" *UCS4]
1007 : : // becomes
1008 : : // "file://" domain "/" *path ["#" *UCS4]
1009 [ + - ][ + + ]: 13147 : if (pEnd - pPos >= 2 && pPos[0] == '/' && pPos[1] == '/')
[ + + ]
1010 : : {
1011 : 12146 : sal_Unicode const * p1 = pPos + 2;
1012 [ + - ][ - + ]: 12146 : while (p1 != pEnd && *p1 != '/' &&
[ # # ][ - + ]
1013 : : *p1 != nFragmentDelimiter)
1014 : : {
1015 : 0 : ++p1;
1016 : : }
1017 [ + - ][ + - ]: 12146 : if (parseHostOrNetBiosName(
1018 : : pPos + 2, p1, bOctets, ENCODE_ALL,
1019 : 12146 : RTL_TEXTENCODING_DONTKNOW, true, NULL))
1020 : : {
1021 : : aSynAbsURIRef.
1022 [ + - ]: 12146 : appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
1023 : 12146 : pHostPortBegin = pPos + 2;
1024 : 12146 : pHostPortEnd = p1;
1025 : 12146 : pPos = p1;
1026 : 12146 : break;
1027 : : }
1028 : : }
1029 : :
1030 : : // 2nd Production (MS IE generated 1; FSYS_DOS only):
1031 : : // "//" ALPHA ":" ["/" *path] ["#" *UCS4]
1032 : : // becomes
1033 : : // "file:///" ALPHA ":" ["/" *path] ["#" *UCS4]
1034 : : // replacing "\" by "/" within <*path>
1035 : : // 3rd Production (MS IE generated 2; FSYS_DOS only):
1036 : : // "//" ALPHA ":" ["\" *path] ["#" *UCS4]
1037 : : // becomes
1038 : : // "file:///" ALPHA ":" ["/" *path] ["#" *UCS4]
1039 : : // replacing "\" by "/" within <*path>
1040 : : // 4th Production (misscounted slashes):
1041 : : // "//" *path ["#" *UCS4]
1042 : : // becomes
1043 : : // "file:///" *path ["#" *UCS4]
1044 [ + - ][ + + ]: 1001 : if (pEnd - pPos >= 2 && pPos[0] == '/' && pPos[1] == '/')
[ - + ]
1045 : : {
1046 : : aSynAbsURIRef.
1047 [ # # ]: 0 : appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
1048 : 0 : pPos += 2;
1049 : 0 : bSkippedInitialSlash = true;
1050 [ # # ]: 0 : if ((eStyle & FSYS_DOS) != 0
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1051 : : && pEnd - pPos >= 2
1052 : 0 : && INetMIME::isAlpha(pPos[0])
1053 : 0 : && pPos[1] == ':'
1054 : : && (pEnd - pPos == 2
1055 : 0 : || pPos[2] == '/' || pPos[2] == '\\'))
1056 : 0 : nAltSegmentDelimiter = '\\';
1057 : 0 : break;
1058 : : }
1059 : :
1060 : : // 5th Production (Unix):
1061 : : // "/" *path ["#" *UCS4]
1062 : : // becomes
1063 : : // "file:///" *path ["#" *UCS4]
1064 [ + - ][ + + ]: 1001 : if (pPos < pEnd && *pPos == '/')
1065 : : {
1066 : : aSynAbsURIRef.
1067 [ + - ]: 570 : appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
1068 : 570 : break;
1069 : : }
1070 : :
1071 : : // 6th Production (UNC; FSYS_DOS only):
1072 : : // "\\" domain ["\" *path] ["#" *UCS4]
1073 : : // becomes
1074 : : // "file://" domain "/" *path ["#" *UCS4]
1075 : : // replacing "\" by "/" within <*path>
1076 [ + - ][ + - ]: 431 : if (eStyle & FSYS_DOS
[ + + ][ + - ]
1077 : : && pEnd - pPos >= 2
1078 : 431 : && pPos[0] == '\\'
1079 : 2 : && pPos[1] == '\\')
1080 : : {
1081 : 2 : sal_Unicode const * p1 = pPos + 2;
1082 : 2 : sal_Unicode const * pe = p1;
1083 [ + - ][ + + ]: 24 : while (pe < pEnd && *pe != '\\' &&
[ + - ][ + + ]
1084 : : *pe != nFragmentDelimiter)
1085 : : {
1086 : 22 : ++pe;
1087 : : }
1088 [ - + ][ # # ]: 2 : if (
[ # # ][ + - ]
1089 : : parseHostOrNetBiosName(
1090 : : p1, pe, bOctets, ENCODE_ALL,
1091 [ + - ]: 2 : RTL_TEXTENCODING_DONTKNOW, true, NULL) ||
1092 [ # # ]: 0 : (scanDomain(p1, pe) > 0 && p1 == pe)
1093 : : )
1094 : : {
1095 : : aSynAbsURIRef.
1096 [ + - ]: 2 : appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
1097 : 2 : pHostPortBegin = pPos + 2;
1098 : 2 : pHostPortEnd = pe;
1099 : 2 : pPos = pe;
1100 : 2 : nSegmentDelimiter = '\\';
1101 : : break;
1102 : : }
1103 : : }
1104 : :
1105 : : // 7th Production (Unix-like DOS; FSYS_DOS only):
1106 : : // ALPHA ":" ["/" *path] ["#" *UCS4]
1107 : : // becomes
1108 : : // "file:///" ALPHA ":" ["/" *path] ["#" *UCS4]
1109 : : // replacing "\" by "/" within <*path>
1110 : : // 8th Production (DOS; FSYS_DOS only):
1111 : : // ALPHA ":" ["\" *path] ["#" *UCS4]
1112 : : // becomes
1113 : : // "file:///" ALPHA ":" ["/" *path] ["#" *UCS4]
1114 : : // replacing "\" by "/" within <*path>
1115 [ + - ]: 858 : if (eStyle & FSYS_DOS
[ + - + - ]
[ + + ][ + - ]
[ + + ][ + - ]
[ + + ]
1116 : : && pEnd - pPos >= 2
1117 : 429 : && INetMIME::isAlpha(pPos[0])
1118 : 429 : && pPos[1] == ':'
1119 : : && (pEnd - pPos == 2
1120 : 6 : || pPos[2] == '/'
1121 : 2 : || pPos[2] == '\\'))
1122 : : {
1123 : : aSynAbsURIRef.
1124 [ + - ]: 6 : appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
1125 : 6 : nAltSegmentDelimiter = '\\';
1126 : 6 : bSkippedInitialSlash = true;
1127 : 6 : break;
1128 : : }
1129 : :
1130 : : // 9th Production (any):
1131 : : // *path ["#" *UCS4]
1132 : : // becomes
1133 : : // "file:///" *path ["#" *UCS4]
1134 : : // replacing the delimiter by "/" within <*path>. The
1135 : : // delimiter is that character from the set { "/", "\",
1136 : : // ":" } which appears most often in <*path> (if FSYS_UNX
1137 : : // is not among the style bits, "/" is removed from the
1138 : : // set; if FSYS_DOS is not among the style bits, "\" is
1139 : : // removed from the set; if FSYS_MAC is not among the
1140 : : // style bits, ":" is removed from the set). If two or
1141 : : // more characters appear the same number of times, the
1142 : : // character mentioned first in that set is chosen. If
1143 : : // the first character of <*path> is the delimiter, that
1144 : : // character is not copied.
1145 [ + - ]: 423 : if (eStyle & (FSYS_UNX | FSYS_DOS | FSYS_MAC))
1146 : : {
1147 : : aSynAbsURIRef.
1148 [ + - ]: 423 : appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
1149 [ + - - - ]: 423 : switch (guessFSysStyleByCounting(pPos, pEnd, eStyle))
1150 : : {
1151 : : case FSYS_UNX:
1152 : 423 : nSegmentDelimiter = '/';
1153 : 423 : break;
1154 : :
1155 : : case FSYS_DOS:
1156 : 0 : nSegmentDelimiter = '\\';
1157 : 0 : break;
1158 : :
1159 : : case FSYS_MAC:
1160 : 0 : nSegmentDelimiter = ':';
1161 : 0 : break;
1162 : :
1163 : : default:
1164 : : OSL_FAIL(
1165 : : "INetURLObject::setAbsURIRef():"
1166 : : " Bad guessFSysStyleByCounting");
1167 : 0 : break;
1168 : : }
1169 : : bSkippedInitialSlash
1170 [ + - ][ + - ]: 423 : = pPos != pEnd && *pPos != nSegmentDelimiter;
1171 : 423 : break;
1172 : : }
1173 : : }
1174 : : default:
1175 : : {
1176 : : // For INET_PROT_FILE, allow an empty authority ("//") to be
1177 : : // missing if the following path starts with an explicit "/"
1178 : : // (Java is notorious in generating such file URLs, so be
1179 : : // liberal here):
1180 [ + - ][ + + ]: 98456 : if (pEnd - pPos >= 2 && pPos[0] == '/' && pPos[1] == '/')
[ + - ]
1181 : 98423 : pPos += 2;
1182 [ - + ][ # # ]: 33 : else if (!bSmart
1183 : : && !(m_eScheme == INET_PROT_FILE
1184 [ # # ][ # # ]: 0 : && pPos != pEnd && *pPos == '/'))
1185 : : {
1186 [ # # ]: 0 : setInvalid();
1187 : 0 : return false;
1188 : : }
1189 [ + - ]: 98456 : aSynAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
1190 : :
1191 : 98456 : sal_Unicode const * pAuthority = pPos;
1192 [ + + ]: 98456 : sal_uInt32 c = getSchemeInfo().m_bQuery ? '?' : 0x80000000;
1193 [ + + ][ + + ]: 101500 : while (pPos < pEnd && *pPos != '/' && *pPos != c
[ + - ][ + - ]
[ + + ]
1194 : : && *pPos != nFragmentDelimiter)
1195 : 3044 : ++pPos;
1196 [ + + ]: 98456 : if (getSchemeInfo().m_bUser)
1197 [ + - ]: 13 : if (getSchemeInfo().m_bHost)
1198 : : {
1199 : 13 : sal_Unicode const * p1 = pAuthority;
1200 [ + + ][ + + ]: 150 : while (p1 < pPos && *p1 != '@')
[ + + ]
1201 : 137 : ++p1;
1202 [ + + ]: 13 : if (p1 == pPos)
1203 : : {
1204 : 11 : pHostPortBegin = pAuthority;
1205 : 11 : pHostPortEnd = pPos;
1206 : : }
1207 : : else
1208 : : {
1209 : 2 : pUserInfoBegin = pAuthority;
1210 : 2 : pUserInfoEnd = p1;
1211 : 2 : pHostPortBegin = p1 + 1;
1212 : 2 : pHostPortEnd = pPos;
1213 : : }
1214 : : }
1215 : : else
1216 : : {
1217 : 0 : pUserInfoBegin = pAuthority;
1218 : 0 : pUserInfoEnd = pPos;
1219 : : }
1220 [ + - ]: 98443 : else if (getSchemeInfo().m_bHost)
1221 : : {
1222 : 98443 : pHostPortBegin = pAuthority;
1223 : 98443 : pHostPortEnd = pPos;
1224 : : }
1225 [ # # ]: 0 : else if (pPos != pAuthority)
1226 : : {
1227 [ # # ]: 0 : setInvalid();
1228 : 0 : return false;
1229 : : }
1230 : 98456 : break;
1231 : : }
1232 : : }
1233 : :
1234 [ + + ]: 112006 : if (pUserInfoBegin)
1235 : : {
1236 : : Part ePart = m_eScheme == INET_PROT_IMAP ?
1237 : : PART_IMAP_ACHAR :
1238 : : m_eScheme == INET_PROT_VIM ?
1239 : : PART_VIM :
1240 [ + - ][ - + ]: 2 : PART_USER_PASSWORD;
1241 : 2 : bool bSupportsPassword = getSchemeInfo().m_bPassword;
1242 : : bool bSupportsAuth
1243 [ # # ][ - + ]: 2 : = !bSupportsPassword && getSchemeInfo().m_bAuth;
1244 : 2 : bool bHasAuth = false;
1245 : 2 : rtl::OUStringBuffer aSynUser;
1246 : 2 : sal_Unicode const * p1 = pUserInfoBegin;
1247 [ + + ]: 28 : while (p1 < pUserInfoEnd)
1248 : : {
1249 : : EscapeType eEscapeType;
1250 : : sal_uInt32 nUTF32 = getUTF32(p1, pUserInfoEnd, bOctets,
1251 : : cEscapePrefix, eMechanism,
1252 [ + - ]: 26 : eCharset, eEscapeType);
1253 [ + - ]: 26 : if (eEscapeType == ESCAPE_NO)
1254 : : {
1255 [ - + ][ # # ]: 26 : if (nUTF32 == ':' && bSupportsPassword)
1256 : : {
1257 : 0 : bHasAuth = true;
1258 : : break;
1259 : : }
1260 [ - + ][ # # ]: 26 : else if (nUTF32 == ';' && bSupportsAuth
[ # # ][ # # ]
[ - + ]
1261 : : && pUserInfoEnd - p1
1262 : : > RTL_CONSTASCII_LENGTH("auth=")
1263 : : && INetMIME::equalIgnoreCase(
1264 : : p1,
1265 : : p1 + RTL_CONSTASCII_LENGTH("auth="),
1266 [ # # ]: 0 : "auth="))
1267 : : {
1268 : 0 : p1 += RTL_CONSTASCII_LENGTH("auth=");
1269 : 0 : bHasAuth = true;
1270 : : break;
1271 : : }
1272 : : }
1273 : : appendUCS4(aSynUser, nUTF32, eEscapeType, bOctets, ePart,
1274 [ + - ]: 26 : cEscapePrefix, eCharset, false);
1275 : : }
1276 : : m_aUser.set(aSynAbsURIRef, aSynUser.makeStringAndClear(),
1277 [ + - ][ + - ]: 2 : aSynAbsURIRef.getLength());
1278 [ - + ]: 2 : if (bHasAuth)
1279 : : {
1280 [ # # ]: 0 : if (bSupportsPassword)
1281 : : {
1282 [ # # ]: 0 : aSynAbsURIRef.append(sal_Unicode(':'));
1283 : 0 : rtl::OUStringBuffer aSynAuth;
1284 [ # # ]: 0 : while (p1 < pUserInfoEnd)
1285 : : {
1286 : : EscapeType eEscapeType;
1287 : : sal_uInt32 nUTF32 = getUTF32(p1, pUserInfoEnd, bOctets,
1288 : : cEscapePrefix,
1289 : : eMechanism, eCharset,
1290 [ # # ]: 0 : eEscapeType);
1291 : : appendUCS4(aSynAuth, nUTF32, eEscapeType, bOctets,
1292 [ # # ]: 0 : ePart, cEscapePrefix, eCharset, false);
1293 : : }
1294 : : m_aAuth.set(aSynAbsURIRef, aSynAuth.makeStringAndClear(),
1295 [ # # ][ # # ]: 0 : aSynAbsURIRef.getLength());
1296 : : }
1297 : : else
1298 : : {
1299 : : aSynAbsURIRef.
1300 [ # # ]: 0 : appendAscii(RTL_CONSTASCII_STRINGPARAM(";AUTH="));
1301 : 0 : rtl::OUStringBuffer aSynAuth;
1302 [ # # ]: 0 : while (p1 < pUserInfoEnd)
1303 : : {
1304 : : EscapeType eEscapeType;
1305 : : sal_uInt32 nUTF32 = getUTF32(p1, pUserInfoEnd, bOctets,
1306 : : cEscapePrefix,
1307 : : eMechanism, eCharset,
1308 [ # # ]: 0 : eEscapeType);
1309 [ # # ][ # # ]: 0 : if (!INetMIME::isIMAPAtomChar(nUTF32))
1310 : : {
1311 [ # # ]: 0 : setInvalid();
1312 : 0 : return false;
1313 : : }
1314 : : appendUCS4(aSynAuth, nUTF32, eEscapeType, bOctets,
1315 [ # # ]: 0 : ePart, cEscapePrefix, eCharset, false);
1316 : : }
1317 : : m_aAuth.set(aSynAbsURIRef, aSynAuth.makeStringAndClear(),
1318 [ # # ][ # # ]: 0 : aSynAbsURIRef.getLength());
[ # # ]
1319 : : }
1320 : : }
1321 [ + - ]: 2 : if (pHostPortBegin)
1322 [ + - ][ + - ]: 2 : aSynAbsURIRef.append(sal_Unicode('@'));
1323 : : }
1324 : :
1325 [ + + ]: 112006 : if (pHostPortBegin)
1326 : : {
1327 : 110604 : sal_Unicode const * pPort = pHostPortEnd;
1328 [ + + ][ + - ]: 110604 : if ( getSchemeInfo().m_bPort && pHostPortBegin < pHostPortEnd )
[ + + ]
1329 : : {
1330 : 184 : sal_Unicode const * p1 = pHostPortEnd - 1;
1331 [ + - ][ + + ]: 214 : while (p1 > pHostPortBegin && INetMIME::isDigit(*p1))
[ + + ]
1332 : 30 : --p1;
1333 [ - + ]: 184 : if (*p1 == ':')
1334 : 0 : pPort = p1;
1335 : : }
1336 : 110604 : bool bNetBiosName = false;
1337 [ + + + ]: 110604 : switch (m_eScheme)
1338 : : {
1339 : : case INET_PROT_FILE:
1340 : : // If the host equals "LOCALHOST" (unencoded and ignoring
1341 : : // case), turn it into an empty host:
1342 [ + - ][ - + ]: 110420 : if (INetMIME::equalIgnoreCase(pHostPortBegin, pPort,
1343 : : "localhost"))
1344 : 0 : pHostPortBegin = pPort;
1345 : 110420 : bNetBiosName = true;
1346 : 110420 : break;
1347 : :
1348 : : case INET_PROT_LDAP:
1349 : : case INET_PROT_SMB:
1350 [ - + ][ # # ]: 5 : if (pHostPortBegin == pPort && pPort != pHostPortEnd)
1351 : : {
1352 [ # # ]: 0 : setInvalid();
1353 : 0 : return false;
1354 : : }
1355 : 5 : break;
1356 : : default:
1357 [ - + ]: 179 : if (pHostPortBegin == pPort)
1358 : : {
1359 [ # # ]: 0 : setInvalid();
1360 : 0 : return false;
1361 : : }
1362 : 179 : break;
1363 : : }
1364 : 110604 : rtl::OUStringBuffer aSynHost;
1365 [ + + ]: 110604 : if (!parseHostOrNetBiosName(
1366 : : pHostPortBegin, pPort, bOctets, eMechanism, eCharset,
1367 [ + - ]: 110604 : bNetBiosName, &aSynHost))
1368 : : {
1369 [ + - ]: 2 : setInvalid();
1370 : 2 : return false;
1371 : : }
1372 : : m_aHost.set(aSynAbsURIRef, aSynHost.makeStringAndClear(),
1373 [ + - ][ + - ]: 110602 : aSynAbsURIRef.getLength());
1374 [ - + ]: 110602 : if (pPort != pHostPortEnd)
1375 : : {
1376 [ # # ]: 0 : aSynAbsURIRef.append(sal_Unicode(':'));
1377 : : m_aPort.set(aSynAbsURIRef,
1378 : 0 : rtl::OUString(pPort + 1, pHostPortEnd - (pPort + 1)),
1379 [ # # ]: 110602 : aSynAbsURIRef.getLength());
1380 [ + + ]: 110604 : }
1381 : : }
1382 : : }
1383 : :
1384 : : // Parse <path>
1385 : 799162 : rtl::OUStringBuffer aSynPath;
1386 [ - + ]: 799162 : if (!parsePath(m_eScheme, &pPos, pEnd, bOctets, eMechanism, eCharset,
1387 : : bSkippedInitialSlash, nSegmentDelimiter,
1388 : : nAltSegmentDelimiter,
1389 : 799162 : getSchemeInfo().m_bQuery ? '?' : 0x80000000,
1390 [ + - ][ + + ]: 799162 : nFragmentDelimiter, aSynPath))
1391 : : {
1392 [ # # ]: 0 : setInvalid();
1393 : 0 : return false;
1394 : : }
1395 : : m_aPath.set(aSynAbsURIRef, aSynPath.makeStringAndClear(),
1396 [ + - ][ + - ]: 799162 : aSynAbsURIRef.getLength());
1397 : :
1398 : : // Parse ?<query>
1399 [ + + ][ + + ]: 799162 : if (getSchemeInfo().m_bQuery && pPos < pEnd && *pPos == '?')
[ + + ][ + + ]
1400 : : {
1401 [ + - ]: 4682 : aSynAbsURIRef.append(sal_Unicode('?'));
1402 : 4682 : rtl::OUStringBuffer aSynQuery;
1403 [ + + ][ + - ]: 54546 : for (++pPos; pPos < pEnd && *pPos != nFragmentDelimiter;)
[ + + ]
1404 : : {
1405 : : EscapeType eEscapeType;
1406 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets, cEscapePrefix,
1407 [ + - ]: 49864 : eMechanism, eCharset, eEscapeType);
1408 : : appendUCS4(aSynQuery, nUTF32, eEscapeType, bOctets,
1409 [ + - ]: 49864 : PART_URIC, cEscapePrefix, eCharset, true);
1410 : : }
1411 : : m_aQuery.set(aSynAbsURIRef, aSynQuery.makeStringAndClear(),
1412 [ + - ][ + - ]: 4682 : aSynAbsURIRef.getLength());
1413 : : }
1414 : :
1415 : : // Parse #<fragment>
1416 [ + + ][ + - ]: 799162 : if (pPos < pEnd && *pPos == nFragmentDelimiter)
1417 : : {
1418 [ + - ]: 32 : aSynAbsURIRef.append(sal_Unicode(nFragmentDelimiter));
1419 : 32 : rtl::OUStringBuffer aSynFragment;
1420 [ + + ]: 66 : for (++pPos; pPos < pEnd;)
1421 : : {
1422 : : EscapeType eEscapeType;
1423 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets, cEscapePrefix,
1424 [ + - ]: 34 : eMechanism, eCharset, eEscapeType);
1425 : : appendUCS4(aSynFragment, nUTF32, eEscapeType, bOctets, PART_URIC,
1426 [ + - ]: 34 : cEscapePrefix, eCharset, true);
1427 : : }
1428 : : m_aFragment.set(aSynAbsURIRef, aSynFragment.makeStringAndClear(),
1429 [ + - ][ + - ]: 32 : aSynAbsURIRef.getLength());
1430 : : }
1431 : :
1432 [ - + ]: 799162 : if (pPos != pEnd)
1433 : : {
1434 [ # # ]: 0 : setInvalid();
1435 : 0 : return false;
1436 : : }
1437 : :
1438 [ + - ]: 799162 : m_aAbsURIRef = aSynAbsURIRef;
1439 : :
1440 : : // At this point references of type "\\server\paths" have
1441 : : // been converted to file:://server/path".
1442 : : #ifdef LINUX
1443 [ + + ][ + + ]: 799162 : if (m_eScheme==INET_PROT_FILE && !m_aHost.isEmpty()) {
[ + + ]
1444 : : // Change "file:://server/path" URIs to "smb:://server/path" on
1445 : : // Linux
1446 : : // Leave "file::path" URIs unchanged.
1447 [ + - ]: 27 : changeScheme(INET_PROT_SMB);
1448 : : }
1449 : : #endif
1450 : :
1451 : : #ifdef WIN
1452 : : if (m_eScheme==INET_PROT_SMB) {
1453 : : // Change "smb://server/path" URIs to "file://server/path"
1454 : : // URIs on Windows, since Windows doesn't understand the
1455 : : // SMB scheme.
1456 : : changeScheme(INET_PROT_FILE);
1457 : : }
1458 : : #endif
1459 : :
1460 : 826557 : return true;
1461 : : }
1462 : :
1463 : 27 : void INetURLObject::changeScheme(INetProtocol eTargetScheme) {
1464 [ + - ]: 27 : ::rtl::OUString aTmpStr=m_aAbsURIRef.makeStringAndClear();
1465 : 27 : int oldSchemeLen=strlen(getSchemeInfo().m_pScheme);
1466 : 27 : m_eScheme=eTargetScheme;
1467 : 27 : int newSchemeLen=strlen(getSchemeInfo().m_pScheme);
1468 [ + - ]: 27 : m_aAbsURIRef.appendAscii(getSchemeInfo().m_pScheme);
1469 [ + - ]: 27 : m_aAbsURIRef.append(aTmpStr.getStr()+oldSchemeLen);
1470 : 27 : int delta=newSchemeLen-oldSchemeLen;
1471 : 27 : m_aUser+=delta;
1472 : 27 : m_aAuth+=delta;
1473 : 27 : m_aHost+=delta;
1474 : 27 : m_aPort+=delta;
1475 : 27 : m_aPath+=delta;
1476 : 27 : m_aQuery+=delta;
1477 : 27 : m_aFragment+=delta;
1478 : 27 : }
1479 : :
1480 : 576 : bool INetURLObject::convertRelToAbs(rtl::OUString const & rTheRelURIRef,
1481 : : bool bOctets,
1482 : : INetURLObject & rTheAbsURIRef,
1483 : : bool & rWasAbsolute,
1484 : : EncodeMechanism eMechanism,
1485 : : rtl_TextEncoding eCharset,
1486 : : bool bIgnoreFragment, bool bSmart,
1487 : : bool bRelativeNonURIs, FSysStyle eStyle)
1488 : : const
1489 : : {
1490 : 576 : sal_Unicode const * p = rTheRelURIRef.getStr();
1491 : 576 : sal_Unicode const * pEnd = p + rTheRelURIRef.getLength();
1492 : :
1493 : 576 : sal_Unicode const * pPrefixBegin = p;
1494 : 576 : PrefixInfo const * pPrefix = getPrefix(pPrefixBegin, pEnd);
1495 : 576 : bool hasScheme = pPrefix != 0;
1496 [ + + ]: 576 : if (!hasScheme) {
1497 : 184 : pPrefixBegin = p;
1498 : 184 : hasScheme = !parseScheme(&pPrefixBegin, pEnd, '#').isEmpty();
1499 : : }
1500 : :
1501 : 576 : sal_uInt32 nSegmentDelimiter = '/';
1502 : : sal_uInt32 nQueryDelimiter
1503 [ + + ][ - + ]: 576 : = !bSmart || getSchemeInfo().m_bQuery ? '?' : 0x80000000;
1504 : 576 : sal_uInt32 nFragmentDelimiter = '#';
1505 : 576 : Part ePart = PART_VISIBLE;
1506 : :
1507 [ + + ][ - + ]: 576 : if (!hasScheme && bSmart)
1508 : : {
1509 : : // If the input matches any of the following productions (for which
1510 : : // the appropriate style bit is set in eStyle), it is assumed to be an
1511 : : // absolute file system path, rather than a relative URI reference.
1512 : : // (This is only a subset of the productions used for scheme detection
1513 : : // in INetURLObject::setAbsURIRef(), because most of those productions
1514 : : // interfere with the syntax of relative URI references.) The
1515 : : // productions use the auxiliary rules
1516 : : //
1517 : : // domain = label *("." label)
1518 : : // label = alphanum [*(alphanum / "-") alphanum]
1519 : : // alphanum = ALPHA / DIGIT
1520 : : // UCS4 = <any UCS4 character>
1521 : : //
1522 : : // 1st Production (UNC file; FSYS_DOS only):
1523 : : // "\\" domain ["\" *UCS4]
1524 : : // 2nd Production (Unix-like DOS file; FSYS_DOS only):
1525 : : // ALPHA ":" ["/" *UCS4]
1526 : : // 3rd Production (DOS file; FSYS_DOS only):
1527 : : // ALPHA ":" ["\" *UCS4]
1528 [ # # ]: 0 : if (eStyle & FSYS_DOS)
1529 : : {
1530 : 0 : bool bFSys = false;
1531 : 0 : sal_Unicode const * q = p;
1532 [ # # # # ]: 0 : if (pEnd - q >= 2
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1533 : 0 : && INetMIME::isAlpha(q[0])
1534 : 0 : && q[1] == ':'
1535 : 0 : && (pEnd - q == 2 || q[2] == '/' || q[2] == '\\'))
1536 : 0 : bFSys = true; // 2nd, 3rd
1537 [ # # ][ # # ]: 0 : else if (pEnd - q >= 2 && q[0] == '\\' && q[1] == '\\')
[ # # ]
1538 : : {
1539 : 0 : q += 2;
1540 : : sal_Int32 n = rtl_ustr_indexOfChar_WithLength(
1541 : 0 : q, pEnd - q, '\\');
1542 [ # # ]: 0 : sal_Unicode const * qe = n == -1 ? pEnd : q + n;
1543 [ # # ][ # # ]: 0 : if (parseHostOrNetBiosName(
1544 : : q, qe, bOctets, ENCODE_ALL, RTL_TEXTENCODING_DONTKNOW,
1545 : 0 : true, NULL))
1546 : : {
1547 : 0 : bFSys = true; // 1st
1548 : : }
1549 : : }
1550 [ # # ]: 0 : if (bFSys)
1551 : : {
1552 [ # # ]: 0 : INetURLObject aNewURI;
1553 : : aNewURI.setAbsURIRef(rTheRelURIRef, bOctets, eMechanism,
1554 [ # # ]: 0 : eCharset, true, eStyle);
1555 [ # # ]: 0 : if (!aNewURI.HasError())
1556 : : {
1557 [ # # ]: 0 : rTheAbsURIRef = aNewURI;
1558 : 0 : rWasAbsolute = true;
1559 : 0 : return true;
1560 [ # # ][ # # ]: 0 : }
1561 : : }
1562 : : }
1563 : :
1564 : : // When the base URL is a file URL, accept relative file system paths
1565 : : // using "\" or ":" as delimiter (and ignoring URI conventions for "%"
1566 : : // and "#"), as well as relative URIs using "/" as delimiter:
1567 [ # # ]: 0 : if (m_eScheme == INET_PROT_FILE)
1568 [ # # # # ]: 0 : switch (guessFSysStyleByCounting(p, pEnd, eStyle))
1569 : : {
1570 : : case FSYS_UNX:
1571 : 0 : nSegmentDelimiter = '/';
1572 : 0 : break;
1573 : :
1574 : : case FSYS_DOS:
1575 : 0 : nSegmentDelimiter = '\\';
1576 : 0 : bRelativeNonURIs = true;
1577 : 0 : break;
1578 : :
1579 : : case FSYS_MAC:
1580 : 0 : nSegmentDelimiter = ':';
1581 : 0 : bRelativeNonURIs = true;
1582 : 0 : break;
1583 : :
1584 : : default:
1585 : : OSL_FAIL("INetURLObject::convertRelToAbs():"
1586 : : " Bad guessFSysStyleByCounting");
1587 : 0 : break;
1588 : : }
1589 : :
1590 [ # # ]: 0 : if (bRelativeNonURIs)
1591 : : {
1592 : 0 : eMechanism = ENCODE_ALL;
1593 : 0 : nQueryDelimiter = 0x80000000;
1594 : 0 : nFragmentDelimiter = 0x80000000;
1595 : 0 : ePart = PART_VISIBLE_NONSPECIAL;
1596 : : }
1597 : : }
1598 : :
1599 : : // If the relative URI has the same scheme as the base URI, and that
1600 : : // scheme is hierarchical, then ignore its presence in the relative
1601 : : // URI in order to be backward compatible (cf. RFC 2396 section 5.2
1602 : : // step 3):
1603 [ + + ]: 951 : if (pPrefix && pPrefix->m_eScheme == m_eScheme
[ + + + - ]
[ + + ]
1604 : 375 : && getSchemeInfo().m_bHierarchical)
1605 : : {
1606 : 375 : hasScheme = false;
1607 [ + - ][ + + ]: 1875 : while (p != pEnd && *p++ != ':') ;
[ + + ]
1608 : : }
1609 : 576 : rWasAbsolute = hasScheme;
1610 : :
1611 : : // Fast solution for non-relative URIs:
1612 [ + + ]: 576 : if (hasScheme)
1613 : : {
1614 [ + - ]: 173 : INetURLObject aNewURI(rTheRelURIRef, eMechanism, eCharset);
1615 [ - + ]: 173 : if (aNewURI.HasError())
1616 : : {
1617 : 0 : rWasAbsolute = false;
1618 : 0 : return false;
1619 : : }
1620 : :
1621 [ - + ]: 173 : if (bIgnoreFragment)
1622 [ # # ]: 0 : aNewURI.clearFragment();
1623 [ + - ]: 173 : rTheAbsURIRef = aNewURI;
1624 [ + - ]: 173 : return true;
1625 : : }
1626 : :
1627 : : enum State { STATE_AUTH, STATE_ABS_PATH, STATE_REL_PATH, STATE_FRAGMENT,
1628 : : STATE_DONE };
1629 : :
1630 : 403 : rtl::OUStringBuffer aSynAbsURIRef;
1631 : : // make sure that the scheme is copied for generic schemes: getSchemeInfo().m_pScheme
1632 : : // is empty ("") in that case, so take the scheme from m_aAbsURIRef
1633 [ + - ]: 403 : if (m_eScheme != INET_PROT_GENERIC)
1634 : : {
1635 [ + - ]: 403 : aSynAbsURIRef.appendAscii(getSchemeInfo().m_pScheme);
1636 : : }
1637 : : else
1638 : : {
1639 : : sal_Unicode const * pSchemeBegin
1640 : 0 : = m_aAbsURIRef.getStr();
1641 : 0 : sal_Unicode const * pSchemeEnd = pSchemeBegin;
1642 [ # # ]: 0 : while (pSchemeEnd[0] != ':')
1643 : : {
1644 : 0 : ++pSchemeEnd;
1645 : : }
1646 [ # # ]: 0 : aSynAbsURIRef.append(pSchemeBegin, pSchemeEnd - pSchemeBegin);
1647 : : }
1648 [ + - ]: 403 : aSynAbsURIRef.append(sal_Unicode(':'));
1649 : :
1650 : 403 : sal_Char cEscapePrefix = getEscapePrefix();
1651 : :
1652 : 403 : State eState = STATE_AUTH;
1653 : 403 : bool bSameDoc = true;
1654 : :
1655 [ + + ]: 403 : if (getSchemeInfo().m_bAuthority)
1656 : : {
1657 [ + - ][ + + ]: 399 : if (pEnd - p >= 2 && p[0] == '/' && p[1] == '/')
[ + - ]
1658 : : {
1659 [ + - ]: 375 : aSynAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
1660 : 375 : p += 2;
1661 : 375 : eState = STATE_ABS_PATH;
1662 : 375 : bSameDoc = false;
1663 [ + - ]: 375 : while (p != pEnd)
1664 : : {
1665 : : EscapeType eEscapeType;
1666 : : sal_uInt32 nUTF32
1667 : : = getUTF32(p, pEnd, bOctets, cEscapePrefix, eMechanism,
1668 [ + - ]: 375 : eCharset, eEscapeType);
1669 [ + - ]: 375 : if (eEscapeType == ESCAPE_NO)
1670 : : {
1671 [ - + ]: 375 : if (nUTF32 == nSegmentDelimiter)
1672 : : break;
1673 [ # # ]: 0 : else if (nUTF32 == nFragmentDelimiter)
1674 : : {
1675 : 0 : eState = STATE_FRAGMENT;
1676 : : break;
1677 : : }
1678 : : }
1679 : : appendUCS4(aSynAbsURIRef, nUTF32, eEscapeType, bOctets,
1680 [ # # ]: 375 : PART_VISIBLE, cEscapePrefix, eCharset, true);
1681 : 375 : }
1682 : : }
1683 : : else
1684 : : {
1685 [ + - ]: 24 : SubString aAuthority(getAuthority());
1686 : 24 : aSynAbsURIRef.append(m_aAbsURIRef.getStr()
1687 : 24 : + aAuthority.getBegin(),
1688 [ + - ]: 423 : aAuthority.getLength());
1689 : : }
1690 : : }
1691 : :
1692 [ + + ]: 403 : if (eState == STATE_AUTH)
1693 : : {
1694 [ - + ]: 28 : if (p == pEnd)
1695 : 0 : eState = STATE_DONE;
1696 [ - + ]: 28 : else if (*p == nFragmentDelimiter)
1697 : : {
1698 : 0 : ++p;
1699 : 0 : eState = STATE_FRAGMENT;
1700 : : }
1701 [ + + ]: 28 : else if (*p == nSegmentDelimiter)
1702 : : {
1703 : 2 : ++p;
1704 : 2 : eState = STATE_ABS_PATH;
1705 : 2 : bSameDoc = false;
1706 : : }
1707 : : else
1708 : : {
1709 : 26 : eState = STATE_REL_PATH;
1710 : 26 : bSameDoc = false;
1711 : : }
1712 : : }
1713 : :
1714 [ + + ]: 403 : if (eState == STATE_ABS_PATH)
1715 : : {
1716 [ + - ]: 377 : aSynAbsURIRef.append(sal_Unicode('/'));
1717 : 377 : eState = STATE_DONE;
1718 [ + + ]: 19989 : while (p != pEnd)
1719 : : {
1720 : : EscapeType eEscapeType;
1721 : : sal_uInt32 nUTF32
1722 : : = getUTF32(p, pEnd, bOctets, cEscapePrefix, eMechanism,
1723 [ + - ]: 19612 : eCharset, eEscapeType);
1724 [ + - ]: 19612 : if (eEscapeType == ESCAPE_NO)
1725 : : {
1726 [ - + ]: 19612 : if (nUTF32 == nFragmentDelimiter)
1727 : : {
1728 : 0 : eState = STATE_FRAGMENT;
1729 : : break;
1730 : : }
1731 [ + + ]: 19612 : else if (nUTF32 == nSegmentDelimiter)
1732 : 2126 : nUTF32 = '/';
1733 : : }
1734 : : appendUCS4(aSynAbsURIRef, nUTF32, eEscapeType, bOctets, ePart,
1735 [ + - ]: 19612 : cEscapePrefix, eCharset, true);
1736 : : }
1737 : : }
1738 [ + - ]: 26 : else if (eState == STATE_REL_PATH)
1739 : : {
1740 [ + + ]: 26 : if (!getSchemeInfo().m_bHierarchical)
1741 : : {
1742 : : // Detect cases where a relative input could not be made absolute
1743 : : // because the given base URL is broken (most probably because it is
1744 : : // empty):
1745 : : OSL_ASSERT(!HasError());
1746 : 2 : rWasAbsolute = false;
1747 : 2 : return false;
1748 : : }
1749 : :
1750 : : sal_Unicode const * pBasePathBegin
1751 : 24 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
1752 : : sal_Unicode const * pBasePathEnd
1753 : 24 : = pBasePathBegin + m_aPath.getLength();
1754 [ + - ]: 228 : while (pBasePathEnd != pBasePathBegin)
1755 [ + + ]: 228 : if (*(--pBasePathEnd) == '/')
1756 : : {
1757 : 24 : ++pBasePathEnd;
1758 : 24 : break;
1759 : : }
1760 : :
1761 : 24 : sal_Int32 nPathBegin = aSynAbsURIRef.getLength();
1762 [ + - ]: 24 : aSynAbsURIRef.append(pBasePathBegin, pBasePathEnd - pBasePathBegin);
1763 : : DBG_ASSERT(aSynAbsURIRef.getLength() > nPathBegin
1764 : : && aSynAbsURIRef[aSynAbsURIRef.getLength() - 1] == '/',
1765 : : "INetURLObject::convertRelToAbs(): Bad base path");
1766 : :
1767 [ + + ][ + - ]: 122 : while (p != pEnd && *p != nQueryDelimiter && *p != nFragmentDelimiter)
[ + - ][ + + ]
1768 : : {
1769 [ + + ]: 98 : if (*p == '.')
1770 : : {
1771 [ + + ][ + - ]: 64 : if (pEnd - p == 1
[ + - ][ - + ]
1772 : 62 : || p[1] == nSegmentDelimiter
1773 : 62 : || p[1] == nQueryDelimiter
1774 : 62 : || p[1] == nFragmentDelimiter)
1775 : : {
1776 : 2 : ++p;
1777 [ - + ][ # # ]: 2 : if (p != pEnd && *p == nSegmentDelimiter)
1778 : 0 : ++p;
1779 : 2 : continue;
1780 : : }
1781 [ + - ][ + - ]: 124 : else if (pEnd - p >= 2
[ + - ][ - + ]
[ # # ]
[ # # + - ]
[ + - ]
1782 : 62 : && p[1] == '.'
1783 : : && (pEnd - p == 2
1784 : 62 : || p[2] == nSegmentDelimiter
1785 : 0 : || p[2] == nQueryDelimiter
1786 : 0 : || p[2] == nFragmentDelimiter)
1787 : 62 : && aSynAbsURIRef.getLength() - nPathBegin > 1)
1788 : : {
1789 : 62 : p += 2;
1790 [ + - ][ + - ]: 62 : if (p != pEnd && *p == nSegmentDelimiter)
1791 : 62 : ++p;
1792 : :
1793 : 62 : sal_Int32 i = aSynAbsURIRef.getLength() - 2;
1794 [ + + ][ + + ]: 636 : while (i > nPathBegin && aSynAbsURIRef[i] != '/')
[ + + ]
1795 : 574 : --i;
1796 [ + - ]: 62 : aSynAbsURIRef.setLength(i + 1);
1797 : : DBG_ASSERT(
1798 : : aSynAbsURIRef.getLength() > nPathBegin
1799 : : && aSynAbsURIRef[aSynAbsURIRef.getLength() - 1] == '/',
1800 : : "INetURLObject::convertRelToAbs(): Bad base path");
1801 : 62 : continue;
1802 : : }
1803 : : }
1804 : :
1805 [ + + ][ + + ]: 394 : while (p != pEnd
[ + - ][ + - ]
[ + + ]
1806 : : && *p != nSegmentDelimiter
1807 : : && *p != nQueryDelimiter
1808 : : && *p != nFragmentDelimiter)
1809 : : {
1810 : : EscapeType eEscapeType;
1811 : : sal_uInt32 nUTF32
1812 : : = getUTF32(p, pEnd, bOctets, cEscapePrefix, eMechanism,
1813 [ + - ]: 360 : eCharset, eEscapeType);
1814 : : appendUCS4(aSynAbsURIRef, nUTF32, eEscapeType, bOctets, ePart,
1815 [ + - ]: 360 : cEscapePrefix, eCharset, true);
1816 : : }
1817 [ + + ][ + - ]: 34 : if (p != pEnd && *p == nSegmentDelimiter)
1818 : : {
1819 [ + - ]: 12 : aSynAbsURIRef.append(sal_Unicode('/'));
1820 : 12 : ++p;
1821 : : }
1822 : : }
1823 : :
1824 [ - + ][ # # ]: 24 : while (p != pEnd && *p != nFragmentDelimiter)
[ - + ]
1825 : : {
1826 : : EscapeType eEscapeType;
1827 : : sal_uInt32 nUTF32
1828 : : = getUTF32(p, pEnd, bOctets, cEscapePrefix, eMechanism,
1829 [ # # ]: 0 : eCharset, eEscapeType);
1830 : : appendUCS4(aSynAbsURIRef, nUTF32, eEscapeType, bOctets, ePart,
1831 [ # # ]: 0 : cEscapePrefix, eCharset, true);
1832 : : }
1833 : :
1834 [ + - ]: 24 : if (p == pEnd)
1835 : 24 : eState = STATE_DONE;
1836 : : else
1837 : : {
1838 : 0 : ++p;
1839 : 0 : eState = STATE_FRAGMENT;
1840 : : }
1841 : : }
1842 [ # # ]: 0 : else if (bSameDoc)
1843 : : {
1844 : 0 : aSynAbsURIRef.append(m_aAbsURIRef.getStr() + m_aPath.getBegin(),
1845 [ # # ]: 0 : m_aPath.getLength());
1846 [ # # ]: 0 : if (m_aQuery.isPresent())
1847 : 0 : aSynAbsURIRef.append(m_aAbsURIRef.getStr()
1848 : 0 : + m_aQuery.getBegin() - 1,
1849 [ # # ]: 0 : m_aQuery.getLength() + 1);
1850 : : }
1851 : :
1852 [ - + ][ # # ]: 401 : if (eState == STATE_FRAGMENT && !bIgnoreFragment)
1853 : : {
1854 [ # # ]: 0 : aSynAbsURIRef.append(sal_Unicode('#'));
1855 [ # # ]: 0 : while (p != pEnd)
1856 : : {
1857 : : EscapeType eEscapeType;
1858 : : sal_uInt32 nUTF32
1859 : : = getUTF32(p, pEnd, bOctets, cEscapePrefix, eMechanism,
1860 [ # # ]: 0 : eCharset, eEscapeType);
1861 : : appendUCS4(aSynAbsURIRef, nUTF32, eEscapeType, bOctets,
1862 [ # # ]: 0 : PART_VISIBLE, cEscapePrefix, eCharset, true);
1863 : : }
1864 : : }
1865 : :
1866 [ + - ][ + - ]: 401 : INetURLObject aNewURI(aSynAbsURIRef.makeStringAndClear());
1867 [ + + ]: 401 : if (aNewURI.HasError())
1868 : : {
1869 : : // Detect cases where a relative input could not be made absolute
1870 : : // because the given base URL is broken (most probably because it is
1871 : : // empty):
1872 : : OSL_ASSERT(!HasError());
1873 : 2 : rWasAbsolute = false;
1874 : 2 : return false;
1875 : : }
1876 : :
1877 [ + - ]: 399 : rTheAbsURIRef = aNewURI;
1878 [ + - ]: 576 : return true;
1879 : : }
1880 : :
1881 : 174 : bool INetURLObject::convertAbsToRel(rtl::OUString const & rTheAbsURIRef,
1882 : : bool bOctets, rtl::OUString & rTheRelURIRef,
1883 : : EncodeMechanism eEncodeMechanism,
1884 : : DecodeMechanism eDecodeMechanism,
1885 : : rtl_TextEncoding eCharset,
1886 : : FSysStyle eStyle) const
1887 : : {
1888 : : // Check for hierarchical base URL:
1889 [ - + ]: 174 : if (!getSchemeInfo().m_bHierarchical)
1890 : : {
1891 : : rTheRelURIRef
1892 : : = decode(rTheAbsURIRef,
1893 [ # # ]: 0 : getEscapePrefix(CompareProtocolScheme(rTheAbsURIRef)),
1894 [ # # ]: 0 : eDecodeMechanism, eCharset);
1895 : 0 : return false;
1896 : : }
1897 : :
1898 : : // Convert the input (absolute or relative URI ref) to an absolute URI
1899 : : // ref:
1900 [ + - ]: 174 : INetURLObject aSubject;
1901 : : bool bWasAbsolute;
1902 [ - + ]: 174 : if (!convertRelToAbs(rTheAbsURIRef, bOctets, aSubject, bWasAbsolute,
1903 : : eEncodeMechanism, eCharset, false, false, false,
1904 [ + - ]: 174 : eStyle))
1905 : : {
1906 : : rTheRelURIRef
1907 : : = decode(rTheAbsURIRef,
1908 [ # # ]: 0 : getEscapePrefix(CompareProtocolScheme(rTheAbsURIRef)),
1909 [ # # ]: 0 : eDecodeMechanism, eCharset);
1910 : 0 : return false;
1911 : : }
1912 : :
1913 : : // Check for differing scheme or authority parts:
1914 [ + - ][ + - ]: 870 : if ((m_aScheme.compare(
[ + - ][ + - ]
[ - + ][ - + ]
1915 [ + - ]: 174 : aSubject.m_aScheme, m_aAbsURIRef, aSubject.m_aAbsURIRef)
1916 : : != 0)
1917 : : || (m_aUser.compare(
1918 [ + - ]: 174 : aSubject.m_aUser, m_aAbsURIRef, aSubject.m_aAbsURIRef)
1919 : : != 0)
1920 : : || (m_aAuth.compare(
1921 [ + - ]: 174 : aSubject.m_aAuth, m_aAbsURIRef, aSubject.m_aAbsURIRef)
1922 : : != 0)
1923 : : || (m_aHost.compare(
1924 [ + - ]: 174 : aSubject.m_aHost, m_aAbsURIRef, aSubject.m_aAbsURIRef)
1925 : : != 0)
1926 : : || (m_aPort.compare(
1927 [ + - ]: 174 : aSubject.m_aPort, m_aAbsURIRef, aSubject.m_aAbsURIRef)
1928 : : != 0))
1929 : : {
1930 [ # # ]: 0 : rTheRelURIRef = aSubject.GetMainURL(eDecodeMechanism, eCharset);
1931 : 0 : return false;
1932 : : }
1933 : :
1934 : : sal_Unicode const * pBasePathBegin
1935 : 174 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
1936 : 174 : sal_Unicode const * pBasePathEnd = pBasePathBegin + m_aPath.getLength();
1937 : : sal_Unicode const * pSubjectPathBegin
1938 : 174 : = aSubject.m_aAbsURIRef.getStr() + aSubject.m_aPath.getBegin();
1939 : : sal_Unicode const * pSubjectPathEnd
1940 : 174 : = pSubjectPathBegin + aSubject.m_aPath.getLength();
1941 : :
1942 : : // Make nMatch point past the last matching slash, or past the end of the
1943 : : // paths, in case they are equal:
1944 : 174 : sal_Unicode const * pSlash = 0;
1945 : 174 : sal_Unicode const * p1 = pBasePathBegin;
1946 : 174 : sal_Unicode const * p2 = pSubjectPathBegin;
1947 : 15310 : for (;;)
1948 : : {
1949 [ + - ][ + + ]: 15484 : if (p1 == pBasePathEnd || p2 == pSubjectPathEnd)
1950 : : {
1951 [ - + ][ # # ]: 168 : if (p1 == pBasePathEnd && p2 == pSubjectPathEnd)
1952 : 0 : pSlash = p1;
1953 : 168 : break;
1954 : : }
1955 : :
1956 : 15316 : sal_Unicode c = *p1++;
1957 [ + + ]: 15316 : if (c != *p2++)
1958 : 6 : break;
1959 [ + + ]: 15310 : if (c == '/')
1960 : 2022 : pSlash = p1;
1961 : : }
1962 [ - + ]: 174 : if (!pSlash)
1963 : : {
1964 : : // One of the paths does not start with '/':
1965 [ # # ]: 0 : rTheRelURIRef = aSubject.GetMainURL(eDecodeMechanism, eCharset);
1966 : 0 : return false;
1967 : : }
1968 : 174 : sal_Int32 nMatch = pSlash - pBasePathBegin;
1969 : :
1970 : : // If the two URLs are DOS file URLs starting with different volumes
1971 : : // (e.g., file:///a:/... and file:///b:/...), the subject is not made
1972 : : // relative (it could be, but some people do not like that):
1973 [ + - ][ + + : 180 : if (m_eScheme == INET_PROT_FILE
- + # # ]
[ - + ]
1974 : : && nMatch <= 1
1975 : 6 : && hasDosVolume(eStyle)
1976 : 0 : && aSubject.hasDosVolume(eStyle)) //TODO! ok to use eStyle for these?
1977 : : {
1978 [ # # ]: 0 : rTheRelURIRef = aSubject.GetMainURL(eDecodeMechanism, eCharset);
1979 : 0 : return false;
1980 : : }
1981 : :
1982 : : // For every slash in the base path after nMatch, a prefix of "../" is
1983 : : // added to the new relative URL (if the common prefix of the two paths is
1984 : : // only "/"---but see handling of file URLs above---, the complete subject
1985 : : // path could go into the new relative URL instead, but some people don't
1986 : : // like that):
1987 : 174 : rtl::OUStringBuffer aSynRelURIRef;
1988 [ + + ]: 6446 : for (sal_Unicode const * p = pBasePathBegin + nMatch; p != pBasePathEnd;
1989 : : ++p)
1990 : : {
1991 [ + + ]: 6272 : if (*p == '/')
1992 [ + - ]: 240 : aSynRelURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("../"));
1993 : : }
1994 : :
1995 : : // If the new relative URL would start with "//" (i.e., it would be
1996 : : // mistaken for a relative URL starting with an authority part), or if the
1997 : : // new relative URL would neither be empty nor start with <"/"> nor start
1998 : : // with <1*rseg> (i.e., it could be mistaken for an absolute URL starting
1999 : : // with a scheme part), then the new relative URL is prefixed with "./":
2000 [ - + ]: 174 : if (aSynRelURIRef.getLength() == 0)
2001 : : {
2002 [ # # ][ # # ]: 0 : if (pSubjectPathEnd - pSubjectPathBegin >= nMatch + 2
[ # # ]
2003 : 0 : && pSubjectPathBegin[nMatch] == '/'
2004 : 0 : && pSubjectPathBegin[nMatch + 1] == '/')
2005 : : {
2006 [ # # ]: 0 : aSynRelURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("./"));
2007 : : }
2008 : : else
2009 : : {
2010 [ # # ][ # # ]: 0 : for (sal_Unicode const * p = pSubjectPathBegin + nMatch;
[ # # ]
2011 : : p != pSubjectPathEnd && *p != '/'; ++p)
2012 : : {
2013 [ # # ]: 0 : if (mustEncode(*p, PART_REL_SEGMENT_EXTRA))
2014 : : {
2015 : : aSynRelURIRef.
2016 [ # # ]: 0 : appendAscii(RTL_CONSTASCII_STRINGPARAM("./"));
2017 : 0 : break;
2018 : : }
2019 : : }
2020 : : }
2021 : : }
2022 : :
2023 : : // The remainder of the subject path, starting at nMatch, is appended to
2024 : : // the new relative URL:
2025 : 174 : sal_Char cEscapePrefix = getEscapePrefix();
2026 : : aSynRelURIRef.append(decode(pSubjectPathBegin + nMatch, pSubjectPathEnd,
2027 [ + - ][ + - ]: 174 : cEscapePrefix, eDecodeMechanism, eCharset));
2028 : :
2029 : : // If the subject has defined query or fragment parts, they are appended
2030 : : // to the new relative URL:
2031 [ - + ]: 174 : if (aSubject.m_aQuery.isPresent())
2032 : : {
2033 [ # # ]: 0 : aSynRelURIRef.append(sal_Unicode('?'));
2034 : : aSynRelURIRef.append(aSubject.decode(aSubject.m_aQuery, cEscapePrefix,
2035 [ # # ][ # # ]: 0 : eDecodeMechanism, eCharset));
2036 : : }
2037 [ - + ]: 174 : if (aSubject.m_aFragment.isPresent())
2038 : : {
2039 [ # # ]: 0 : aSynRelURIRef.append(sal_Unicode('#'));
2040 : : aSynRelURIRef.append(aSubject.decode(aSubject.m_aFragment,
2041 [ # # ][ # # ]: 0 : cEscapePrefix, eDecodeMechanism, eCharset));
2042 : : }
2043 : :
2044 [ + - ]: 174 : rTheRelURIRef = aSynRelURIRef.makeStringAndClear();
2045 [ + - ]: 174 : return true;
2046 : : }
2047 : :
2048 : : // static
2049 : 0 : bool INetURLObject::convertIntToExt(rtl::OUString const & rTheIntURIRef,
2050 : : bool bOctets, rtl::OUString & rTheExtURIRef,
2051 : : DecodeMechanism eDecodeMechanism,
2052 : : rtl_TextEncoding eCharset)
2053 : : {
2054 : : sal_Char cEscapePrefix
2055 [ # # ]: 0 : = getEscapePrefix(CompareProtocolScheme(rTheIntURIRef));
2056 : : rtl::OUString aSynExtURIRef(encodeText(rTheIntURIRef, bOctets, PART_VISIBLE,
2057 : : cEscapePrefix, NOT_CANONIC, eCharset,
2058 [ # # ]: 0 : true));
2059 : 0 : sal_Unicode const * pBegin = aSynExtURIRef.getStr();
2060 : 0 : sal_Unicode const * pEnd = pBegin + aSynExtURIRef.getLength();
2061 : 0 : sal_Unicode const * p = pBegin;
2062 : 0 : PrefixInfo const * pPrefix = getPrefix(p, pEnd);
2063 [ # # ][ # # ]: 0 : bool bConvert = pPrefix && pPrefix->m_eKind == PrefixInfo::INTERNAL;
2064 [ # # ]: 0 : if (bConvert)
2065 : : {
2066 : : aSynExtURIRef =
2067 : : aSynExtURIRef.replaceAt(0, p - pBegin,
2068 : 0 : rtl::OUString::createFromAscii(pPrefix->m_pTranslatedPrefix));
2069 : : }
2070 : : rTheExtURIRef = decode(aSynExtURIRef, cEscapePrefix, eDecodeMechanism,
2071 [ # # ]: 0 : eCharset);
2072 : 0 : return bConvert;
2073 : : }
2074 : :
2075 : : // static
2076 : 0 : bool INetURLObject::convertExtToInt(rtl::OUString const & rTheExtURIRef,
2077 : : bool bOctets, rtl::OUString & rTheIntURIRef,
2078 : : DecodeMechanism eDecodeMechanism,
2079 : : rtl_TextEncoding eCharset)
2080 : : {
2081 : : sal_Char cEscapePrefix
2082 [ # # ]: 0 : = getEscapePrefix(CompareProtocolScheme(rTheExtURIRef));
2083 : : rtl::OUString aSynIntURIRef(encodeText(rTheExtURIRef, bOctets, PART_VISIBLE,
2084 : : cEscapePrefix, NOT_CANONIC, eCharset,
2085 [ # # ]: 0 : true));
2086 : 0 : sal_Unicode const * pBegin = aSynIntURIRef.getStr();
2087 : 0 : sal_Unicode const * pEnd = pBegin + aSynIntURIRef.getLength();
2088 : 0 : sal_Unicode const * p = pBegin;
2089 : 0 : PrefixInfo const * pPrefix = getPrefix(p, pEnd);
2090 [ # # ][ # # ]: 0 : bool bConvert = pPrefix && pPrefix->m_eKind == PrefixInfo::EXTERNAL;
2091 [ # # ]: 0 : if (bConvert)
2092 : : {
2093 : : aSynIntURIRef =
2094 : : aSynIntURIRef.replaceAt(0, p - pBegin,
2095 : 0 : rtl::OUString::createFromAscii(pPrefix->m_pTranslatedPrefix));
2096 : : }
2097 : : rTheIntURIRef = decode(aSynIntURIRef, cEscapePrefix, eDecodeMechanism,
2098 [ # # ]: 0 : eCharset);
2099 : 0 : return bConvert;
2100 : : }
2101 : :
2102 : : // static
2103 : 1381383 : INetURLObject::PrefixInfo const * INetURLObject::getPrefix(sal_Unicode const *& rBegin,
2104 : : sal_Unicode const * pEnd)
2105 : : {
2106 : : static PrefixInfo const aMap[]
2107 : : = { // dummy entry at front needed, because pLast may point here:
2108 : : { 0, 0, INET_PROT_NOT_VALID, PrefixInfo::INTERNAL },
2109 : : { ".component:", "staroffice.component:", INET_PROT_COMPONENT,
2110 : : PrefixInfo::INTERNAL },
2111 : : { ".uno:", "staroffice.uno:", INET_PROT_UNO,
2112 : : PrefixInfo::INTERNAL },
2113 : : { "cid:", 0, INET_PROT_CID, PrefixInfo::OFFICIAL },
2114 : : { "data:", 0, INET_PROT_DATA, PrefixInfo::OFFICIAL },
2115 : : { "db:", "staroffice.db:", INET_PROT_DB, PrefixInfo::INTERNAL },
2116 : : { "file:", 0, INET_PROT_FILE, PrefixInfo::OFFICIAL },
2117 : : { "ftp:", 0, INET_PROT_FTP, PrefixInfo::OFFICIAL },
2118 : : { "hid:", "staroffice.hid:", INET_PROT_HID,
2119 : : PrefixInfo::INTERNAL },
2120 : : { "http:", 0, INET_PROT_HTTP, PrefixInfo::OFFICIAL },
2121 : : { "https:", 0, INET_PROT_HTTPS, PrefixInfo::OFFICIAL },
2122 : : { "imap:", 0, INET_PROT_IMAP, PrefixInfo::OFFICIAL },
2123 : : { "javascript:", 0, INET_PROT_JAVASCRIPT, PrefixInfo::OFFICIAL },
2124 : : { "ldap:", 0, INET_PROT_LDAP, PrefixInfo::OFFICIAL },
2125 : : { "macro:", "staroffice.macro:", INET_PROT_MACRO,
2126 : : PrefixInfo::INTERNAL },
2127 : : { "mailto:", 0, INET_PROT_MAILTO, PrefixInfo::OFFICIAL },
2128 : : { "news:", 0, INET_PROT_NEWS, PrefixInfo::OFFICIAL },
2129 : : { "out:", "staroffice.out:", INET_PROT_OUT,
2130 : : PrefixInfo::INTERNAL },
2131 : : { "pop3:", "staroffice.pop3:", INET_PROT_POP3,
2132 : : PrefixInfo::INTERNAL },
2133 : : { "private:", "staroffice.private:", INET_PROT_PRIV_SOFFICE,
2134 : : PrefixInfo::INTERNAL },
2135 : : { "private:factory/", "staroffice.factory:",
2136 : : INET_PROT_PRIV_SOFFICE, PrefixInfo::INTERNAL },
2137 : : { "private:helpid/", "staroffice.helpid:", INET_PROT_PRIV_SOFFICE,
2138 : : PrefixInfo::INTERNAL },
2139 : : { "private:java/", "staroffice.java:", INET_PROT_PRIV_SOFFICE,
2140 : : PrefixInfo::INTERNAL },
2141 : : { "private:searchfolder:", "staroffice.searchfolder:",
2142 : : INET_PROT_PRIV_SOFFICE, PrefixInfo::INTERNAL },
2143 : : { "private:trashcan:", "staroffice.trashcan:",
2144 : : INET_PROT_PRIV_SOFFICE, PrefixInfo::INTERNAL },
2145 : : { "sftp:", 0, INET_PROT_SFTP, PrefixInfo::OFFICIAL },
2146 : : { "slot:", "staroffice.slot:", INET_PROT_SLOT,
2147 : : PrefixInfo::INTERNAL },
2148 : : { "smb:", 0, INET_PROT_SMB, PrefixInfo::OFFICIAL },
2149 : : { "staroffice.component:", ".component:", INET_PROT_COMPONENT,
2150 : : PrefixInfo::EXTERNAL },
2151 : : { "staroffice.db:", "db:", INET_PROT_DB, PrefixInfo::EXTERNAL },
2152 : : { "staroffice.factory:", "private:factory/",
2153 : : INET_PROT_PRIV_SOFFICE, PrefixInfo::EXTERNAL },
2154 : : { "staroffice.helpid:", "private:helpid/", INET_PROT_PRIV_SOFFICE,
2155 : : PrefixInfo::EXTERNAL },
2156 : : { "staroffice.hid:", "hid:", INET_PROT_HID,
2157 : : PrefixInfo::EXTERNAL },
2158 : : { "staroffice.java:", "private:java/", INET_PROT_PRIV_SOFFICE,
2159 : : PrefixInfo::EXTERNAL },
2160 : : { "staroffice.macro:", "macro:", INET_PROT_MACRO,
2161 : : PrefixInfo::EXTERNAL },
2162 : : { "staroffice.out:", "out:", INET_PROT_OUT,
2163 : : PrefixInfo::EXTERNAL },
2164 : : { "staroffice.pop3:", "pop3:", INET_PROT_POP3,
2165 : : PrefixInfo::EXTERNAL },
2166 : : { "staroffice.private:", "private:", INET_PROT_PRIV_SOFFICE,
2167 : : PrefixInfo::EXTERNAL },
2168 : : { "staroffice.searchfolder:", "private:searchfolder:",
2169 : : INET_PROT_PRIV_SOFFICE, PrefixInfo::EXTERNAL },
2170 : : { "staroffice.slot:", "slot:", INET_PROT_SLOT,
2171 : : PrefixInfo::EXTERNAL },
2172 : : { "staroffice.trashcan:", "private:trashcan:",
2173 : : INET_PROT_PRIV_SOFFICE, PrefixInfo::EXTERNAL },
2174 : : { "staroffice.uno:", ".uno:", INET_PROT_UNO,
2175 : : PrefixInfo::EXTERNAL },
2176 : : { "staroffice.vim:", "vim:", INET_PROT_VIM,
2177 : : PrefixInfo::EXTERNAL },
2178 : : { "staroffice:", "private:", INET_PROT_PRIV_SOFFICE,
2179 : : PrefixInfo::EXTERNAL },
2180 : : { "telnet:", 0, INET_PROT_TELNET, PrefixInfo::OFFICIAL },
2181 : : { "vim:", "staroffice.vim:", INET_PROT_VIM,
2182 : : PrefixInfo::INTERNAL },
2183 : : { "vnd.libreoffice.cmis+atom:", 0, INET_PROT_CMIS_ATOM, PrefixInfo::INTERNAL },
2184 : : { "vnd.sun.star.cmd:", 0, INET_PROT_VND_SUN_STAR_CMD,
2185 : : PrefixInfo::OFFICIAL },
2186 : : { "vnd.sun.star.expand:", 0, INET_PROT_VND_SUN_STAR_EXPAND,
2187 : : PrefixInfo::OFFICIAL },
2188 : : { "vnd.sun.star.help:", 0, INET_PROT_VND_SUN_STAR_HELP,
2189 : : PrefixInfo::OFFICIAL },
2190 : : { "vnd.sun.star.hier:", 0, INET_PROT_VND_SUN_STAR_HIER,
2191 : : PrefixInfo::OFFICIAL },
2192 : : { "vnd.sun.star.odma:", 0, INET_PROT_VND_SUN_STAR_ODMA,
2193 : : PrefixInfo::OFFICIAL },
2194 : : { "vnd.sun.star.pkg:", 0, INET_PROT_VND_SUN_STAR_PKG,
2195 : : PrefixInfo::OFFICIAL },
2196 : : { "vnd.sun.star.tdoc:", 0, INET_PROT_VND_SUN_STAR_TDOC,
2197 : : PrefixInfo::OFFICIAL },
2198 : : { "vnd.sun.star.webdav:", 0, INET_PROT_VND_SUN_STAR_WEBDAV,
2199 : : PrefixInfo::OFFICIAL } };
2200 : : /* This list needs to be sorted, or you'll introduce serious bugs */
2201 : :
2202 : 1381383 : PrefixInfo const * pFirst = aMap + 1;
2203 : 1381383 : PrefixInfo const * pLast = aMap + sizeof aMap / sizeof (PrefixInfo) - 1;
2204 : 1381383 : PrefixInfo const * pMatch = 0;
2205 : 1381383 : sal_Unicode const * pMatched = rBegin;
2206 : 1381383 : sal_Unicode const * p = rBegin;
2207 : 1381383 : sal_Int32 i = 0;
2208 [ + + ]: 4479117 : for (; pFirst < pLast; ++i)
2209 : : {
2210 [ + + ]: 3135022 : if (pFirst->m_pPrefix[i] == '\0')
2211 : : {
2212 : 55361 : pMatch = pFirst++;
2213 : 55361 : pMatched = p;
2214 : : }
2215 [ + + ]: 3135022 : if (p >= pEnd)
2216 : 37288 : break;
2217 : 3097734 : sal_uInt32 nChar = INetMIME::toLowerCase(*p++);
2218 [ + + ][ + + ]: 6024325 : while (pFirst <= pLast && sal_uChar(pFirst->m_pPrefix[i]) < nChar)
[ + + ]
2219 : 2926591 : ++pFirst;
2220 [ + + ][ + + ]: 71989198 : while (pFirst <= pLast && sal_uChar(pLast->m_pPrefix[i]) > nChar)
[ + + ]
2221 : 68891464 : --pLast;
2222 : : }
2223 [ + + ]: 1381383 : if (pFirst == pLast)
2224 : : {
2225 : 1325261 : sal_Char const * q = pFirst->m_pPrefix + i;
2226 [ + + ]: 9489605 : while (p < pEnd && *q != '\0'
[ + + + + ]
[ + + ]
2227 : 4082766 : && INetMIME::toLowerCase(*p) == sal_uChar(*q))
2228 : : {
2229 : 4081578 : ++p;
2230 : 4081578 : ++q;
2231 : : }
2232 [ + + ]: 1325261 : if (*q == '\0')
2233 : : {
2234 : 1323917 : rBegin = p;
2235 : 1323917 : return pFirst;
2236 : : }
2237 : : }
2238 : 57466 : rBegin = pMatched;
2239 : 1381383 : return pMatch;
2240 : : }
2241 : :
2242 : 24 : sal_Int32 INetURLObject::getAuthorityBegin() const
2243 : : {
2244 : : DBG_ASSERT(getSchemeInfo().m_bAuthority,
2245 : : "INetURLObject::getAuthority(): Bad scheme");
2246 : : sal_Int32 nBegin;
2247 [ - + ]: 24 : if (m_aUser.isPresent())
2248 : 0 : nBegin = m_aUser.getBegin();
2249 [ + - ]: 24 : else if (m_aHost.isPresent())
2250 : 24 : nBegin = m_aHost.getBegin();
2251 : : else
2252 : 0 : nBegin = m_aPath.getBegin();
2253 : 24 : nBegin -= RTL_CONSTASCII_LENGTH("//");
2254 : : DBG_ASSERT(m_aAbsURIRef.getStr()[nBegin] == '/'
2255 : : && m_aAbsURIRef.getStr()[nBegin + 1] == '/',
2256 : : "INetURLObject::getAuthority(): Bad authority");
2257 : 24 : return nBegin;
2258 : : }
2259 : :
2260 : 24 : INetURLObject::SubString INetURLObject::getAuthority() const
2261 : : {
2262 : 24 : sal_Int32 nBegin = getAuthorityBegin();
2263 : 24 : sal_Int32 nEnd = m_aPort.isPresent() ? m_aPort.getEnd() :
2264 : 24 : m_aHost.isPresent() ? m_aHost.getEnd() :
2265 : 0 : m_aAuth.isPresent() ? m_aAuth.getEnd() :
2266 : 0 : m_aUser.isPresent() ? m_aUser.getEnd() :
2267 [ + - ][ # # ]: 48 : nBegin + RTL_CONSTASCII_LENGTH("//");
[ # # ][ - + ]
2268 : 24 : return SubString(nBegin, nEnd - nBegin);
2269 : : }
2270 : :
2271 : 0 : bool INetURLObject::setUser(rtl::OUString const & rTheUser,
2272 : : bool bOctets, EncodeMechanism eMechanism,
2273 : : rtl_TextEncoding eCharset)
2274 : : {
2275 [ # # # # ]: 0 : if (
[ # # ][ # # ]
2276 : 0 : !getSchemeInfo().m_bUser ||
2277 : 0 : (m_eScheme == INET_PROT_IMAP && rTheUser.isEmpty())
2278 : : )
2279 : : {
2280 : 0 : return false;
2281 : : }
2282 : :
2283 : : rtl::OUString aNewUser(encodeText(rTheUser, bOctets,
2284 : : m_eScheme == INET_PROT_IMAP ?
2285 : : PART_IMAP_ACHAR :
2286 : : m_eScheme == INET_PROT_VIM ?
2287 : : PART_VIM :
2288 : : PART_USER_PASSWORD,
2289 : 0 : getEscapePrefix(), eMechanism, eCharset,
2290 [ # # ][ # # ]: 0 : false));
[ # # ]
2291 : : sal_Int32 nDelta;
2292 [ # # ]: 0 : if (m_aUser.isPresent())
2293 [ # # ]: 0 : nDelta = m_aUser.set(m_aAbsURIRef, aNewUser);
2294 [ # # ]: 0 : else if (m_aHost.isPresent())
2295 : : {
2296 [ # # ]: 0 : m_aAbsURIRef.insert(m_aHost.getBegin(), sal_Unicode('@'));
2297 [ # # ]: 0 : nDelta = m_aUser.set(m_aAbsURIRef, aNewUser, m_aHost.getBegin()) + 1;
2298 : : }
2299 [ # # ]: 0 : else if (getSchemeInfo().m_bHost)
2300 : 0 : return false;
2301 : : else
2302 [ # # ]: 0 : nDelta = m_aUser.set(m_aAbsURIRef, aNewUser, m_aPath.getBegin());
2303 : 0 : m_aAuth += nDelta;
2304 : 0 : m_aHost += nDelta;
2305 : 0 : m_aPort += nDelta;
2306 : 0 : m_aPath += nDelta;
2307 : 0 : m_aQuery += nDelta;
2308 : 0 : m_aFragment += nDelta;
2309 : 0 : return true;
2310 : : }
2311 : :
2312 : : namespace
2313 : : {
2314 : 0 : void lcl_Erase(rtl::OUStringBuffer &rBuf, sal_Int32 index, sal_Int32 count)
2315 : : {
2316 [ # # ]: 0 : rtl::OUString sTemp(rBuf.makeStringAndClear());
2317 [ # # ]: 0 : rBuf.append(sTemp.replaceAt(index, count, rtl::OUString()));
2318 : 0 : }
2319 : : }
2320 : :
2321 : 4463 : bool INetURLObject::clearPassword()
2322 : : {
2323 [ + - ]: 4463 : if (!getSchemeInfo().m_bPassword)
2324 : 4463 : return false;
2325 [ # # ]: 0 : if (m_aAuth.isPresent())
2326 : : {
2327 : 0 : lcl_Erase(m_aAbsURIRef, m_aAuth.getBegin() - 1,
2328 : 0 : m_aAuth.getLength() + 1);
2329 : 0 : sal_Int32 nDelta = m_aAuth.clear() - 1;
2330 : 0 : m_aHost += nDelta;
2331 : 0 : m_aPort += nDelta;
2332 : 0 : m_aPath += nDelta;
2333 : 0 : m_aQuery += nDelta;
2334 : 0 : m_aFragment += nDelta;
2335 : : }
2336 : 4463 : return true;
2337 : : }
2338 : :
2339 : 0 : bool INetURLObject::setPassword(rtl::OUString const & rThePassword,
2340 : : bool bOctets, EncodeMechanism eMechanism,
2341 : : rtl_TextEncoding eCharset)
2342 : : {
2343 [ # # ]: 0 : if (!getSchemeInfo().m_bPassword)
2344 : 0 : return false;
2345 : : rtl::OUString aNewAuth(encodeText(rThePassword, bOctets,
2346 : : m_eScheme == INET_PROT_VIM ?
2347 : : PART_VIM : PART_USER_PASSWORD,
2348 : 0 : getEscapePrefix(), eMechanism, eCharset,
2349 [ # # ][ # # ]: 0 : false));
2350 : : sal_Int32 nDelta;
2351 [ # # ]: 0 : if (m_aAuth.isPresent())
2352 [ # # ]: 0 : nDelta = m_aAuth.set(m_aAbsURIRef, aNewAuth);
2353 [ # # ]: 0 : else if (m_aUser.isPresent())
2354 : : {
2355 [ # # ]: 0 : m_aAbsURIRef.insert(m_aUser.getEnd(), sal_Unicode(':'));
2356 : : nDelta
2357 [ # # ]: 0 : = m_aAuth.set(m_aAbsURIRef, aNewAuth, m_aUser.getEnd() + 1) + 1;
2358 : : }
2359 [ # # ]: 0 : else if (m_aHost.isPresent())
2360 : : {
2361 : : m_aAbsURIRef.insert(m_aHost.getBegin(),
2362 [ # # ][ # # ]: 0 : rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":@" )));
2363 [ # # ]: 0 : m_aUser.set(m_aAbsURIRef, rtl::OUString(), m_aHost.getBegin());
2364 : : nDelta
2365 [ # # ]: 0 : = m_aAuth.set(m_aAbsURIRef, aNewAuth, m_aHost.getBegin() + 1) + 2;
2366 : : }
2367 [ # # ]: 0 : else if (getSchemeInfo().m_bHost)
2368 : 0 : return false;
2369 : : else
2370 : : {
2371 [ # # ]: 0 : m_aAbsURIRef.insert(m_aPath.getBegin(), sal_Unicode(':'));
2372 [ # # ]: 0 : m_aUser.set(m_aAbsURIRef, rtl::OUString(), m_aPath.getBegin());
2373 : : nDelta
2374 [ # # ]: 0 : = m_aAuth.set(m_aAbsURIRef, aNewAuth, m_aPath.getBegin() + 1) + 1;
2375 : : }
2376 : 0 : m_aHost += nDelta;
2377 : 0 : m_aPort += nDelta;
2378 : 0 : m_aPath += nDelta;
2379 : 0 : m_aQuery += nDelta;
2380 : 0 : m_aFragment += nDelta;
2381 : 0 : return true;
2382 : : }
2383 : :
2384 : : // static
2385 : 235 : bool INetURLObject::parseHost(sal_Unicode const *& rBegin, sal_Unicode const * pEnd,
2386 : : rtl::OUString & rCanonic)
2387 : : {
2388 : : // RFC 2373 is inconsistent about how to write an IPv6 address in which an
2389 : : // IPv4 address directly follows the abbreviating "::". The ABNF in
2390 : : // Appendix B suggests ":::13.1.68.3", while an example in 2.2/3 explicitly
2391 : : // mentions "::13:1.68.3". This algorithm accepts both variants:
2392 : : enum State { STATE_INITIAL, STATE_LABEL, STATE_LABEL_HYPHEN,
2393 : : STATE_LABEL_DOT, STATE_TOPLABEL, STATE_TOPLABEL_HYPHEN,
2394 : : STATE_TOPLABEL_DOT, STATE_IP4, STATE_IP4_DOT, STATE_IP6,
2395 : : STATE_IP6_COLON, STATE_IP6_2COLON, STATE_IP6_3COLON,
2396 : : STATE_IP6_HEXSEQ1, STATE_IP6_HEXSEQ1_COLON,
2397 : : STATE_IP6_HEXSEQ1_MAYBE_IP4, STATE_IP6_HEXSEQ2,
2398 : : STATE_IP6_HEXSEQ2_COLON, STATE_IP6_HEXSEQ2_MAYBE_IP4,
2399 : : STATE_IP6_IP4, STATE_IP6_IP4_DOT, STATE_IP6_DONE };
2400 : 235 : rtl::OUStringBuffer aTheCanonic;
2401 : 235 : sal_uInt32 nNumber = 0;
2402 : 235 : int nDigits = 0;
2403 : 235 : int nOctets = 0;
2404 : 235 : State eState = STATE_INITIAL;
2405 : 235 : sal_Unicode const * p = rBegin;
2406 [ + + ]: 3555 : for (; p != pEnd; ++p)
2407 [ + - - - : 3342 : switch (eState)
+ + + + +
- - - - -
- - - - -
- - - - ]
2408 : : {
2409 : : case STATE_INITIAL:
2410 [ - + ]: 235 : if (*p == '[')
2411 : : {
2412 [ # # ]: 0 : aTheCanonic.append(sal_Unicode('['));
2413 : 0 : eState = STATE_IP6;
2414 : : }
2415 [ + + ][ - + ]: 235 : else if (INetMIME::isAlpha(*p) || *p == '_')
[ + + ]
2416 : 205 : eState = STATE_TOPLABEL;
2417 [ + - ]: 30 : else if (INetMIME::isDigit(*p))
2418 : : {
2419 : 30 : nNumber = INetMIME::getWeight(*p);
2420 : 30 : nDigits = 1;
2421 : 30 : nOctets = 1;
2422 : 30 : eState = STATE_IP4;
2423 : : }
2424 : : else
2425 : 0 : goto done;
2426 : 235 : break;
2427 : :
2428 : : case STATE_LABEL:
2429 [ # # ]: 0 : if (*p == '.')
2430 : 0 : eState = STATE_LABEL_DOT;
2431 [ # # ]: 0 : else if (*p == '-')
2432 : 0 : eState = STATE_LABEL_HYPHEN;
2433 [ # # ][ # # ]: 0 : else if (!INetMIME::isAlphanumeric(*p) && *p != '_')
[ # # ]
2434 : 0 : goto done;
2435 : 0 : break;
2436 : :
2437 : : case STATE_LABEL_HYPHEN:
2438 [ # # ][ # # ]: 0 : if (INetMIME::isAlphanumeric(*p) || *p == '_')
[ # # ]
2439 : 0 : eState = STATE_LABEL;
2440 [ # # ]: 0 : else if (*p != '-')
2441 : 0 : goto done;
2442 : 0 : break;
2443 : :
2444 : : case STATE_LABEL_DOT:
2445 [ # # ][ # # ]: 0 : if (INetMIME::isAlpha(*p) || *p == '_')
[ # # ]
2446 : 0 : eState = STATE_TOPLABEL;
2447 [ # # ]: 0 : else if (INetMIME::isDigit(*p))
2448 : 0 : eState = STATE_LABEL;
2449 : : else
2450 : 0 : goto done;
2451 : 0 : break;
2452 : :
2453 : : case STATE_TOPLABEL:
2454 [ + + ]: 2425 : if (*p == '.')
2455 : 312 : eState = STATE_TOPLABEL_DOT;
2456 [ + + ]: 2113 : else if (*p == '-')
2457 : 40 : eState = STATE_TOPLABEL_HYPHEN;
2458 [ + + ][ + - ]: 2073 : else if (!INetMIME::isAlphanumeric(*p) && *p != '_')
[ + + ]
2459 : 12 : goto done;
2460 : 2413 : break;
2461 : :
2462 : : case STATE_TOPLABEL_HYPHEN:
2463 [ - + ][ # # ]: 40 : if (INetMIME::isAlphanumeric(*p) || *p == '_')
[ + - ]
2464 : 40 : eState = STATE_TOPLABEL;
2465 [ # # ]: 0 : else if (*p != '-')
2466 : 0 : goto done;
2467 : 40 : break;
2468 : :
2469 : : case STATE_TOPLABEL_DOT:
2470 [ - + ][ # # ]: 312 : if (INetMIME::isAlpha(*p) || *p == '_')
[ + - ]
2471 : 312 : eState = STATE_TOPLABEL;
2472 [ # # ]: 0 : else if (INetMIME::isDigit(*p))
2473 : 0 : eState = STATE_LABEL;
2474 : : else
2475 : 0 : goto done;
2476 : 312 : break;
2477 : :
2478 : : case STATE_IP4:
2479 [ + + ]: 240 : if (*p == '.')
2480 [ + - ]: 90 : if (nOctets < 4)
2481 : : {
2482 : : aTheCanonic.append(
2483 [ + - ]: 90 : rtl::OUString::valueOf(sal_Int32(nNumber)));
2484 [ + - ]: 90 : aTheCanonic.append(sal_Unicode('.'));
2485 : 90 : ++nOctets;
2486 : 90 : eState = STATE_IP4_DOT;
2487 : : }
2488 : : else
2489 : 0 : eState = STATE_LABEL_DOT;
2490 [ - + ]: 150 : else if (*p == '-')
2491 : 0 : eState = STATE_LABEL_HYPHEN;
2492 [ + - ][ - + ]: 150 : else if (INetMIME::isAlpha(*p) || *p == '_')
[ - + ]
2493 : 0 : eState = STATE_LABEL;
2494 [ + + ]: 150 : else if (INetMIME::isDigit(*p))
2495 [ + - ]: 140 : if (nDigits < 3)
2496 : : {
2497 : 140 : nNumber = 10 * nNumber + INetMIME::getWeight(*p);
2498 : 140 : ++nDigits;
2499 : : }
2500 : : else
2501 : 0 : eState = STATE_LABEL;
2502 : : else
2503 : 10 : goto done;
2504 : 230 : break;
2505 : :
2506 : : case STATE_IP4_DOT:
2507 [ + - ][ - + ]: 90 : if (INetMIME::isAlpha(*p) || *p == '_')
[ - + ]
2508 : 0 : eState = STATE_TOPLABEL;
2509 [ + - ]: 90 : else if (INetMIME::isDigit(*p))
2510 : : {
2511 : 90 : nNumber = INetMIME::getWeight(*p);
2512 : 90 : nDigits = 1;
2513 : 90 : eState = STATE_IP4;
2514 : : }
2515 : : else
2516 : 0 : goto done;
2517 : 90 : break;
2518 : :
2519 : : case STATE_IP6:
2520 [ # # ]: 0 : if (*p == ':')
2521 : 0 : eState = STATE_IP6_COLON;
2522 [ # # ]: 0 : else if (INetMIME::isHexDigit(*p))
2523 : : {
2524 : 0 : nNumber = INetMIME::getHexWeight(*p);
2525 : 0 : nDigits = 1;
2526 : 0 : eState = STATE_IP6_HEXSEQ1;
2527 : : }
2528 : : else
2529 : 0 : goto done;
2530 : 0 : break;
2531 : :
2532 : : case STATE_IP6_COLON:
2533 [ # # ]: 0 : if (*p == ':')
2534 : : {
2535 [ # # ]: 0 : aTheCanonic.appendAscii(RTL_CONSTASCII_STRINGPARAM("::"));
2536 : 0 : eState = STATE_IP6_2COLON;
2537 : : }
2538 : : else
2539 : 0 : goto done;
2540 : 0 : break;
2541 : :
2542 : : case STATE_IP6_2COLON:
2543 [ # # ]: 0 : if (*p == ']')
2544 : 0 : eState = STATE_IP6_DONE;
2545 [ # # ]: 0 : else if (*p == ':')
2546 : : {
2547 [ # # ]: 0 : aTheCanonic.append(sal_Unicode(':'));
2548 : 0 : eState = STATE_IP6_3COLON;
2549 : : }
2550 [ # # ]: 0 : else if (INetMIME::isDigit(*p))
2551 : : {
2552 : 0 : nNumber = INetMIME::getWeight(*p);
2553 : 0 : nDigits = 1;
2554 : 0 : eState = STATE_IP6_HEXSEQ2_MAYBE_IP4;
2555 : : }
2556 [ # # ]: 0 : else if (INetMIME::isHexDigit(*p))
2557 : : {
2558 : 0 : nNumber = INetMIME::getHexWeight(*p);
2559 : 0 : nDigits = 1;
2560 : 0 : eState = STATE_IP6_HEXSEQ2;
2561 : : }
2562 : : else
2563 : 0 : goto done;
2564 : 0 : break;
2565 : :
2566 : : case STATE_IP6_3COLON:
2567 [ # # ]: 0 : if (INetMIME::isDigit(*p))
2568 : : {
2569 : 0 : nNumber = INetMIME::getWeight(*p);
2570 : 0 : nDigits = 1;
2571 : 0 : nOctets = 1;
2572 : 0 : eState = STATE_IP6_IP4;
2573 : : }
2574 : : else
2575 : 0 : goto done;
2576 : 0 : break;
2577 : :
2578 : : case STATE_IP6_HEXSEQ1:
2579 [ # # ]: 0 : if (*p == ']')
2580 : : {
2581 : : aTheCanonic.append(
2582 [ # # ]: 0 : rtl::OUString::valueOf(sal_Int32(nNumber), 16));
2583 : 0 : eState = STATE_IP6_DONE;
2584 : : }
2585 [ # # ]: 0 : else if (*p == ':')
2586 : : {
2587 : : aTheCanonic.append(
2588 [ # # ]: 0 : rtl::OUString::valueOf(sal_Int32(nNumber), 16));
2589 [ # # ]: 0 : aTheCanonic.append(sal_Unicode(':'));
2590 : 0 : eState = STATE_IP6_HEXSEQ1_COLON;
2591 : : }
2592 [ # # ][ # # ]: 0 : else if (INetMIME::isHexDigit(*p) && nDigits < 4)
[ # # ]
2593 : : {
2594 : 0 : nNumber = 16 * nNumber + INetMIME::getHexWeight(*p);
2595 : 0 : ++nDigits;
2596 : : }
2597 : : else
2598 : 0 : goto done;
2599 : 0 : break;
2600 : :
2601 : : case STATE_IP6_HEXSEQ1_COLON:
2602 [ # # ]: 0 : if (*p == ':')
2603 : : {
2604 [ # # ]: 0 : aTheCanonic.append(sal_Unicode(':'));
2605 : 0 : eState = STATE_IP6_2COLON;
2606 : : }
2607 [ # # ]: 0 : else if (INetMIME::isDigit(*p))
2608 : : {
2609 : 0 : nNumber = INetMIME::getWeight(*p);
2610 : 0 : nDigits = 1;
2611 : 0 : eState = STATE_IP6_HEXSEQ1_MAYBE_IP4;
2612 : : }
2613 [ # # ]: 0 : else if (INetMIME::isHexDigit(*p))
2614 : : {
2615 : 0 : nNumber = INetMIME::getHexWeight(*p);
2616 : 0 : nDigits = 1;
2617 : 0 : eState = STATE_IP6_HEXSEQ1;
2618 : : }
2619 : : else
2620 : 0 : goto done;
2621 : 0 : break;
2622 : :
2623 : : case STATE_IP6_HEXSEQ1_MAYBE_IP4:
2624 [ # # ]: 0 : if (*p == ']')
2625 : : {
2626 : : aTheCanonic.append(
2627 [ # # ]: 0 : rtl::OUString::valueOf(sal_Int32(nNumber), 16));
2628 : 0 : eState = STATE_IP6_DONE;
2629 : : }
2630 [ # # ]: 0 : else if (*p == ':')
2631 : : {
2632 : : aTheCanonic.append(
2633 [ # # ]: 0 : rtl::OUString::valueOf(sal_Int32(nNumber), 16));
2634 [ # # ]: 0 : aTheCanonic.append(sal_Unicode(':'));
2635 : 0 : eState = STATE_IP6_HEXSEQ1_COLON;
2636 : : }
2637 [ # # ]: 0 : else if (*p == '.')
2638 : : {
2639 : : nNumber = 100 * (nNumber >> 8) + 10 * (nNumber >> 4 & 15)
2640 : 0 : + (nNumber & 15);
2641 : : aTheCanonic.append(
2642 [ # # ]: 0 : rtl::OUString::valueOf(sal_Int32(nNumber)));
2643 [ # # ]: 0 : aTheCanonic.append(sal_Unicode('.'));
2644 : 0 : nOctets = 2;
2645 : 0 : eState = STATE_IP6_IP4_DOT;
2646 : : }
2647 [ # # ][ # # ]: 0 : else if (INetMIME::isDigit(*p) && nDigits < 3)
[ # # ]
2648 : : {
2649 : 0 : nNumber = 16 * nNumber + INetMIME::getWeight(*p);
2650 : 0 : ++nDigits;
2651 : : }
2652 [ # # ][ # # ]: 0 : else if (INetMIME::isHexDigit(*p) && nDigits < 4)
[ # # ]
2653 : : {
2654 : 0 : nNumber = 16 * nNumber + INetMIME::getHexWeight(*p);
2655 : 0 : ++nDigits;
2656 : 0 : eState = STATE_IP6_HEXSEQ1;
2657 : : }
2658 : : else
2659 : 0 : goto done;
2660 : 0 : break;
2661 : :
2662 : : case STATE_IP6_HEXSEQ2:
2663 [ # # ]: 0 : if (*p == ']')
2664 : : {
2665 : : aTheCanonic.append(
2666 [ # # ]: 0 : rtl::OUString::valueOf(sal_Int32(nNumber), 16));
2667 : 0 : eState = STATE_IP6_DONE;
2668 : : }
2669 [ # # ]: 0 : else if (*p == ':')
2670 : : {
2671 : : aTheCanonic.append(
2672 [ # # ]: 0 : rtl::OUString::valueOf(sal_Int32(nNumber), 16));
2673 [ # # ]: 0 : aTheCanonic.append(sal_Unicode(':'));
2674 : 0 : eState = STATE_IP6_HEXSEQ2_COLON;
2675 : : }
2676 [ # # ][ # # ]: 0 : else if (INetMIME::isHexDigit(*p) && nDigits < 4)
[ # # ]
2677 : : {
2678 : 0 : nNumber = 16 * nNumber + INetMIME::getHexWeight(*p);
2679 : 0 : ++nDigits;
2680 : : }
2681 : : else
2682 : 0 : goto done;
2683 : 0 : break;
2684 : :
2685 : : case STATE_IP6_HEXSEQ2_COLON:
2686 [ # # ]: 0 : if (INetMIME::isDigit(*p))
2687 : : {
2688 : 0 : nNumber = INetMIME::getWeight(*p);
2689 : 0 : nDigits = 1;
2690 : 0 : eState = STATE_IP6_HEXSEQ2_MAYBE_IP4;
2691 : : }
2692 [ # # ]: 0 : else if (INetMIME::isHexDigit(*p))
2693 : : {
2694 : 0 : nNumber = INetMIME::getHexWeight(*p);
2695 : 0 : nDigits = 1;
2696 : 0 : eState = STATE_IP6_HEXSEQ2;
2697 : : }
2698 : : else
2699 : 0 : goto done;
2700 : 0 : break;
2701 : :
2702 : : case STATE_IP6_HEXSEQ2_MAYBE_IP4:
2703 [ # # ]: 0 : if (*p == ']')
2704 : : {
2705 : : aTheCanonic.append(
2706 [ # # ]: 0 : rtl::OUString::valueOf(sal_Int32(nNumber), 16));
2707 : 0 : eState = STATE_IP6_DONE;
2708 : : }
2709 [ # # ]: 0 : else if (*p == ':')
2710 : : {
2711 : : aTheCanonic.append(
2712 [ # # ]: 0 : rtl::OUString::valueOf(sal_Int32(nNumber), 16));
2713 [ # # ]: 0 : aTheCanonic.append(sal_Unicode(':'));
2714 : 0 : eState = STATE_IP6_HEXSEQ2_COLON;
2715 : : }
2716 [ # # ]: 0 : else if (*p == '.')
2717 : : {
2718 : : nNumber = 100 * (nNumber >> 8) + 10 * (nNumber >> 4 & 15)
2719 : 0 : + (nNumber & 15);
2720 : : aTheCanonic.append(
2721 [ # # ]: 0 : rtl::OUString::valueOf(sal_Int32(nNumber)));
2722 [ # # ]: 0 : aTheCanonic.append(sal_Unicode('.'));
2723 : 0 : nOctets = 2;
2724 : 0 : eState = STATE_IP6_IP4_DOT;
2725 : : }
2726 [ # # ][ # # ]: 0 : else if (INetMIME::isDigit(*p) && nDigits < 3)
[ # # ]
2727 : : {
2728 : 0 : nNumber = 16 * nNumber + INetMIME::getWeight(*p);
2729 : 0 : ++nDigits;
2730 : : }
2731 [ # # ][ # # ]: 0 : else if (INetMIME::isHexDigit(*p) && nDigits < 4)
[ # # ]
2732 : : {
2733 : 0 : nNumber = 16 * nNumber + INetMIME::getHexWeight(*p);
2734 : 0 : ++nDigits;
2735 : 0 : eState = STATE_IP6_HEXSEQ2;
2736 : : }
2737 : : else
2738 : 0 : goto done;
2739 : 0 : break;
2740 : :
2741 : : case STATE_IP6_IP4:
2742 [ # # ]: 0 : if (*p == ']')
2743 [ # # ]: 0 : if (nOctets == 4)
2744 : : {
2745 : : aTheCanonic.append(
2746 [ # # ]: 0 : rtl::OUString::valueOf(sal_Int32(nNumber)));
2747 : 0 : eState = STATE_IP6_DONE;
2748 : : }
2749 : : else
2750 : 0 : goto done;
2751 [ # # ]: 0 : else if (*p == '.')
2752 [ # # ]: 0 : if (nOctets < 4)
2753 : : {
2754 : : aTheCanonic.append(
2755 [ # # ]: 0 : rtl::OUString::valueOf(sal_Int32(nNumber)));
2756 [ # # ]: 0 : aTheCanonic.append(sal_Unicode('.'));
2757 : 0 : ++nOctets;
2758 : 0 : eState = STATE_IP6_IP4_DOT;
2759 : : }
2760 : : else
2761 : 0 : goto done;
2762 [ # # ][ # # ]: 0 : else if (INetMIME::isDigit(*p) && nDigits < 3)
[ # # ]
2763 : : {
2764 : 0 : nNumber = 10 * nNumber + INetMIME::getWeight(*p);
2765 : 0 : ++nDigits;
2766 : : }
2767 : : else
2768 : 0 : goto done;
2769 : 0 : break;
2770 : :
2771 : : case STATE_IP6_IP4_DOT:
2772 [ # # ]: 0 : if (INetMIME::isDigit(*p))
2773 : : {
2774 : 0 : nNumber = INetMIME::getWeight(*p);
2775 : 0 : nDigits = 1;
2776 : 0 : eState = STATE_IP6_IP4;
2777 : : }
2778 : : else
2779 : 0 : goto done;
2780 : 0 : break;
2781 : :
2782 : : case STATE_IP6_DONE:
2783 : 0 : goto done;
2784 : : }
2785 : : done:
2786 [ + + - - ]: 235 : switch (eState)
2787 : : {
2788 : : case STATE_LABEL:
2789 : : case STATE_TOPLABEL:
2790 : : case STATE_TOPLABEL_DOT:
2791 [ + - ]: 205 : aTheCanonic.setLength(0);
2792 [ + - ]: 205 : aTheCanonic.append(rBegin, p - rBegin);
2793 : 205 : rBegin = p;
2794 [ + - ]: 205 : rCanonic = aTheCanonic.makeStringAndClear();
2795 : 205 : return true;
2796 : :
2797 : : case STATE_IP4:
2798 [ + - ]: 30 : if (nOctets == 4)
2799 : : {
2800 : : aTheCanonic.append(
2801 [ + - ]: 30 : rtl::OUString::valueOf(sal_Int32(nNumber)));
2802 : 30 : rBegin = p;
2803 [ + - ]: 30 : rCanonic = aTheCanonic.makeStringAndClear();
2804 : 30 : return true;
2805 : : }
2806 : 0 : return false;
2807 : :
2808 : : case STATE_IP6_DONE:
2809 [ # # ]: 0 : aTheCanonic.append(sal_Unicode(']'));
2810 : 0 : rBegin = p;
2811 [ # # ]: 0 : rCanonic = aTheCanonic.makeStringAndClear();
2812 : 0 : return true;
2813 : :
2814 : : default:
2815 : 0 : return false;
2816 : 235 : }
2817 : : }
2818 : :
2819 : : // static
2820 : 122754 : bool INetURLObject::parseHostOrNetBiosName(
2821 : : sal_Unicode const * pBegin, sal_Unicode const * pEnd, bool bOctets,
2822 : : EncodeMechanism eMechanism, rtl_TextEncoding eCharset, bool bNetBiosName,
2823 : : rtl::OUStringBuffer* pCanonic)
2824 : : {
2825 : 122754 : rtl::OUString aTheCanonic;
2826 [ + + ]: 122754 : if (pBegin < pEnd)
2827 : : {
2828 : 215 : sal_Unicode const * p = pBegin;
2829 [ + - ][ + - ]: 215 : if (!parseHost(p, pEnd, aTheCanonic) || p != pEnd)
[ + + ][ + + ]
2830 : : {
2831 [ - + ]: 2 : if (bNetBiosName)
2832 : : {
2833 : 0 : rtl::OUStringBuffer buf;
2834 [ # # ]: 0 : while (pBegin < pEnd)
2835 : : {
2836 : : EscapeType eEscapeType;
2837 : : sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd, bOctets, '%',
2838 : : eMechanism, eCharset,
2839 [ # # ]: 0 : eEscapeType);
2840 [ # # ]: 0 : if (!INetMIME::isVisible(nUTF32))
2841 : 0 : return false;
2842 [ # # ]: 0 : if (!INetMIME::isAlphanumeric(nUTF32))
2843 [ # # ]: 0 : switch (nUTF32)
2844 : : {
2845 : : case '"':
2846 : : case '*':
2847 : : case '+':
2848 : : case ',':
2849 : : case '/':
2850 : : case ':':
2851 : : case ';':
2852 : : case '<':
2853 : : case '=':
2854 : : case '>':
2855 : : case '?':
2856 : : case '[':
2857 : : case '\\':
2858 : : case ']':
2859 : : case '`':
2860 : : case '|':
2861 : 0 : return false;
2862 : : }
2863 [ # # ]: 0 : if (pCanonic != NULL) {
2864 : : appendUCS4(
2865 : : buf, nUTF32, eEscapeType, bOctets, PART_URIC, '%',
2866 [ # # ]: 0 : eCharset, true);
2867 : : }
2868 : : }
2869 [ # # ][ # # ]: 0 : aTheCanonic = buf.makeStringAndClear();
2870 : : }
2871 : : else
2872 : 215 : return false;
2873 : : }
2874 : : }
2875 [ + + ]: 122752 : if (pCanonic != NULL) {
2876 [ + - ][ + - ]: 110602 : *pCanonic = aTheCanonic;
2877 : : }
2878 : 122754 : return true;
2879 : : }
2880 : :
2881 : 0 : bool INetURLObject::setHost(rtl::OUString const & rTheHost, bool bOctets,
2882 : : EncodeMechanism eMechanism,
2883 : : rtl_TextEncoding eCharset)
2884 : : {
2885 [ # # ]: 0 : if (!getSchemeInfo().m_bHost)
2886 : 0 : return false;
2887 [ # # ]: 0 : rtl::OUStringBuffer aSynHost(rTheHost);
2888 : 0 : bool bNetBiosName = false;
2889 [ # # # ]: 0 : switch (m_eScheme)
2890 : : {
2891 : : case INET_PROT_FILE:
2892 : : {
2893 : 0 : rtl::OUString sTemp(aSynHost.toString());
2894 [ # # ]: 0 : if (sTemp.equalsIgnoreAsciiCaseAsciiL(
2895 : 0 : RTL_CONSTASCII_STRINGPARAM("localhost")))
2896 : : {
2897 [ # # ]: 0 : aSynHost.setLength(0);
2898 : : }
2899 : 0 : bNetBiosName = true;
2900 : : }
2901 : 0 : break;
2902 : : case INET_PROT_LDAP:
2903 [ # # ][ # # ]: 0 : if (aSynHost.getLength() == 0 && m_aPort.isPresent())
[ # # ]
2904 : 0 : return false;
2905 : 0 : break;
2906 : :
2907 : : default:
2908 [ # # ]: 0 : if (aSynHost.getLength() == 0)
2909 : 0 : return false;
2910 : 0 : break;
2911 : : }
2912 [ # # ]: 0 : if (!parseHostOrNetBiosName(
2913 : 0 : aSynHost.getStr(), aSynHost.getStr() + aSynHost.getLength(),
2914 [ # # ]: 0 : bOctets, eMechanism, eCharset, bNetBiosName, &aSynHost))
2915 : 0 : return false;
2916 [ # # ][ # # ]: 0 : sal_Int32 nDelta = m_aHost.set(m_aAbsURIRef, aSynHost.makeStringAndClear());
2917 : 0 : m_aPort += nDelta;
2918 : 0 : m_aPath += nDelta;
2919 : 0 : m_aQuery += nDelta;
2920 : 0 : m_aFragment += nDelta;
2921 : 0 : return true;
2922 : : }
2923 : :
2924 : : // static
2925 : 819023 : bool INetURLObject::parsePath(INetProtocol eScheme,
2926 : : sal_Unicode const ** pBegin,
2927 : : sal_Unicode const * pEnd,
2928 : : bool bOctets,
2929 : : EncodeMechanism eMechanism,
2930 : : rtl_TextEncoding eCharset,
2931 : : bool bSkippedInitialSlash,
2932 : : sal_uInt32 nSegmentDelimiter,
2933 : : sal_uInt32 nAltSegmentDelimiter,
2934 : : sal_uInt32 nQueryDelimiter,
2935 : : sal_uInt32 nFragmentDelimiter,
2936 : : rtl::OUStringBuffer &rSynPath)
2937 : : {
2938 : : DBG_ASSERT(pBegin, "INetURLObject::parsePath(): Null output param");
2939 : :
2940 : 819023 : sal_Unicode const * pPos = *pBegin;
2941 : 819023 : rtl::OUStringBuffer aTheSynPath;
2942 : :
2943 [ - + + + : 819023 : switch (eScheme)
+ - - + +
- - + - +
- - - +
- ]
2944 : : {
2945 : : case INET_PROT_NOT_VALID:
2946 : 0 : return false;
2947 : :
2948 : : case INET_PROT_FTP:
2949 : : case INET_PROT_IMAP:
2950 [ + - ][ - + ]: 8 : if (pPos < pEnd && *pPos != '/')
2951 : 0 : return false;
2952 [ + + ][ + - ]: 72 : while (pPos < pEnd && *pPos != nFragmentDelimiter)
[ + + ]
2953 : : {
2954 : : EscapeType eEscapeType;
2955 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
2956 : : '%', eMechanism,
2957 [ + - ]: 64 : eCharset, eEscapeType);
2958 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
2959 [ + - ]: 64 : PART_HTTP_PATH, '%', eCharset, true);
2960 : : }
2961 [ - + ]: 8 : if (aTheSynPath.getLength() == 0)
2962 [ # # ]: 0 : aTheSynPath.append(sal_Unicode('/'));
2963 : 8 : break;
2964 : :
2965 : : case INET_PROT_HTTP:
2966 : : case INET_PROT_VND_SUN_STAR_WEBDAV:
2967 : : case INET_PROT_HTTPS:
2968 : : case INET_PROT_SMB:
2969 : : case INET_PROT_CMIS_ATOM:
2970 [ + + ][ - + ]: 184 : if (pPos < pEnd && *pPos != '/')
2971 : 0 : return false;
2972 [ + + ][ + - ]: 1040 : while (pPos < pEnd && *pPos != nQueryDelimiter
[ + + ][ + + ]
2973 : : && *pPos != nFragmentDelimiter)
2974 : : {
2975 : : EscapeType eEscapeType;
2976 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
2977 : : '%', eMechanism,
2978 [ + - ]: 856 : eCharset, eEscapeType);
2979 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
2980 [ + - ]: 856 : PART_HTTP_PATH, '%', eCharset, true);
2981 : : }
2982 [ + + ]: 184 : if (aTheSynPath.getLength() == 0)
2983 [ + - ]: 51 : aTheSynPath.append(sal_Unicode('/'));
2984 : 184 : break;
2985 : :
2986 : : case INET_PROT_FILE:
2987 : : {
2988 [ + + ]: 130810 : if (bSkippedInitialSlash)
2989 [ + - ]: 429 : aTheSynPath.append(sal_Unicode('/'));
2990 [ + - ][ - + ]: 130381 : else if (pPos < pEnd
[ # # ]
2991 : : && *pPos != nSegmentDelimiter
2992 : : && *pPos != nAltSegmentDelimiter)
2993 : 0 : return false;
2994 [ + + ][ + + ]: 8448071 : while (pPos < pEnd && *pPos != nFragmentDelimiter)
[ + + ]
2995 : : {
2996 : : EscapeType eEscapeType;
2997 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
2998 : : '%', eMechanism,
2999 [ + - ]: 8317261 : eCharset, eEscapeType);
3000 [ + + ]: 8317261 : if (eEscapeType == ESCAPE_NO)
3001 : : {
3002 [ + + ][ + + ]: 8316601 : if (nUTF32 == nSegmentDelimiter
3003 : : || nUTF32 == nAltSegmentDelimiter)
3004 : : {
3005 [ + - ]: 1093547 : aTheSynPath.append(sal_Unicode('/'));
3006 : 1093547 : continue;
3007 : : }
3008 [ + + ][ + + ]: 7223068 : else if (nUTF32 == '|'
[ + - ][ + + ]
[ - + + +
+ - ][ + + ]
3009 : : && (pPos == pEnd
3010 : : || *pPos == nFragmentDelimiter
3011 : : || *pPos == nSegmentDelimiter
3012 : : || *pPos == nAltSegmentDelimiter)
3013 : 8 : && aTheSynPath.getLength() == 2
3014 : 6 : && INetMIME::isAlpha(aTheSynPath[1]))
3015 : : {
3016 : : // A first segment of <ALPHA "|"> is translated to
3017 : : // <ALPHA ":">:
3018 [ + - ]: 6 : aTheSynPath.append(sal_Unicode(':'));
3019 : 6 : continue;
3020 : : }
3021 : : }
3022 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3023 [ + - ]: 8317261 : PART_PCHAR, '%', eCharset, true);
3024 : : }
3025 [ - + ]: 130810 : if (aTheSynPath.getLength() == 0)
3026 [ # # ]: 0 : aTheSynPath.append(sal_Unicode('/'));
3027 : 130810 : break;
3028 : : }
3029 : :
3030 : : case INET_PROT_MAILTO:
3031 [ + + ][ + - ]: 453 : while (pPos < pEnd && *pPos != nQueryDelimiter
[ + - ][ + + ]
3032 : : && *pPos != nFragmentDelimiter)
3033 : : {
3034 : : EscapeType eEscapeType;
3035 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
3036 : : '%', eMechanism,
3037 [ + - ]: 431 : eCharset, eEscapeType);
3038 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3039 [ + - ]: 431 : PART_MAILTO, '%', eCharset, true);
3040 : : }
3041 : 22 : break;
3042 : :
3043 : : case INET_PROT_NEWS:
3044 [ # # ][ # # ]: 0 : if (pPos == pEnd || *pPos == nQueryDelimiter
[ # # ]
3045 : : || *pPos == nFragmentDelimiter)
3046 : 0 : return false;
3047 : :
3048 : : // Match <"*">:
3049 [ # # ][ # # ]: 0 : if (*pPos == '*'
[ # # ][ # # ]
3050 : 0 : && (pEnd - pPos == 1 || pPos[1] == nQueryDelimiter
3051 : 0 : || pPos[1] == nFragmentDelimiter))
3052 : : {
3053 : 0 : ++pPos;
3054 [ # # ]: 0 : aTheSynPath.append(sal_Unicode('*'));
3055 : 0 : break;
3056 : : }
3057 : :
3058 : : // Match <group>:
3059 [ # # ]: 0 : if (INetMIME::isAlpha(*pPos))
3060 : : {
3061 : 0 : for (sal_Unicode const * p = pPos + 1;; ++p)
3062 : : {
3063 [ # # ][ # # ]: 0 : if (p == pEnd || *p == nQueryDelimiter
[ # # ]
3064 : : || *p == nFragmentDelimiter)
3065 : : {
3066 [ # # ]: 0 : aTheSynPath.setLength(0);
3067 [ # # ]: 0 : aTheSynPath.append(pPos, p - pPos);
3068 : 0 : pPos = p;
3069 : 0 : goto done;
3070 : : }
3071 [ # # ][ # # ]: 0 : else if (!INetMIME::isAlphanumeric(*p) && *p != '+'
[ # # ][ # # ]
[ # # ][ # # ]
3072 : : && *p != '-' && *p != '.' && *p != '_')
3073 : : {
3074 : 0 : break;
3075 : : }
3076 : : }
3077 : : }
3078 : :
3079 : : // Match <article>:
3080 : 0 : for (;;)
3081 : : {
3082 [ # # ][ # # ]: 0 : if (pPos == pEnd || *pPos == nQueryDelimiter
[ # # ]
3083 : : || *pPos == nFragmentDelimiter)
3084 : 0 : return false;
3085 [ # # ]: 0 : if (*pPos == '@')
3086 : : break;
3087 : : EscapeType eEscapeType;
3088 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets, '%',
3089 [ # # ]: 0 : eMechanism, eCharset, eEscapeType);
3090 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3091 [ # # ]: 0 : PART_NEWS_ARTICLE_LOCALPART, '%', eCharset, true);
3092 : : }
3093 [ # # ]: 0 : if (aTheSynPath.getLength() == 0)
3094 : 0 : return false;
3095 : 0 : ++pPos;
3096 [ # # ]: 0 : aTheSynPath.append(sal_Unicode('@'));
3097 : : {
3098 : 0 : sal_Unicode const * p = pPos;
3099 [ # # ][ # # ]: 0 : while (p < pEnd && *pPos != nQueryDelimiter
[ # # ][ # # ]
3100 : : && *pPos != nFragmentDelimiter)
3101 : 0 : ++p;
3102 : 0 : rtl::OUString aCanonic;
3103 [ # # ][ # # ]: 0 : if (!parseHost(pPos, p, aCanonic))
3104 : 0 : return false;
3105 [ # # ][ # # ]: 0 : aTheSynPath.append(aCanonic);
3106 : : }
3107 : :
3108 : : done:
3109 : 0 : break;
3110 : :
3111 : : case INET_PROT_POP3:
3112 [ # # ][ # # ]: 0 : while (pPos < pEnd && *pPos != nFragmentDelimiter)
[ # # ]
3113 : : {
3114 : : EscapeType eEscapeType;
3115 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
3116 : : '%', eMechanism,
3117 [ # # ]: 0 : eCharset, eEscapeType);
3118 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3119 : : PART_MESSAGE_ID_PATH, '%', eCharset,
3120 [ # # ]: 0 : true);
3121 : : }
3122 : 0 : break;
3123 : :
3124 : : case INET_PROT_PRIV_SOFFICE:
3125 : : case INET_PROT_SLOT:
3126 : : case INET_PROT_HID:
3127 : : case INET_PROT_MACRO:
3128 : : case INET_PROT_UNO:
3129 : : case INET_PROT_COMPONENT:
3130 : : case INET_PROT_LDAP:
3131 [ + + ][ + + ]: 8944041 : while (pPos < pEnd && *pPos != nQueryDelimiter
[ + - ][ + + ]
3132 : : && *pPos != nFragmentDelimiter)
3133 : : {
3134 : : EscapeType eEscapeType;
3135 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
3136 : : '%', eMechanism,
3137 [ + - ]: 8257248 : eCharset, eEscapeType);
3138 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3139 : : PART_PATH_BEFORE_QUERY, '%', eCharset,
3140 [ + - ]: 8257248 : true);
3141 : : }
3142 : 686793 : break;
3143 : :
3144 : : case INET_PROT_VND_SUN_STAR_HELP:
3145 [ + - ][ + - ]: 190 : if (pPos == pEnd
[ - + ]
3146 : : || *pPos == nQueryDelimiter
3147 : : || *pPos == nFragmentDelimiter)
3148 [ # # ]: 0 : aTheSynPath.append(sal_Unicode('/'));
3149 : : else
3150 : : {
3151 [ - + ]: 190 : if (*pPos != '/')
3152 : 0 : return false;
3153 [ + - ][ + + ]: 3302 : while (pPos < pEnd && *pPos != nQueryDelimiter
[ + - ][ + + ]
3154 : : && *pPos != nFragmentDelimiter)
3155 : : {
3156 : : EscapeType eEscapeType;
3157 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
3158 : : '%', eMechanism,
3159 [ + - ]: 3112 : eCharset, eEscapeType);
3160 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3161 [ + - ]: 3112 : PART_HTTP_PATH, '%', eCharset, true);
3162 : : }
3163 : : }
3164 : 190 : break;
3165 : :
3166 : : case INET_PROT_JAVASCRIPT:
3167 : : case INET_PROT_DATA:
3168 : : case INET_PROT_CID:
3169 : : case INET_PROT_DB:
3170 [ # # ][ # # ]: 0 : while (pPos < pEnd && *pPos != nFragmentDelimiter)
[ # # ]
3171 : : {
3172 : : EscapeType eEscapeType;
3173 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
3174 : : '%', eMechanism,
3175 [ # # ]: 0 : eCharset, eEscapeType);
3176 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3177 [ # # ]: 0 : PART_URIC, '%', eCharset, true);
3178 : : }
3179 : 0 : break;
3180 : :
3181 : : case INET_PROT_OUT:
3182 [ # # ][ # # ]: 0 : if (pEnd - pPos < 2 || *pPos++ != '/' || *pPos++ != '~')
[ # # ][ # # ]
3183 : 0 : return false;
3184 [ # # ]: 0 : aTheSynPath.appendAscii(RTL_CONSTASCII_STRINGPARAM("/~"));
3185 [ # # ][ # # ]: 0 : while (pPos < pEnd && *pPos != nFragmentDelimiter)
[ # # ]
3186 : : {
3187 : : EscapeType eEscapeType;
3188 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
3189 : : '%', eMechanism,
3190 [ # # ]: 0 : eCharset, eEscapeType);
3191 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3192 [ # # ]: 0 : PART_URIC, '%', eCharset, true);
3193 : : }
3194 : 0 : break;
3195 : :
3196 : : case INET_PROT_VND_SUN_STAR_HIER:
3197 : : case INET_PROT_VND_SUN_STAR_PKG:
3198 [ + + ][ - + ]: 353 : if (pPos < pEnd && *pPos != '/'
[ # # ][ # # ]
3199 : : && *pPos != nQueryDelimiter && *pPos != nFragmentDelimiter)
3200 : 0 : return false;
3201 [ + + ][ + - ]: 7785 : while (pPos < pEnd && *pPos != nQueryDelimiter
[ + - ][ + + ]
3202 : : && *pPos != nFragmentDelimiter)
3203 : : {
3204 : : EscapeType eEscapeType;
3205 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
3206 : : '%', eMechanism,
3207 [ + - ]: 7432 : eCharset, eEscapeType);
3208 [ + + ][ + + ]: 7432 : if (eEscapeType == ESCAPE_NO && nUTF32 == '/')
3209 [ + - ]: 676 : aTheSynPath.append(sal_Unicode('/'));
3210 : : else
3211 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3212 [ + - ]: 7432 : PART_PCHAR, '%', eCharset, false);
3213 : : }
3214 [ + + ]: 353 : if (aTheSynPath.getLength() == 0)
3215 [ + - ]: 81 : aTheSynPath.append(sal_Unicode('/'));
3216 : 353 : break;
3217 : :
3218 : : case INET_PROT_VIM:
3219 : : {
3220 : 0 : sal_Unicode const * pPathEnd = pPos;
3221 [ # # ][ # # ]: 0 : while (pPathEnd < pEnd && *pPathEnd != nFragmentDelimiter)
[ # # ]
3222 : 0 : ++pPathEnd;
3223 [ # # ]: 0 : aTheSynPath.append(sal_Unicode('/'));
3224 [ # # ]: 0 : if (pPos == pPathEnd)
3225 : : break;
3226 [ # # ]: 0 : else if (*pPos++ != '/')
3227 : 0 : return false;
3228 [ # # ]: 0 : if (pPos == pPathEnd)
3229 : : break;
3230 [ # # ][ # # ]: 0 : while (pPos < pPathEnd && *pPos != '/')
[ # # ]
3231 : : {
3232 : : EscapeType eEscapeType;
3233 : : sal_uInt32 nUTF32 = getUTF32(pPos, pPathEnd, bOctets,
3234 : : '=', eMechanism,
3235 [ # # ]: 0 : eCharset, eEscapeType);
3236 : : appendUCS4(aTheSynPath,
3237 : : eEscapeType == ESCAPE_NO ?
3238 : : INetMIME::toLowerCase(nUTF32) : nUTF32,
3239 : : eEscapeType, bOctets, PART_VIM, '=',
3240 [ # # ][ # # ]: 0 : eCharset, false);
3241 : : }
3242 : : bool bInbox;
3243 : 0 : rtl::OUString sCompare(aTheSynPath.toString());
3244 [ # # ]: 0 : if ( sCompare == "/inbox" )
3245 : 0 : bInbox = true;
3246 [ # # ]: 0 : else if ( sCompare == "/newsgroups" )
3247 : 0 : bInbox = false;
3248 : : else
3249 : 0 : return false;
3250 [ # # ]: 0 : aTheSynPath.append(sal_Unicode('/'));
3251 [ # # ]: 0 : if (pPos == pPathEnd)
3252 : : break;
3253 [ # # ]: 0 : else if (*pPos++ != '/')
3254 : 0 : return false;
3255 [ # # ]: 0 : if (!bInbox)
3256 : : {
3257 : 0 : bool bEmpty = true;
3258 [ # # ][ # # ]: 0 : while (pPos < pPathEnd && *pPos != '/')
[ # # ]
3259 : : {
3260 : : EscapeType eEscapeType;
3261 : : sal_uInt32 nUTF32 = getUTF32(pPos, pPathEnd, bOctets,
3262 : : '=', eMechanism,
3263 [ # # ]: 0 : eCharset, eEscapeType);
3264 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3265 [ # # ]: 0 : PART_VIM, '=', eCharset, false);
3266 : 0 : bEmpty = false;
3267 : : }
3268 [ # # ]: 0 : if (bEmpty)
3269 : 0 : return false;
3270 [ # # ]: 0 : aTheSynPath.append(sal_Unicode('/'));
3271 [ # # ]: 0 : if (pPos == pPathEnd)
3272 : : break;
3273 [ # # ]: 0 : else if (*pPos++ != '/')
3274 : 0 : return false;
3275 : : }
3276 : 0 : bool bEmpty = true;
3277 [ # # ][ # # ]: 0 : while (pPos < pPathEnd && *pPos != ':')
[ # # ]
3278 : : {
3279 : : EscapeType eEscapeType;
3280 : : sal_uInt32 nUTF32 = getUTF32(pPos, pPathEnd, bOctets,
3281 : : '=', eMechanism,
3282 [ # # ]: 0 : eCharset, eEscapeType);
3283 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3284 [ # # ]: 0 : PART_VIM, '=', eCharset, false);
3285 : 0 : bEmpty = false;
3286 : : }
3287 [ # # ]: 0 : if (bEmpty)
3288 : 0 : return false;
3289 [ # # ]: 0 : if (pPos == pPathEnd)
3290 : : break;
3291 [ # # ]: 0 : else if (*pPos++ != ':')
3292 : 0 : return false;
3293 [ # # ]: 0 : aTheSynPath.append(sal_Unicode(':'));
3294 [ # # ]: 0 : for (int i = 0; i < 3; ++i)
3295 : : {
3296 [ # # ]: 0 : if (i != 0)
3297 : : {
3298 [ # # ][ # # ]: 0 : if (pPos == pPathEnd || *pPos++ != '.')
[ # # ]
3299 : 0 : return false;
3300 [ # # ]: 0 : aTheSynPath.append(sal_Unicode('.'));
3301 : : }
3302 : 0 : bEmpty = true;
3303 [ # # ][ # # ]: 0 : while (pPos < pPathEnd && *pPos != '.')
[ # # ]
3304 : : {
3305 : : EscapeType eEscapeType;
3306 : : sal_uInt32 nUTF32 = getUTF32(pPos, pPathEnd, bOctets,
3307 : : '=', eMechanism,
3308 [ # # ]: 0 : eCharset, eEscapeType);
3309 [ # # ]: 0 : if (!INetMIME::isDigit(nUTF32))
3310 : 0 : return false;
3311 [ # # ]: 0 : aTheSynPath.append(sal_Unicode(nUTF32));
3312 : 0 : bEmpty = false;
3313 : : }
3314 [ # # ]: 0 : if (bEmpty)
3315 : 0 : return false;
3316 : : }
3317 [ # # ]: 0 : if (pPos != pPathEnd)
3318 : 0 : return false;
3319 [ # # ]: 0 : break;
3320 : : }
3321 : :
3322 : : case INET_PROT_VND_SUN_STAR_CMD:
3323 : : case INET_PROT_VND_SUN_STAR_EXPAND:
3324 : : {
3325 [ + - ][ - + ]: 375 : if (pPos == pEnd || *pPos == nFragmentDelimiter)
3326 : 0 : return false;
3327 : 375 : Part ePart = PART_URIC_NO_SLASH;
3328 [ + + ][ + - ]: 12564 : while (pPos != pEnd && *pPos != nFragmentDelimiter)
[ + + ]
3329 : : {
3330 : : EscapeType eEscapeType;
3331 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
3332 : : '%', eMechanism,
3333 [ + - ]: 12189 : eCharset, eEscapeType);
3334 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets, ePart,
3335 [ + - ]: 12189 : '%', eCharset, true);
3336 : 12189 : ePart = PART_URIC;
3337 : : }
3338 : 375 : break;
3339 : : }
3340 : :
3341 : : case INET_PROT_VND_SUN_STAR_ODMA:
3342 [ # # ]: 0 : if (pPos < pEnd)
3343 : : {
3344 [ # # ]: 0 : if (*pPos == '/')
3345 : 0 : ++pPos;
3346 : : else
3347 : 0 : return false;
3348 : : }
3349 [ # # ]: 0 : aTheSynPath.append(sal_Unicode('/'));
3350 [ # # ][ # # ]: 0 : while (pPos < pEnd && *pPos != nFragmentDelimiter)
[ # # ]
3351 : : {
3352 : : EscapeType eEscapeType;
3353 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
3354 : : '%', eMechanism,
3355 [ # # ]: 0 : eCharset, eEscapeType);
3356 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3357 [ # # ]: 0 : PART_URIC_NO_SLASH, '%', eCharset, true);
3358 : : }
3359 : 0 : break;
3360 : :
3361 : : case INET_PROT_TELNET:
3362 [ # # ]: 0 : if (pPos < pEnd)
3363 : : {
3364 [ # # ][ # # ]: 0 : if (*pPos != '/' || pEnd - pPos > 1)
3365 : 0 : return false;
3366 : 0 : ++pPos;
3367 : : }
3368 [ # # ]: 0 : aTheSynPath.append(sal_Unicode('/'));
3369 : 0 : break;
3370 : :
3371 : : case INET_PROT_VND_SUN_STAR_TDOC:
3372 [ # # ][ # # ]: 0 : if (pPos == pEnd || *pPos != '/')
3373 : 0 : return false;
3374 [ # # ][ # # ]: 0 : while (pPos < pEnd && *pPos != nFragmentDelimiter)
[ # # ]
3375 : : {
3376 : : EscapeType eEscapeType;
3377 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
3378 : : '%', eMechanism,
3379 [ # # ]: 0 : eCharset, eEscapeType);
3380 [ # # ][ # # ]: 0 : if (eEscapeType == ESCAPE_NO && nUTF32 == '/')
3381 [ # # ]: 0 : aTheSynPath.append(sal_Unicode('/'));
3382 : : else
3383 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3384 [ # # ]: 0 : PART_PCHAR, '%', eCharset, false);
3385 : : }
3386 : 0 : break;
3387 : :
3388 : : case INET_PROT_GENERIC:
3389 : : case INET_PROT_SFTP:
3390 [ + + ][ + - ]: 28232 : while (pPos < pEnd && *pPos != nFragmentDelimiter)
[ + + ]
3391 : : {
3392 : : EscapeType eEscapeType;
3393 : : sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
3394 : : '%', eMechanism,
3395 [ + - ]: 27944 : eCharset, eEscapeType);
3396 : : appendUCS4(aTheSynPath, nUTF32, eEscapeType, bOctets,
3397 [ + - ]: 27944 : PART_URIC, '%', eCharset, true);
3398 : : }
3399 [ - + ]: 288 : if (aTheSynPath.getLength() == 0)
3400 : 0 : return false;
3401 : 288 : break;
3402 : : default:
3403 : : OSL_ASSERT(false);
3404 : 0 : break;
3405 : : }
3406 : :
3407 : 819023 : *pBegin = pPos;
3408 [ + - ]: 819023 : rSynPath = aTheSynPath;
3409 : 819023 : return true;
3410 : : }
3411 : :
3412 : 19861 : bool INetURLObject::setPath(rtl::OUString const & rThePath, bool bOctets,
3413 : : EncodeMechanism eMechanism,
3414 : : rtl_TextEncoding eCharset)
3415 : : {
3416 : 19861 : rtl::OUStringBuffer aSynPath;
3417 : 19861 : sal_Unicode const * p = rThePath.getStr();
3418 : 19861 : sal_Unicode const * pEnd = p + rThePath.getLength();
3419 [ + - ][ - + ]: 19861 : if (!parsePath(m_eScheme, &p, pEnd, bOctets, eMechanism, eCharset, false,
[ - + ]
3420 [ + - ]: 19861 : '/', 0x80000000, 0x80000000, 0x80000000, aSynPath)
3421 : : || p != pEnd)
3422 : 0 : return false;
3423 [ + - ][ + - ]: 19861 : sal_Int32 nDelta = m_aPath.set(m_aAbsURIRef, aSynPath.makeStringAndClear());
3424 : 19861 : m_aQuery += nDelta;
3425 : 19861 : m_aFragment += nDelta;
3426 : 19861 : return true;
3427 : : }
3428 : :
3429 : 1166829 : bool INetURLObject::checkHierarchical() const {
3430 [ - + ]: 1166829 : if (m_eScheme == INET_PROT_VND_SUN_STAR_EXPAND) {
3431 : : OSL_FAIL(
3432 : : "INetURLObject::checkHierarchical vnd.sun.star.expand");
3433 : 0 : return true;
3434 : : } else {
3435 : 1166829 : return getSchemeInfo().m_bHierarchical;
3436 : : }
3437 : : }
3438 : :
3439 : 10387 : bool INetURLObject::appendSegment(rtl::OUString const & rTheSegment,
3440 : : bool bOctets, EncodeMechanism eMechanism,
3441 : : rtl_TextEncoding eCharset)
3442 : : {
3443 : : return insertName(rTheSegment, bOctets, false, LAST_SEGMENT, true,
3444 : 10387 : eMechanism, eCharset);
3445 : : }
3446 : :
3447 : 598274 : INetURLObject::SubString INetURLObject::getSegment(sal_Int32 nIndex,
3448 : : bool bIgnoreFinalSlash)
3449 : : const
3450 : : {
3451 : : DBG_ASSERT(nIndex >= 0 || nIndex == LAST_SEGMENT,
3452 : : "INetURLObject::getSegment(): Bad index");
3453 : :
3454 [ + + ]: 598274 : if (!checkHierarchical())
3455 : 553417 : return SubString();
3456 : :
3457 : : sal_Unicode const * pPathBegin
3458 : 44857 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
3459 : 44857 : sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
3460 : : sal_Unicode const * pSegBegin;
3461 : : sal_Unicode const * pSegEnd;
3462 [ + + ]: 44857 : if (nIndex == LAST_SEGMENT)
3463 : : {
3464 : 24983 : pSegEnd = pPathEnd;
3465 [ + + ][ + - ]: 24983 : if (bIgnoreFinalSlash && pSegEnd > pPathBegin && pSegEnd[-1] == '/')
[ + + ]
3466 : 2247 : --pSegEnd;
3467 [ + + ]: 24983 : if (pSegEnd <= pPathBegin)
3468 : 15 : return SubString();
3469 : 24968 : pSegBegin = pSegEnd - 1;
3470 [ + + ][ + + ]: 326661 : while (pSegBegin > pPathBegin && *pSegBegin != '/')
[ + + ]
3471 : 301693 : --pSegBegin;
3472 : : }
3473 : : else
3474 : : {
3475 : 19874 : pSegBegin = pPathBegin;
3476 [ + + ]: 97686 : while (nIndex-- > 0)
3477 [ + + ]: 451434 : do
3478 : : {
3479 : 451434 : ++pSegBegin;
3480 [ - + ]: 451434 : if (pSegBegin >= pPathEnd)
3481 : 0 : return SubString();
3482 : : }
3483 : : while (*pSegBegin != '/');
3484 : 19874 : pSegEnd = pSegBegin + 1;
3485 [ + - ][ + + ]: 122121 : while (pSegEnd < pPathEnd && *pSegEnd != '/')
[ + + ]
3486 : 102247 : ++pSegEnd;
3487 : : }
3488 : :
3489 : 44842 : return SubString(pSegBegin - m_aAbsURIRef.getStr(),
3490 : 598274 : pSegEnd - pSegBegin);
3491 : : }
3492 : :
3493 : 14082 : bool INetURLObject::insertName(rtl::OUString const & rTheName, bool bOctets,
3494 : : bool bAppendFinalSlash, sal_Int32 nIndex,
3495 : : bool bIgnoreFinalSlash,
3496 : : EncodeMechanism eMechanism,
3497 : : rtl_TextEncoding eCharset)
3498 : : {
3499 : : DBG_ASSERT(nIndex >= 0 || nIndex == LAST_SEGMENT,
3500 : : "INetURLObject::insertName(): Bad index");
3501 : :
3502 [ + + ]: 14082 : if (!checkHierarchical())
3503 : 1580 : return false;
3504 : :
3505 : : sal_Unicode const * pPathBegin
3506 : 12502 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
3507 : 12502 : sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
3508 : : sal_Unicode const * pPrefixEnd;
3509 : : bool bInsertSlash;
3510 : : sal_Unicode const * pSuffixBegin;
3511 [ + - ]: 12502 : if (nIndex == LAST_SEGMENT)
3512 : : {
3513 : 12502 : pPrefixEnd = pPathEnd;
3514 [ + - ][ + - ]: 12502 : if (bIgnoreFinalSlash && pPrefixEnd > pPathBegin &&
[ + + ]
3515 : 12502 : pPrefixEnd[-1] == '/')
3516 : : {
3517 : 3798 : --pPrefixEnd;
3518 : : }
3519 : 12502 : bInsertSlash = bAppendFinalSlash;
3520 : 12502 : pSuffixBegin = pPathEnd;
3521 : : }
3522 [ # # ]: 0 : else if (nIndex == 0)
3523 : : {
3524 : 0 : pPrefixEnd = pPathBegin;
3525 : : bInsertSlash =
3526 : : (pPathBegin < pPathEnd && *pPathBegin != '/') ||
3527 [ # # ][ # # ]: 0 : (pPathBegin == pPathEnd && bAppendFinalSlash);
[ # # ][ # # ]
3528 : : pSuffixBegin =
3529 : : (pPathEnd - pPathBegin == 1 && *pPathBegin == '/' &&
3530 : 0 : !bAppendFinalSlash && bIgnoreFinalSlash)
3531 [ # # ][ # # ]: 0 : ? pPathEnd : pPathBegin;
[ # # ][ # # ]
3532 : : }
3533 : : else
3534 : : {
3535 : 0 : pPrefixEnd = pPathBegin;
3536 : 0 : sal_Unicode const * pEnd = pPathEnd;
3537 [ # # ][ # # ]: 0 : if (bIgnoreFinalSlash && pEnd > pPathBegin && pEnd[-1] == '/')
[ # # ]
3538 : 0 : --pEnd;
3539 [ # # ][ # # ]: 0 : bool bSkip = pPrefixEnd < pEnd && *pPrefixEnd == '/';
3540 : 0 : bInsertSlash = false;
3541 : 0 : pSuffixBegin = pPathEnd;
3542 [ # # ]: 0 : while (nIndex-- > 0)
3543 : 0 : for (;;)
3544 : : {
3545 [ # # ]: 0 : if (bSkip)
3546 : 0 : ++pPrefixEnd;
3547 : 0 : bSkip = true;
3548 [ # # ]: 0 : if (pPrefixEnd >= pEnd)
3549 : : {
3550 [ # # ]: 0 : if (nIndex == 0)
3551 : : {
3552 : 0 : bInsertSlash = bAppendFinalSlash;
3553 : 0 : break;
3554 : : }
3555 : : else
3556 : 0 : return false;
3557 : : }
3558 [ # # ]: 0 : if (*pPrefixEnd == '/')
3559 : : {
3560 : 0 : pSuffixBegin = pPrefixEnd;
3561 : 0 : break;
3562 : : }
3563 : : }
3564 : : }
3565 : :
3566 : 12502 : rtl::OUStringBuffer aNewPath;
3567 [ + - ]: 12502 : aNewPath.append(pPathBegin, pPrefixEnd - pPathBegin);
3568 [ + - ]: 12502 : aNewPath.append(sal_Unicode('/'));
3569 : 12502 : aNewPath.append(encodeText(rTheName, bOctets, PART_PCHAR, getEscapePrefix(),
3570 [ + - ][ + - ]: 12502 : eMechanism, eCharset, true));
3571 [ + + ]: 12502 : if (bInsertSlash) {
3572 [ + - ]: 76 : aNewPath.append(sal_Unicode('/'));
3573 : : }
3574 [ + - ]: 12502 : aNewPath.append(pSuffixBegin, pPathEnd - pSuffixBegin);
3575 : :
3576 : : return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
3577 [ + - ][ + - ]: 14082 : RTL_TEXTENCODING_UTF8);
3578 : : }
3579 : :
3580 : 553841 : bool INetURLObject::clearQuery()
3581 : : {
3582 [ - + ]: 553841 : if (HasError())
3583 : 0 : return false;
3584 [ - + ]: 553841 : if (m_aQuery.isPresent())
3585 : : {
3586 : 0 : lcl_Erase(m_aAbsURIRef, m_aQuery.getBegin() - 1,
3587 : 0 : m_aQuery.getLength() + 1);
3588 : 0 : m_aFragment += m_aQuery.clear() - 1;
3589 : : }
3590 : 553841 : return false;
3591 : : }
3592 : :
3593 : 0 : bool INetURLObject::setQuery(rtl::OUString const & rTheQuery, bool bOctets,
3594 : : EncodeMechanism eMechanism,
3595 : : rtl_TextEncoding eCharset)
3596 : : {
3597 [ # # ]: 0 : if (!getSchemeInfo().m_bQuery)
3598 : 0 : return false;
3599 : : rtl::OUString aNewQuery(encodeText(rTheQuery, bOctets, PART_URIC,
3600 : 0 : getEscapePrefix(), eMechanism, eCharset,
3601 [ # # ]: 0 : true));
3602 : : sal_Int32 nDelta;
3603 [ # # ]: 0 : if (m_aQuery.isPresent())
3604 [ # # ]: 0 : nDelta = m_aQuery.set(m_aAbsURIRef, aNewQuery);
3605 : : else
3606 : : {
3607 [ # # ]: 0 : m_aAbsURIRef.insert(m_aPath.getEnd(), sal_Unicode('?'));
3608 [ # # ]: 0 : nDelta = m_aQuery.set(m_aAbsURIRef, aNewQuery, m_aPath.getEnd() + 1)
3609 : 0 : + 1;
3610 : : }
3611 : 0 : m_aFragment += nDelta;
3612 : 0 : return true;
3613 : : }
3614 : :
3615 : 553856 : bool INetURLObject::clearFragment()
3616 : : {
3617 [ + + ]: 553856 : if (HasError())
3618 : 6 : return false;
3619 [ + + ]: 553850 : if (m_aFragment.isPresent())
3620 : : {
3621 : 5 : m_aAbsURIRef.setLength(m_aFragment.getBegin() - 1);
3622 : 5 : m_aFragment.clear();
3623 : : }
3624 : 553856 : return true;
3625 : : }
3626 : :
3627 : 0 : bool INetURLObject::setFragment(rtl::OUString const & rTheFragment,
3628 : : bool bOctets, EncodeMechanism eMechanism,
3629 : : rtl_TextEncoding eCharset)
3630 : : {
3631 [ # # ]: 0 : if (HasError())
3632 : 0 : return false;
3633 : : rtl::OUString aNewFragment(encodeText(rTheFragment, bOctets, PART_URIC,
3634 : 0 : getEscapePrefix(), eMechanism,
3635 [ # # ]: 0 : eCharset, true));
3636 [ # # ]: 0 : if (m_aFragment.isPresent())
3637 [ # # ]: 0 : m_aFragment.set(m_aAbsURIRef, aNewFragment);
3638 : : else
3639 : : {
3640 [ # # ]: 0 : m_aAbsURIRef.append(sal_Unicode('#'));
3641 [ # # ]: 0 : m_aFragment.set(m_aAbsURIRef, aNewFragment, m_aAbsURIRef.getLength());
3642 : : }
3643 : 0 : return true;
3644 : : }
3645 : :
3646 : 34 : bool INetURLObject::hasDosVolume(FSysStyle eStyle) const
3647 : : {
3648 : 34 : sal_Unicode const * p = m_aAbsURIRef.getStr() + m_aPath.getBegin();
3649 : : return (eStyle & FSYS_DOS) != 0
3650 : 34 : && m_aPath.getLength() >= 3
3651 : : && p[0] == '/'
3652 : 34 : && INetMIME::isAlpha(p[1])
3653 : 34 : && p[2] == ':'
3654 [ + - + - ]: 102 : && (m_aPath.getLength() == 3 || p[3] == '/');
[ - + ][ # # ]
[ # # ]
[ + - + - ]
3655 : : }
3656 : :
3657 : : // static
3658 : 13937 : rtl::OUString INetURLObject::encodeText(sal_Unicode const * pBegin,
3659 : : sal_Unicode const * pEnd, bool bOctets,
3660 : : Part ePart, sal_Char cEscapePrefix,
3661 : : EncodeMechanism eMechanism,
3662 : : rtl_TextEncoding eCharset,
3663 : : bool bKeepVisibleEscapes)
3664 : : {
3665 : 13937 : rtl::OUStringBuffer aResult;
3666 [ + + ]: 139171 : while (pBegin < pEnd)
3667 : : {
3668 : : EscapeType eEscapeType;
3669 : : sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd, bOctets, cEscapePrefix,
3670 [ + - ]: 125234 : eMechanism, eCharset, eEscapeType);
3671 : : appendUCS4(aResult, nUTF32, eEscapeType, bOctets, ePart,
3672 [ + - ]: 125234 : cEscapePrefix, eCharset, bKeepVisibleEscapes);
3673 : : }
3674 [ + - ]: 13937 : return aResult.makeStringAndClear();
3675 : : }
3676 : :
3677 : : // static
3678 : 1925216 : rtl::OUString INetURLObject::decode(sal_Unicode const * pBegin,
3679 : : sal_Unicode const * pEnd,
3680 : : sal_Char cEscapePrefix,
3681 : : DecodeMechanism eMechanism,
3682 : : rtl_TextEncoding eCharset)
3683 : : {
3684 [ + + + ]: 1925216 : switch (eMechanism)
3685 : : {
3686 : : case NO_DECODE:
3687 : 1800024 : return rtl::OUString(pBegin, pEnd - pBegin);
3688 : :
3689 : : case DECODE_TO_IURI:
3690 : 109533 : eCharset = RTL_TEXTENCODING_UTF8;
3691 : 109533 : break;
3692 : :
3693 : : default:
3694 : 15659 : break;
3695 : : }
3696 : 125192 : rtl::OUStringBuffer aResult;
3697 [ + + ]: 1506415 : while (pBegin < pEnd)
3698 : : {
3699 : : EscapeType eEscapeType;
3700 : : sal_uInt32 nUTF32 = getUTF32(pBegin, pEnd, false, cEscapePrefix,
3701 [ + - ]: 1381223 : WAS_ENCODED, eCharset, eEscapeType);
3702 [ + - + - ]: 1381223 : switch (eEscapeType)
3703 : : {
3704 : : case ESCAPE_NO:
3705 [ + - ]: 1381006 : aResult.append(sal_Unicode(nUTF32));
3706 : 1381006 : break;
3707 : :
3708 : : case ESCAPE_OCTET:
3709 [ # # ]: 0 : appendEscape(aResult, cEscapePrefix, nUTF32);
3710 : 0 : break;
3711 : :
3712 : : case ESCAPE_UTF32:
3713 [ + + ]: 217 : if (
[ - + # # ]
[ + + ][ + - ]
3714 : 217 : INetMIME::isUSASCII(nUTF32) &&
3715 : : (
3716 : : eMechanism == DECODE_TO_IURI ||
3717 : : (
3718 : : eMechanism == DECODE_UNAMBIGUOUS &&
3719 : 0 : mustEncode(nUTF32, PART_UNAMBIGUOUS)
3720 : : )
3721 : : )
3722 : : )
3723 : : {
3724 [ + - ]: 38 : appendEscape(aResult, cEscapePrefix, nUTF32);
3725 : : }
3726 : : else
3727 [ + - ]: 179 : aResult.append(sal_Unicode(nUTF32));
3728 : 1381223 : break;
3729 : : }
3730 : : }
3731 [ + - ]: 1925216 : return aResult.makeStringAndClear();
3732 : : }
3733 : :
3734 : 4463 : rtl::OUString INetURLObject::GetURLNoPass(DecodeMechanism eMechanism,
3735 : : rtl_TextEncoding eCharset) const
3736 : : {
3737 [ + - ]: 4463 : INetURLObject aTemp(*this);
3738 [ + - ]: 4463 : aTemp.clearPassword();
3739 [ + - ][ + - ]: 4463 : return aTemp.GetMainURL(eMechanism, eCharset);
3740 : : }
3741 : :
3742 : 5 : rtl::OUString INetURLObject::GetURLNoMark(DecodeMechanism eMechanism,
3743 : : rtl_TextEncoding eCharset) const
3744 : : {
3745 [ + - ]: 5 : INetURLObject aTemp(*this);
3746 [ + - ]: 5 : aTemp.clearFragment();
3747 [ + - ][ + - ]: 5 : return aTemp.GetMainURL(eMechanism, eCharset);
3748 : : }
3749 : :
3750 : : rtl::OUString
3751 : 0 : INetURLObject::getAbbreviated(
3752 : : star::uno::Reference< star::util::XStringWidth > const & rStringWidth,
3753 : : sal_Int32 nWidth,
3754 : : DecodeMechanism eMechanism,
3755 : : rtl_TextEncoding eCharset)
3756 : : const
3757 : : {
3758 : : OSL_ENSURE(rStringWidth.is(), "specification violation");
3759 : 0 : sal_Char cEscapePrefix = getEscapePrefix();
3760 : 0 : rtl::OUStringBuffer aBuffer;
3761 : : // make sure that the scheme is copied for generic schemes: getSchemeInfo().m_pScheme
3762 : : // is empty ("") in that case, so take the scheme from m_aAbsURIRef
3763 [ # # ]: 0 : if (m_eScheme != INET_PROT_GENERIC)
3764 : : {
3765 [ # # ]: 0 : aBuffer.appendAscii(getSchemeInfo().m_pScheme);
3766 : : }
3767 : : else
3768 : : {
3769 [ # # ]: 0 : if (m_aAbsURIRef.getLength() != 0)
3770 : : {
3771 : : sal_Unicode const * pSchemeBegin
3772 : 0 : = m_aAbsURIRef.getStr();
3773 : 0 : sal_Unicode const * pSchemeEnd = pSchemeBegin;
3774 : :
3775 [ # # ]: 0 : while (pSchemeEnd[0] != ':')
3776 : : {
3777 : 0 : ++pSchemeEnd;
3778 : : }
3779 [ # # ]: 0 : aBuffer.append(pSchemeBegin, pSchemeEnd - pSchemeBegin);
3780 : : }
3781 : : }
3782 [ # # ]: 0 : aBuffer.append(static_cast< sal_Unicode >(':'));
3783 : 0 : bool bAuthority = getSchemeInfo().m_bAuthority;
3784 : : sal_Unicode const * pCoreBegin
3785 [ # # ]: 0 : = m_aAbsURIRef.getStr() + (bAuthority ? getAuthorityBegin() :
3786 [ # # ]: 0 : m_aPath.getBegin());
3787 : : sal_Unicode const * pCoreEnd
3788 : 0 : = m_aAbsURIRef.getStr() + m_aPath.getBegin() + m_aPath.getLength();
3789 : 0 : bool bSegment = false;
3790 [ # # ]: 0 : if (getSchemeInfo().m_bHierarchical)
3791 : : {
3792 : 0 : rtl::OUString aRest;
3793 [ # # ]: 0 : if (m_aQuery.isPresent())
3794 [ # # ]: 0 : aRest = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("?..."));
3795 [ # # ]: 0 : else if (m_aFragment.isPresent())
3796 [ # # ]: 0 : aRest = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("#..."));
3797 : 0 : rtl::OUStringBuffer aTrailer;
3798 : 0 : sal_Unicode const * pBegin = pCoreBegin;
3799 : 0 : sal_Unicode const * pEnd = pCoreEnd;
3800 : 0 : sal_Unicode const * pPrefixBegin = pBegin;
3801 : 0 : sal_Unicode const * pSuffixEnd = pEnd;
3802 : 0 : bool bPrefix = true;
3803 : 0 : bool bSuffix = true;
3804 [ # # ][ # # ]: 0 : do
[ # # ]
3805 : : {
3806 [ # # ]: 0 : if (bSuffix)
3807 : : {
3808 : 0 : sal_Unicode const * p = pSuffixEnd - 1;
3809 [ # # ][ # # ]: 0 : if (pSuffixEnd == pCoreEnd && *p == '/')
3810 : 0 : --p;
3811 [ # # ]: 0 : while (*p != '/')
3812 : 0 : --p;
3813 [ # # ][ # # ]: 0 : if (bAuthority && p == pCoreBegin + 1)
3814 : 0 : --p;
3815 : : rtl::OUString
3816 : : aSegment(decode(p + (p == pBegin && pBegin != pCoreBegin ?
3817 : : 1 : 0),
3818 : : pSuffixEnd,
3819 : : cEscapePrefix,
3820 : : eMechanism,
3821 [ # # ][ # # ]: 0 : eCharset));
[ # # ]
3822 : 0 : pSuffixEnd = p;
3823 [ # # ]: 0 : rtl::OUStringBuffer aResult(aBuffer);
3824 [ # # ]: 0 : if (pSuffixEnd != pBegin)
3825 [ # # ]: 0 : aResult.appendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
3826 [ # # ]: 0 : aResult.append(aSegment);
3827 [ # # ]: 0 : aResult.append(aTrailer.toString());
3828 [ # # ]: 0 : aResult.append(aRest);
3829 [ # # # # ]: 0 : if (rStringWidth->
3830 [ # # ][ # # ]: 0 : queryStringWidth(aResult.makeStringAndClear())
3831 : : <= nWidth)
3832 : : {
3833 [ # # ]: 0 : aTrailer.insert(0, aSegment);
3834 : 0 : bSegment = true;
3835 : 0 : pEnd = pSuffixEnd;
3836 : : }
3837 : : else
3838 : 0 : bSuffix = false;
3839 [ # # ]: 0 : if (pPrefixBegin > pSuffixEnd)
3840 : 0 : pPrefixBegin = pSuffixEnd;
3841 [ # # ]: 0 : if (pBegin == pEnd)
3842 [ # # ][ # # ]: 0 : break;
3843 : : }
3844 [ # # ]: 0 : if (bPrefix)
3845 : : {
3846 : : sal_Unicode const * p
3847 : : = pPrefixBegin
3848 : : + (bAuthority && pPrefixBegin == pCoreBegin ? 2 :
3849 [ # # ][ # # ]: 0 : 1);
3850 : : OSL_ASSERT(p <= pEnd);
3851 [ # # ][ # # ]: 0 : while (p < pEnd && *p != '/')
[ # # ]
3852 : 0 : ++p;
3853 [ # # ][ # # ]: 0 : if (p == pCoreEnd - 1 && *p == '/')
3854 : 0 : ++p;
3855 : : rtl::OUString
3856 : : aSegment(decode(pPrefixBegin
3857 : : + (pPrefixBegin == pCoreBegin ? 0 :
3858 : : 1),
3859 : : p == pEnd ? p : p + 1,
3860 : : cEscapePrefix,
3861 : : eMechanism,
3862 [ # # ][ # # ]: 0 : eCharset));
3863 : 0 : pPrefixBegin = p;
3864 [ # # ]: 0 : rtl::OUStringBuffer aResult(aBuffer);
3865 [ # # ]: 0 : aResult.append(aSegment);
3866 [ # # ]: 0 : if (pPrefixBegin != pEnd)
3867 [ # # ]: 0 : aResult.appendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
3868 [ # # ]: 0 : aResult.append(aTrailer.toString());
3869 [ # # ]: 0 : aResult.append(aRest);
3870 [ # # # # ]: 0 : if (rStringWidth->
3871 [ # # ][ # # ]: 0 : queryStringWidth(aResult.makeStringAndClear())
3872 : : <= nWidth)
3873 : : {
3874 [ # # ]: 0 : aBuffer.append(aSegment);
3875 : 0 : bSegment = true;
3876 : 0 : pBegin = pPrefixBegin;
3877 : : }
3878 : : else
3879 : 0 : bPrefix = false;
3880 [ # # ]: 0 : if (pPrefixBegin > pSuffixEnd)
3881 : 0 : pSuffixEnd = pPrefixBegin;
3882 [ # # ]: 0 : if (pBegin == pEnd)
3883 [ # # ][ # # ]: 0 : break;
3884 : : }
3885 : : }
3886 : : while (bPrefix || bSuffix);
3887 [ # # ]: 0 : if (bSegment)
3888 : : {
3889 [ # # ][ # # ]: 0 : if (pPrefixBegin != pBegin || pSuffixEnd != pEnd)
3890 [ # # ]: 0 : aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
3891 [ # # ]: 0 : aBuffer.append(aTrailer.toString());
3892 : 0 : }
3893 : : }
3894 [ # # ]: 0 : if (!bSegment)
3895 : : aBuffer.append(decode(pCoreBegin,
3896 : : pCoreEnd,
3897 : : cEscapePrefix,
3898 : : eMechanism,
3899 [ # # ][ # # ]: 0 : eCharset));
3900 [ # # ]: 0 : if (m_aQuery.isPresent())
3901 : : {
3902 [ # # ]: 0 : aBuffer.append(static_cast< sal_Unicode >('?'));
3903 [ # # ][ # # ]: 0 : aBuffer.append(decode(m_aQuery, cEscapePrefix, eMechanism, eCharset));
3904 : : }
3905 [ # # ]: 0 : if (m_aFragment.isPresent())
3906 : : {
3907 [ # # ]: 0 : aBuffer.append(static_cast< sal_Unicode >('#'));
3908 : : aBuffer.
3909 [ # # ][ # # ]: 0 : append(decode(m_aFragment, cEscapePrefix, eMechanism, eCharset));
3910 : : }
3911 [ # # ]: 0 : if (aBuffer.getLength() != 0)
3912 : : {
3913 [ # # ]: 0 : rtl::OUStringBuffer aResult(aBuffer);
3914 [ # # ][ # # ]: 0 : if (rStringWidth->queryStringWidth(aResult.makeStringAndClear())
[ # # ][ # # ]
3915 : : > nWidth)
3916 : 0 : for (sal_Int32 i = aBuffer.getLength();;)
3917 : : {
3918 [ # # ]: 0 : if (i == 0)
3919 : : {
3920 [ # # ]: 0 : aBuffer.setLength(aBuffer.getLength() - 1);
3921 [ # # ]: 0 : if (aBuffer.getLength() == 0)
3922 : 0 : break;
3923 : : }
3924 : : else
3925 : : {
3926 [ # # ]: 0 : aBuffer.setLength(--i);
3927 [ # # ]: 0 : aBuffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
3928 : : }
3929 [ # # ]: 0 : aResult = aBuffer;
3930 [ # # # # ]: 0 : if (rStringWidth->
3931 [ # # ][ # # ]: 0 : queryStringWidth(aResult.makeStringAndClear())
3932 : : <= nWidth)
3933 : 0 : break;
3934 : 0 : }
3935 : : }
3936 [ # # ]: 0 : return aBuffer.makeStringAndClear();
3937 : : }
3938 : :
3939 : 2170 : bool INetURLObject::operator ==(INetURLObject const & rObject) const
3940 : : {
3941 [ + + ]: 2170 : if (m_eScheme != rObject.m_eScheme)
3942 : 275 : return false;
3943 [ + + ]: 1895 : if (m_eScheme == INET_PROT_NOT_VALID)
3944 : 6 : return m_aAbsURIRef.toString() == rObject.m_aAbsURIRef.toString();
3945 [ + - + - : 17001 : if ((m_aScheme.compare(
+ - + - ]
[ + - ][ + -
+ - - + ]
[ - + ]
3946 [ + - ]: 1889 : rObject.m_aScheme, m_aAbsURIRef, rObject.m_aAbsURIRef)
3947 : : != 0)
3948 [ + - ][ + - ]: 3778 : || GetUser(NO_DECODE) != rObject.GetUser(NO_DECODE)
[ + - ][ + - ]
[ # # # # ]
3949 [ + - ][ + - ]: 3778 : || GetPass(NO_DECODE) != rObject.GetPass(NO_DECODE)
[ + - ][ + - ]
[ # # # # ]
3950 : : || !GetHost(NO_DECODE).equalsIgnoreAsciiCase(
3951 [ + - ][ + - ]: 3778 : rObject.GetHost(NO_DECODE))
[ + - ][ + - ]
[ # # # # ]
3952 [ + - ][ + - ]: 1889 : || GetPort() != rObject.GetPort()
3953 [ + - ][ + - ]: 1889 : || HasParam() != rObject.HasParam()
3954 [ + - ][ + - ]: 3778 : || GetParam(NO_DECODE) != rObject.GetParam(NO_DECODE)
[ + - ][ + - ]
[ # # # # ]
3955 [ + - ][ + - ]: 3778 : || GetMsgId(NO_DECODE) != rObject.GetMsgId(NO_DECODE))
[ + - ][ + - ]
[ # # # # ]
3956 : 0 : return false;
3957 [ + - ]: 1889 : rtl::OUString aPath1(GetURLPath(NO_DECODE));
3958 [ + - ]: 1889 : rtl::OUString aPath2(rObject.GetURLPath(NO_DECODE));
3959 [ + - ]: 1889 : switch (m_eScheme)
3960 : : {
3961 : : case INET_PROT_FILE:
3962 : : {
3963 : : // If the URL paths of two file URLs only differ in that one has a
3964 : : // final '/' and the other has not, take the two paths as
3965 : : // equivalent (this could be usefull for other schemes, too):
3966 : 1889 : sal_Int32 nLength = aPath1.getLength();
3967 [ - + - + ]: 1889 : switch (nLength - aPath2.getLength())
3968 : : {
3969 : : case -1:
3970 [ # # ]: 0 : if (aPath2.getStr()[nLength] != '/')
3971 : 0 : return false;
3972 : 0 : break;
3973 : :
3974 : : case 0:
3975 : 8 : break;
3976 : :
3977 : : case 1:
3978 [ # # ]: 0 : if (aPath1.getStr()[--nLength] != '/')
3979 : 0 : return false;
3980 : 0 : break;
3981 : :
3982 : : default:
3983 : 1881 : return false;
3984 : : }
3985 : 8 : return aPath1.compareTo(aPath2, nLength) == 0;
3986 : : }
3987 : :
3988 : : default:
3989 : 0 : return (aPath1 == aPath2) != false;
3990 : 2170 : }
3991 : : }
3992 : :
3993 : 0 : bool INetURLObject::operator <(INetURLObject const & rObject) const
3994 : : {
3995 : : sal_Int32 nCompare = m_aScheme.compare(
3996 : 0 : rObject.m_aScheme, m_aAbsURIRef, rObject.m_aAbsURIRef);
3997 [ # # ]: 0 : if (nCompare < 0) {
3998 : 0 : return true;
3999 [ # # ]: 0 : } else if (nCompare > 0) {
4000 : 0 : return false;
4001 : : }
4002 : 0 : sal_uInt32 nPort1 = GetPort();
4003 : 0 : sal_uInt32 nPort2 = rObject.GetPort();
4004 [ # # ]: 0 : if (nPort1 < nPort2)
4005 : 0 : return true;
4006 [ # # ]: 0 : else if (nPort1 > nPort2)
4007 : 0 : return false;
4008 [ # # ]: 0 : nCompare = GetUser(NO_DECODE).compareTo(rObject.GetUser(NO_DECODE));
4009 [ # # ]: 0 : if (nCompare < 0)
4010 : 0 : return true;
4011 [ # # ]: 0 : else if (nCompare > 0)
4012 : 0 : return false;
4013 [ # # ]: 0 : nCompare = GetPass(NO_DECODE).compareTo(rObject.GetPass(NO_DECODE));
4014 [ # # ]: 0 : if (nCompare < 0)
4015 : 0 : return true;
4016 [ # # ]: 0 : else if (nCompare > 0)
4017 : 0 : return false;
4018 [ # # ]: 0 : nCompare = GetHost(NO_DECODE).compareTo(rObject.GetHost(NO_DECODE));
4019 [ # # ]: 0 : if (nCompare < 0)
4020 : 0 : return true;
4021 [ # # ]: 0 : else if (nCompare > 0)
4022 : 0 : return false;
4023 : 0 : const rtl::OUString &rPath1(GetURLPath(NO_DECODE));
4024 [ # # ]: 0 : const rtl::OUString &rPath2(rObject.GetURLPath(NO_DECODE));
4025 : 0 : nCompare = rPath1.compareTo(rPath2);
4026 [ # # ]: 0 : if (nCompare < 0)
4027 : 0 : return true;
4028 [ # # ]: 0 : else if (nCompare > 0)
4029 : 0 : return false;
4030 [ # # ][ # # ]: 0 : nCompare = GetParam(NO_DECODE).compareTo(rObject.GetParam(NO_DECODE));
4031 [ # # ]: 0 : if (nCompare < 0)
4032 : 0 : return true;
4033 [ # # ]: 0 : else if (nCompare > 0)
4034 : 0 : return false;
4035 [ # # ][ # # ]: 0 : return GetMsgId(NO_DECODE).compareTo(rObject.GetMsgId(NO_DECODE)) < 0;
4036 : : }
4037 : :
4038 : 0 : bool INetURLObject::ConcatData(INetProtocol eTheScheme,
4039 : : rtl::OUString const & rTheUser,
4040 : : rtl::OUString const & rThePassword,
4041 : : rtl::OUString const & rTheHost,
4042 : : sal_uInt32 nThePort,
4043 : : rtl::OUString const & rThePath,
4044 : : EncodeMechanism eMechanism,
4045 : : rtl_TextEncoding eCharset)
4046 : : {
4047 [ # # ]: 0 : setInvalid();
4048 : 0 : m_eScheme = eTheScheme;
4049 [ # # ][ # # ]: 0 : if (HasError() || m_eScheme == INET_PROT_GENERIC)
[ # # ]
4050 : 0 : return false;
4051 [ # # ]: 0 : m_aAbsURIRef.setLength(0);
4052 [ # # ]: 0 : m_aAbsURIRef.appendAscii(getSchemeInfo().m_pScheme);
4053 [ # # ]: 0 : m_aAbsURIRef.append(sal_Unicode(':'));
4054 [ # # ]: 0 : if (getSchemeInfo().m_bAuthority)
4055 : : {
4056 [ # # ]: 0 : m_aAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
4057 : 0 : bool bUserInfo = false;
4058 [ # # ]: 0 : if (getSchemeInfo().m_bUser)
4059 : : {
4060 [ # # ][ # # ]: 0 : if (m_eScheme == INET_PROT_IMAP && rTheUser.isEmpty())
[ # # ]
4061 : : {
4062 [ # # ]: 0 : setInvalid();
4063 : 0 : return false;
4064 : : }
4065 [ # # ]: 0 : if (!rTheUser.isEmpty())
4066 : : {
4067 : : m_aUser.set(m_aAbsURIRef,
4068 : : encodeText(rTheUser, false,
4069 : : m_eScheme == INET_PROT_IMAP ?
4070 : : PART_IMAP_ACHAR :
4071 : : m_eScheme == INET_PROT_VIM ?
4072 : : PART_VIM :
4073 : : PART_USER_PASSWORD,
4074 : 0 : getEscapePrefix(), eMechanism,
4075 : : eCharset, false),
4076 [ # # ][ # # ]: 0 : m_aAbsURIRef.getLength());
[ # # ][ # # ]
4077 : 0 : bUserInfo = true;
4078 : : }
4079 : : }
4080 [ # # ]: 0 : else if (!rTheUser.isEmpty())
4081 : : {
4082 [ # # ]: 0 : setInvalid();
4083 : 0 : return false;
4084 : : }
4085 [ # # ]: 0 : if (!rThePassword.isEmpty())
4086 : : {
4087 [ # # ]: 0 : if (getSchemeInfo().m_bPassword)
4088 : : {
4089 [ # # ]: 0 : m_aAbsURIRef.append(sal_Unicode(':'));
4090 : : m_aAuth.set(m_aAbsURIRef,
4091 : : encodeText(rThePassword, false,
4092 : : m_eScheme == INET_PROT_VIM ?
4093 : : PART_VIM : PART_USER_PASSWORD,
4094 : 0 : getEscapePrefix(), eMechanism,
4095 : : eCharset, false),
4096 [ # # ][ # # ]: 0 : m_aAbsURIRef.getLength());
[ # # ]
4097 : 0 : bUserInfo = true;
4098 : : }
4099 : : else
4100 : : {
4101 [ # # ]: 0 : setInvalid();
4102 : 0 : return false;
4103 : : }
4104 : : }
4105 [ # # ][ # # ]: 0 : if (bUserInfo && getSchemeInfo().m_bHost)
[ # # ]
4106 [ # # ]: 0 : m_aAbsURIRef.append(sal_Unicode('@'));
4107 [ # # ]: 0 : if (getSchemeInfo().m_bHost)
4108 : : {
4109 [ # # ]: 0 : rtl::OUStringBuffer aSynHost(rTheHost);
4110 : 0 : bool bNetBiosName = false;
4111 [ # # # ]: 0 : switch (m_eScheme)
4112 : : {
4113 : : case INET_PROT_FILE:
4114 : : {
4115 : 0 : rtl::OUString sTemp(aSynHost.toString());
4116 [ # # ]: 0 : if (sTemp.equalsIgnoreAsciiCaseAsciiL(
4117 : 0 : RTL_CONSTASCII_STRINGPARAM("localhost")))
4118 : : {
4119 [ # # ]: 0 : aSynHost.setLength(0);
4120 : : }
4121 : 0 : bNetBiosName = true;
4122 : : }
4123 : 0 : break;
4124 : :
4125 : : case INET_PROT_LDAP:
4126 [ # # ][ # # ]: 0 : if (aSynHost.getLength() == 0 && nThePort != 0)
[ # # ]
4127 : : {
4128 [ # # ]: 0 : setInvalid();
4129 : 0 : return false;
4130 : : }
4131 : 0 : break;
4132 : :
4133 : : default:
4134 [ # # ]: 0 : if (aSynHost.getLength() == 0)
4135 : : {
4136 [ # # ]: 0 : setInvalid();
4137 : 0 : return false;
4138 : : }
4139 : 0 : break;
4140 : : }
4141 [ # # ]: 0 : if (!parseHostOrNetBiosName(
4142 : 0 : aSynHost.getStr(), aSynHost.getStr() + aSynHost.getLength(),
4143 [ # # ]: 0 : false, eMechanism, eCharset, bNetBiosName, &aSynHost))
4144 : : {
4145 [ # # ]: 0 : setInvalid();
4146 : 0 : return false;
4147 : : }
4148 : : m_aHost.set(m_aAbsURIRef, aSynHost.makeStringAndClear(),
4149 [ # # ][ # # ]: 0 : m_aAbsURIRef.getLength());
4150 [ # # ]: 0 : if (nThePort != 0)
4151 : : {
4152 [ # # ]: 0 : if (getSchemeInfo().m_bPort)
4153 : : {
4154 [ # # ]: 0 : m_aAbsURIRef.append(sal_Unicode(':'));
4155 : : m_aPort.set(m_aAbsURIRef,
4156 : : rtl::OUString::valueOf(sal_Int64(nThePort)),
4157 [ # # ]: 0 : m_aAbsURIRef.getLength());
4158 : : }
4159 : : else
4160 : : {
4161 [ # # ]: 0 : setInvalid();
4162 : 0 : return false;
4163 : : }
4164 [ # # ]: 0 : }
4165 : : }
4166 [ # # ][ # # ]: 0 : else if (!rTheHost.isEmpty() || nThePort != 0)
[ # # ]
4167 : : {
4168 [ # # ]: 0 : setInvalid();
4169 : 0 : return false;
4170 : : }
4171 : : }
4172 : 0 : rtl::OUStringBuffer aSynPath;
4173 : 0 : sal_Unicode const * p = rThePath.getStr();
4174 : 0 : sal_Unicode const * pEnd = p + rThePath.getLength();
4175 [ # # ][ # # ]: 0 : if (!parsePath(m_eScheme, &p, pEnd, false, eMechanism, eCharset, false, '/',
[ # # ]
4176 [ # # ]: 0 : 0x80000000, 0x80000000, 0x80000000, aSynPath)
4177 : : || p != pEnd)
4178 : : {
4179 [ # # ]: 0 : setInvalid();
4180 : 0 : return false;
4181 : : }
4182 : : m_aPath.set(m_aAbsURIRef, aSynPath.makeStringAndClear(),
4183 [ # # ][ # # ]: 0 : m_aAbsURIRef.getLength());
4184 : 0 : return true;
4185 : : }
4186 : :
4187 : : // static
4188 : 0 : rtl::OUString INetURLObject::GetAbsURL(rtl::OUString const & rTheBaseURIRef,
4189 : : rtl::OUString const & rTheRelURIRef,
4190 : : bool bIgnoreFragment,
4191 : : EncodeMechanism eEncodeMechanism,
4192 : : DecodeMechanism eDecodeMechanism,
4193 : : rtl_TextEncoding eCharset,
4194 : : FSysStyle eStyle)
4195 : : {
4196 : : // Backwards compatibility:
4197 [ # # ][ # # ]: 0 : if (rTheRelURIRef.isEmpty() || rTheRelURIRef[0] == '#')
[ # # ]
4198 : 0 : return rTheRelURIRef;
4199 : :
4200 [ # # ]: 0 : INetURLObject aTheAbsURIRef;
4201 : : bool bWasAbsolute;
4202 : : return INetURLObject(rTheBaseURIRef, eEncodeMechanism, eCharset).
4203 : : convertRelToAbs(rTheRelURIRef, false, aTheAbsURIRef,
4204 : : bWasAbsolute, eEncodeMechanism,
4205 : : eCharset, bIgnoreFragment, false,
4206 [ # # ][ # # ]: 0 : false, eStyle)
[ # # ][ # # ]
[ # # ]
4207 : : || eEncodeMechanism != WAS_ENCODED
4208 : : || eDecodeMechanism != DECODE_TO_IURI
4209 : : || eCharset != RTL_TEXTENCODING_UTF8 ?
4210 : : aTheAbsURIRef.GetMainURL(eDecodeMechanism, eCharset) :
4211 [ # # ][ # # ]: 0 : rTheRelURIRef;
[ # # ][ # # ]
[ # # ][ # # ]
4212 : : }
4213 : :
4214 : 0 : rtl::OUString INetURLObject::getExternalURL(DecodeMechanism eMechanism,
4215 : : rtl_TextEncoding eCharset) const
4216 : : {
4217 : 0 : rtl::OUString aTheExtURIRef;
4218 : : translateToExternal(
4219 [ # # ]: 0 : m_aAbsURIRef.toString(), aTheExtURIRef, eMechanism, eCharset);
4220 : 0 : return aTheExtURIRef;
4221 : : }
4222 : :
4223 : : // static
4224 : 553647 : rtl::OUString INetURLObject::GetScheme(INetProtocol eTheScheme)
4225 : : {
4226 : 553647 : return rtl::OUString::createFromAscii(getSchemeInfo(eTheScheme).m_pPrefix);
4227 : : }
4228 : :
4229 : : // static
4230 : 554250 : INetProtocol INetURLObject::CompareProtocolScheme(rtl::OUString const &
4231 : : rTheAbsURIRef)
4232 : : {
4233 : 554250 : sal_Unicode const * p = rTheAbsURIRef.getStr();
4234 : 554250 : PrefixInfo const * pPrefix = getPrefix(p, p + rTheAbsURIRef.getLength());
4235 [ + + ]: 554250 : return pPrefix ? pPrefix->m_eScheme : INET_PROT_NOT_VALID;
4236 : : }
4237 : :
4238 : 0 : rtl::OUString INetURLObject::GetHostPort(DecodeMechanism eMechanism,
4239 : : rtl_TextEncoding eCharset)
4240 : : {
4241 : : // Check because PROT_VND_SUN_STAR_HELP, PROT_VND_SUN_STAR_HIER, and
4242 : : // PROT_VND_SUN_STAR_PKG misuse m_aHost:
4243 [ # # ]: 0 : if (!getSchemeInfo().m_bHost)
4244 : 0 : return rtl::OUString();
4245 : 0 : rtl::OUStringBuffer aHostPort(decode(m_aHost, getEscapePrefix(),
4246 [ # # ][ # # ]: 0 : eMechanism, eCharset));
4247 [ # # ]: 0 : if (m_aPort.isPresent())
4248 : : {
4249 [ # # ]: 0 : aHostPort.append(sal_Unicode(':'));
4250 : 0 : aHostPort.append(decode(m_aPort, getEscapePrefix(),
4251 [ # # ][ # # ]: 0 : eMechanism, eCharset));
4252 : : }
4253 [ # # ]: 0 : return aHostPort.makeStringAndClear();
4254 : : }
4255 : :
4256 : 557425 : sal_uInt32 INetURLObject::GetPort() const
4257 : : {
4258 [ - + ]: 557425 : if (m_aPort.isPresent())
4259 : : {
4260 : 0 : sal_Unicode const * p = m_aAbsURIRef.getStr() + m_aPort.getBegin();
4261 : 0 : sal_Unicode const * pEnd = p + m_aPort.getLength();
4262 : : sal_uInt32 nThePort;
4263 [ # # ][ # # ]: 0 : if (INetMIME::scanUnsigned(p, pEnd, true, nThePort) && p == pEnd)
[ # # ][ # # ]
4264 : 0 : return nThePort;
4265 : : }
4266 : 557425 : return 0;
4267 : : }
4268 : :
4269 : 124 : bool INetURLObject::SetPort(sal_uInt32 nThePort)
4270 : : {
4271 [ + - ][ + - ]: 124 : if (getSchemeInfo().m_bPort && m_aHost.isPresent())
[ + - ]
4272 : : {
4273 : 124 : rtl::OUString aNewPort(rtl::OUString::valueOf(sal_Int64(nThePort)));
4274 : : sal_Int32 nDelta;
4275 [ - + ]: 124 : if (m_aPort.isPresent())
4276 [ # # ]: 0 : nDelta = m_aPort.set(m_aAbsURIRef, aNewPort);
4277 : : else
4278 : : {
4279 [ + - ]: 124 : m_aAbsURIRef.insert(m_aHost.getEnd(), sal_Unicode(':'));
4280 [ + - ]: 124 : nDelta = m_aPort.set(m_aAbsURIRef, aNewPort, m_aHost.getEnd() + 1)
4281 : 124 : + 1;
4282 : : }
4283 : 124 : m_aPath += nDelta;
4284 : 124 : m_aQuery += nDelta;
4285 : 124 : m_aFragment += nDelta;
4286 : 124 : return true;
4287 : : }
4288 : 124 : return false;
4289 : : }
4290 : :
4291 : 553741 : sal_Int32 INetURLObject::getSegmentCount(bool bIgnoreFinalSlash) const
4292 : : {
4293 [ + + ]: 553741 : if (!checkHierarchical())
4294 : 550868 : return 0;
4295 : :
4296 : 2873 : sal_Unicode const * p = m_aAbsURIRef.getStr() + m_aPath.getBegin();
4297 : 2873 : sal_Unicode const * pEnd = p + m_aPath.getLength();
4298 [ + - ][ + + ]: 2873 : if (bIgnoreFinalSlash && pEnd > p && pEnd[-1] == '/')
[ + + ]
4299 : 72 : --pEnd;
4300 [ + + ][ - + ]: 2873 : sal_Int32 n = p == pEnd || *p == '/' ? 0 : 1;
4301 [ + + ]: 165390 : while (p != pEnd)
4302 [ + + ]: 162517 : if (*p++ == '/')
4303 : 22711 : ++n;
4304 : 553741 : return n;
4305 : : }
4306 : :
4307 : 5327 : bool INetURLObject::removeSegment(sal_Int32 nIndex, bool bIgnoreFinalSlash)
4308 : : {
4309 : 5327 : SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
4310 [ + + ]: 5327 : if (!aSegment.isPresent())
4311 : 4 : return false;
4312 : :
4313 : 5323 : rtl::OUStringBuffer aNewPath;
4314 : 5323 : aNewPath.append(m_aAbsURIRef.getStr() + m_aPath.getBegin(),
4315 [ + - ]: 10646 : aSegment.getBegin() - m_aPath.getBegin());
4316 [ + + ][ + + ]: 5323 : if (bIgnoreFinalSlash && aSegment.getEnd() == m_aPath.getEnd())
[ + + ]
4317 [ + - ]: 4013 : aNewPath.append(sal_Unicode('/'));
4318 : : else
4319 : 1310 : aNewPath.append(m_aAbsURIRef.getStr() + aSegment.getEnd(),
4320 [ + - ]: 2620 : m_aPath.getEnd() - aSegment.getEnd());
4321 [ - + ]: 5323 : if (aNewPath.getLength() == 0 && !aSegment.isEmpty() &&
[ # # # # ]
[ - + ]
4322 : 0 : m_aAbsURIRef[aSegment.getBegin()] == '/')
4323 : : {
4324 [ # # ]: 0 : aNewPath.append(sal_Unicode('/'));
4325 : : }
4326 : :
4327 : : return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
4328 [ + - ][ + - ]: 5327 : RTL_TEXTENCODING_UTF8);
4329 : : }
4330 : :
4331 : 582349 : rtl::OUString INetURLObject::getName(sal_Int32 nIndex, bool bIgnoreFinalSlash,
4332 : : DecodeMechanism eMechanism,
4333 : : rtl_TextEncoding eCharset) const
4334 : : {
4335 : 582349 : SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
4336 [ + + ]: 582349 : if (!aSegment.isPresent())
4337 : 551012 : return rtl::OUString();
4338 : :
4339 : : sal_Unicode const * pSegBegin
4340 : 31337 : = m_aAbsURIRef.getStr() + aSegment.getBegin();
4341 : 31337 : sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
4342 : :
4343 [ + - ][ + - ]: 31337 : if (pSegBegin < pSegEnd && *pSegBegin == '/')
4344 : 31337 : ++pSegBegin;
4345 : 31337 : sal_Unicode const * p = pSegBegin;
4346 [ + + ][ + - ]: 283079 : while (p != pSegEnd && *p != ';')
[ + + ]
4347 : 251742 : ++p;
4348 : :
4349 [ + - ]: 582349 : return decode(pSegBegin, p, getEscapePrefix(), eMechanism, eCharset);
4350 : : }
4351 : :
4352 : 0 : bool INetURLObject::setName(rtl::OUString const & rTheName, sal_Int32 nIndex,
4353 : : bool bIgnoreFinalSlash,
4354 : : EncodeMechanism eMechanism,
4355 : : rtl_TextEncoding eCharset)
4356 : : {
4357 : 0 : SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
4358 [ # # ]: 0 : if (!aSegment.isPresent())
4359 : 0 : return false;
4360 : :
4361 : : sal_Unicode const * pPathBegin
4362 : 0 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
4363 : 0 : sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
4364 : : sal_Unicode const * pSegBegin
4365 : 0 : = m_aAbsURIRef.getStr() + aSegment.getBegin();
4366 : 0 : sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
4367 : :
4368 [ # # ][ # # ]: 0 : if (pSegBegin < pSegEnd && *pSegBegin == '/')
4369 : 0 : ++pSegBegin;
4370 : 0 : sal_Unicode const * p = pSegBegin;
4371 [ # # ][ # # ]: 0 : while (p != pSegEnd && *p != ';')
[ # # ]
4372 : 0 : ++p;
4373 : :
4374 : 0 : rtl::OUStringBuffer aNewPath;
4375 [ # # ]: 0 : aNewPath.append(pPathBegin, pSegBegin - pPathBegin);
4376 : 0 : aNewPath.append(encodeText(rTheName, false, PART_PCHAR, getEscapePrefix(),
4377 [ # # ][ # # ]: 0 : eMechanism, eCharset, true));
4378 [ # # ]: 0 : aNewPath.append(p, pPathEnd - p);
4379 : :
4380 : : return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
4381 [ # # ][ # # ]: 0 : RTL_TEXTENCODING_UTF8);
4382 : : }
4383 : :
4384 : 0 : bool INetURLObject::hasExtension(sal_Int32 nIndex, bool bIgnoreFinalSlash)
4385 : : const
4386 : : {
4387 : 0 : SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
4388 [ # # ]: 0 : if (!aSegment.isPresent())
4389 : 0 : return false;
4390 : :
4391 : : sal_Unicode const * pSegBegin
4392 : 0 : = m_aAbsURIRef.getStr() + aSegment.getBegin();
4393 : 0 : sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
4394 : :
4395 [ # # ][ # # ]: 0 : if (pSegBegin < pSegEnd && *pSegBegin == '/')
4396 : 0 : ++pSegBegin;
4397 [ # # ][ # # ]: 0 : for (sal_Unicode const * p = pSegBegin; p != pSegEnd && *p != ';'; ++p)
[ # # ]
4398 [ # # ][ # # ]: 0 : if (*p == '.' && p != pSegBegin)
4399 : 0 : return true;
4400 : 0 : return false;
4401 : : }
4402 : :
4403 : 3559 : rtl::OUString INetURLObject::getBase(sal_Int32 nIndex, bool bIgnoreFinalSlash,
4404 : : DecodeMechanism eMechanism,
4405 : : rtl_TextEncoding eCharset) const
4406 : : {
4407 : 3559 : SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
4408 [ + + ]: 3559 : if (!aSegment.isPresent())
4409 : 1122 : return rtl::OUString();
4410 : :
4411 : : sal_Unicode const * pSegBegin
4412 : 2437 : = m_aAbsURIRef.getStr() + aSegment.getBegin();
4413 : 2437 : sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
4414 : :
4415 [ + - ][ + - ]: 2437 : if (pSegBegin < pSegEnd && *pSegBegin == '/')
4416 : 2437 : ++pSegBegin;
4417 : 2437 : sal_Unicode const * pExtension = 0;
4418 : 2437 : sal_Unicode const * p = pSegBegin;
4419 [ + + ][ + - ]: 33655 : for (; p != pSegEnd && *p != ';'; ++p)
[ + + ]
4420 [ + + ][ + - ]: 31218 : if (*p == '.' && p != pSegBegin)
4421 : 2222 : pExtension = p;
4422 [ + + ]: 2437 : if (!pExtension)
4423 : 215 : pExtension = p;
4424 : :
4425 : 2437 : return decode(pSegBegin, pExtension, getEscapePrefix(), eMechanism,
4426 [ + - ]: 3559 : eCharset);
4427 : : }
4428 : :
4429 : 0 : bool INetURLObject::setBase(rtl::OUString const & rTheBase, sal_Int32 nIndex,
4430 : : bool bIgnoreFinalSlash,
4431 : : EncodeMechanism eMechanism,
4432 : : rtl_TextEncoding eCharset)
4433 : : {
4434 : 0 : SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
4435 [ # # ]: 0 : if (!aSegment.isPresent())
4436 : 0 : return false;
4437 : :
4438 : : sal_Unicode const * pPathBegin
4439 : 0 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
4440 : 0 : sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
4441 : : sal_Unicode const * pSegBegin
4442 : 0 : = m_aAbsURIRef.getStr() + aSegment.getBegin();
4443 : 0 : sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
4444 : :
4445 [ # # ][ # # ]: 0 : if (pSegBegin < pSegEnd && *pSegBegin == '/')
4446 : 0 : ++pSegBegin;
4447 : 0 : sal_Unicode const * pExtension = 0;
4448 : 0 : sal_Unicode const * p = pSegBegin;
4449 [ # # ][ # # ]: 0 : for (; p != pSegEnd && *p != ';'; ++p)
[ # # ]
4450 [ # # ][ # # ]: 0 : if (*p == '.' && p != pSegBegin)
4451 : 0 : pExtension = p;
4452 [ # # ]: 0 : if (!pExtension)
4453 : 0 : pExtension = p;
4454 : :
4455 : 0 : rtl::OUStringBuffer aNewPath;
4456 [ # # ]: 0 : aNewPath.append(pPathBegin, pSegBegin - pPathBegin);
4457 : 0 : aNewPath.append(encodeText(rTheBase, false, PART_PCHAR, getEscapePrefix(),
4458 [ # # ][ # # ]: 0 : eMechanism, eCharset, true));
4459 [ # # ]: 0 : aNewPath.append(pExtension, pPathEnd - pExtension);
4460 : :
4461 : : return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
4462 [ # # ][ # # ]: 0 : RTL_TEXTENCODING_UTF8);
4463 : : }
4464 : :
4465 : 5565 : rtl::OUString INetURLObject::getExtension(sal_Int32 nIndex,
4466 : : bool bIgnoreFinalSlash,
4467 : : DecodeMechanism eMechanism,
4468 : : rtl_TextEncoding eCharset) const
4469 : : {
4470 : 5565 : SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
4471 [ + + ]: 5565 : if (!aSegment.isPresent())
4472 : 1156 : return rtl::OUString();
4473 : :
4474 : : sal_Unicode const * pSegBegin
4475 : 4409 : = m_aAbsURIRef.getStr() + aSegment.getBegin();
4476 : 4409 : sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
4477 : :
4478 [ + + ][ + - ]: 4409 : if (pSegBegin < pSegEnd && *pSegBegin == '/')
4479 : 4405 : ++pSegBegin;
4480 : 4409 : sal_Unicode const * pExtension = 0;
4481 : 4409 : sal_Unicode const * p = pSegBegin;
4482 [ + + ][ + - ]: 64457 : for (; p != pSegEnd && *p != ';'; ++p)
[ + + ]
4483 [ + + ][ + - ]: 60048 : if (*p == '.' && p != pSegBegin)
4484 : 4160 : pExtension = p;
4485 : :
4486 [ + + ]: 4409 : if (!pExtension)
4487 : 249 : return rtl::OUString();
4488 : :
4489 [ + - ]: 5565 : return decode(pExtension + 1, p, getEscapePrefix(), eMechanism, eCharset);
4490 : : }
4491 : :
4492 : 1472 : bool INetURLObject::setExtension(rtl::OUString const & rTheExtension,
4493 : : sal_Int32 nIndex, bool bIgnoreFinalSlash,
4494 : : EncodeMechanism eMechanism,
4495 : : rtl_TextEncoding eCharset)
4496 : : {
4497 : 1472 : SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
4498 [ + + ]: 1472 : if (!aSegment.isPresent())
4499 : 138 : return false;
4500 : :
4501 : : sal_Unicode const * pPathBegin
4502 : 1334 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
4503 : 1334 : sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
4504 : : sal_Unicode const * pSegBegin
4505 : 1334 : = m_aAbsURIRef.getStr() + aSegment.getBegin();
4506 : 1334 : sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
4507 : :
4508 [ + - ][ + - ]: 1334 : if (pSegBegin < pSegEnd && *pSegBegin == '/')
4509 : 1334 : ++pSegBegin;
4510 : 1334 : sal_Unicode const * pExtension = 0;
4511 : 1334 : sal_Unicode const * p = pSegBegin;
4512 [ + + ][ + - ]: 13149 : for (; p != pSegEnd && *p != ';'; ++p)
[ + + ]
4513 [ + + ][ + - ]: 11815 : if (*p == '.' && p != pSegBegin)
4514 : 312 : pExtension = p;
4515 [ + + ]: 1334 : if (!pExtension)
4516 : 1022 : pExtension = p;
4517 : :
4518 : 1334 : rtl::OUStringBuffer aNewPath;
4519 [ + - ]: 1334 : aNewPath.append(pPathBegin, pExtension - pPathBegin);
4520 [ + - ]: 1334 : aNewPath.append(sal_Unicode('.'));
4521 : : aNewPath.append(encodeText(rTheExtension, false, PART_PCHAR,
4522 [ + - ][ + - ]: 1334 : getEscapePrefix(), eMechanism, eCharset, true));
4523 [ + - ]: 1334 : aNewPath.append(p, pPathEnd - p);
4524 : :
4525 : : return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
4526 [ + - ][ + - ]: 1472 : RTL_TEXTENCODING_UTF8);
4527 : : }
4528 : :
4529 : 2 : bool INetURLObject::removeExtension(sal_Int32 nIndex, bool bIgnoreFinalSlash)
4530 : : {
4531 : 2 : SubString aSegment(getSegment(nIndex, bIgnoreFinalSlash));
4532 [ - + ]: 2 : if (!aSegment.isPresent())
4533 : 0 : return false;
4534 : :
4535 : : sal_Unicode const * pPathBegin
4536 : 2 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
4537 : 2 : sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
4538 : : sal_Unicode const * pSegBegin
4539 : 2 : = m_aAbsURIRef.getStr() + aSegment.getBegin();
4540 : 2 : sal_Unicode const * pSegEnd = pSegBegin + aSegment.getLength();
4541 : :
4542 [ + - ][ + - ]: 2 : if (pSegBegin < pSegEnd && *pSegBegin == '/')
4543 : 2 : ++pSegBegin;
4544 : 2 : sal_Unicode const * pExtension = 0;
4545 : 2 : sal_Unicode const * p = pSegBegin;
4546 [ + + ][ + - ]: 26 : for (; p != pSegEnd && *p != ';'; ++p)
[ + + ]
4547 [ + + ][ + - ]: 24 : if (*p == '.' && p != pSegBegin)
4548 : 2 : pExtension = p;
4549 [ - + ]: 2 : if (!pExtension)
4550 : 0 : return true;
4551 : :
4552 : 2 : rtl::OUStringBuffer aNewPath;
4553 [ + - ]: 2 : aNewPath.append(pPathBegin, pExtension - pPathBegin);
4554 [ + - ]: 2 : aNewPath.append(p, pPathEnd - p);
4555 : :
4556 : : return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
4557 [ + - ][ + - ]: 2 : RTL_TEXTENCODING_UTF8);
4558 : : }
4559 : :
4560 : 0 : bool INetURLObject::hasFinalSlash() const
4561 : : {
4562 [ # # ]: 0 : if (!checkHierarchical())
4563 : 0 : return false;
4564 : :
4565 : : sal_Unicode const * pPathBegin
4566 : 0 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
4567 : 0 : sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
4568 [ # # ][ # # ]: 0 : return pPathEnd > pPathBegin && pPathEnd[-1] == '/';
4569 : : }
4570 : :
4571 : 498 : bool INetURLObject::setFinalSlash()
4572 : : {
4573 [ - + ]: 498 : if (!checkHierarchical())
4574 : 0 : return false;
4575 : :
4576 : : sal_Unicode const * pPathBegin
4577 : 498 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
4578 : 498 : sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
4579 [ + + ][ + - ]: 498 : if (pPathEnd > pPathBegin && pPathEnd[-1] == '/')
4580 : 86 : return true;
4581 : :
4582 : 412 : rtl::OUStringBuffer aNewPath;
4583 [ + - ]: 412 : aNewPath.append(pPathBegin, pPathEnd - pPathBegin);
4584 [ + - ]: 412 : aNewPath.append(sal_Unicode('/'));
4585 : :
4586 : : return setPath(aNewPath.makeStringAndClear(), false, NOT_CANONIC,
4587 [ + - ][ + - ]: 498 : RTL_TEXTENCODING_UTF8);
4588 : : }
4589 : :
4590 : 40 : bool INetURLObject::removeFinalSlash()
4591 : : {
4592 [ - + ]: 40 : if (!checkHierarchical())
4593 : 0 : return false;
4594 : :
4595 : : sal_Unicode const * pPathBegin
4596 : 40 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
4597 : 40 : sal_Unicode const * pPathEnd = pPathBegin + m_aPath.getLength();
4598 [ + + ][ + - ]: 40 : if (pPathEnd <= pPathBegin || pPathEnd[-1] != '/')
4599 : 10 : return true;
4600 : :
4601 : 30 : --pPathEnd;
4602 [ - + ][ # # ]: 30 : if (pPathEnd == pPathBegin && *pPathBegin == '/')
4603 : 0 : return false;
4604 : 30 : rtl::OUString aNewPath(pPathBegin, pPathEnd - pPathBegin);
4605 : :
4606 [ + - ]: 40 : return setPath(aNewPath, false, NOT_CANONIC, RTL_TEXTENCODING_UTF8);
4607 : : }
4608 : :
4609 : 20 : bool INetURLObject::setFSysPath(rtl::OUString const & rFSysPath,
4610 : : FSysStyle eStyle)
4611 : : {
4612 : 20 : sal_Unicode const * pFSysBegin = rFSysPath.getStr();
4613 : 20 : sal_Unicode const * pFSysEnd = pFSysBegin + rFSysPath.getLength();
4614 : :
4615 [ + - ][ - + ]: 20 : switch ((eStyle & FSYS_VOS ? 1 : 0)
[ - - + ]
[ + - ]
4616 : : + (eStyle & FSYS_UNX ? 1 : 0)
4617 : : + (eStyle & FSYS_DOS ? 1 : 0)
4618 : : + (eStyle & FSYS_MAC ? 1 : 0))
4619 : : {
4620 : : case 0:
4621 : 0 : return false;
4622 : :
4623 : : case 1:
4624 : 0 : break;
4625 : :
4626 : : default:
4627 [ + - ][ + - ]: 20 : if (eStyle & FSYS_VOS
[ + + ][ + - ]
4628 : : && pFSysEnd - pFSysBegin >= 2
4629 : : && pFSysBegin[0] == '/'
4630 : 10 : && pFSysBegin[1] == '/')
4631 : : {
4632 [ + - ][ - + ]: 10 : if (pFSysEnd - pFSysBegin >= 3
[ # # ][ # # ]
4633 : 10 : && pFSysBegin[2] == '.'
4634 : 0 : && (pFSysEnd - pFSysBegin == 3 || pFSysBegin[3] == '/'))
4635 : : {
4636 : 0 : eStyle = FSYS_VOS; // Production T1
4637 : : break;
4638 : : }
4639 : :
4640 : 10 : sal_Unicode const * p = pFSysBegin + 2;
4641 : 10 : rtl::OUString aHost;
4642 [ + - ][ + - ]: 10 : if (parseHost(p, pFSysEnd, aHost)
[ + - ][ + - ]
[ + - ]
4643 : : && (p == pFSysEnd || *p == '/'))
4644 : : {
4645 : 10 : eStyle = FSYS_VOS; // Production T2
4646 : : break;
4647 [ - + ]: 10 : }
4648 : : }
4649 : :
4650 [ + - ][ + - ]: 10 : if (eStyle & FSYS_DOS
[ + - ][ + - ]
4651 : : && pFSysEnd - pFSysBegin >= 2
4652 : : && pFSysBegin[0] == '\\'
4653 : 10 : && pFSysBegin[1] == '\\')
4654 : : {
4655 : 10 : sal_Unicode const * p = pFSysBegin + 2;
4656 : 10 : rtl::OUString aHost;
4657 [ + - ][ + - ]: 10 : if (parseHost(p, pFSysEnd, aHost)
[ + - ][ + - ]
[ + - ]
4658 : : && (p == pFSysEnd || *p == '\\'))
4659 : : {
4660 : 10 : eStyle = FSYS_DOS; // Production T3
4661 : : break;
4662 [ - + ]: 10 : }
4663 : : }
4664 : :
4665 [ # # ]: 0 : if (eStyle & FSYS_DOS
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4666 : : && pFSysEnd - pFSysBegin >= 2
4667 : 0 : && INetMIME::isAlpha(pFSysBegin[0])
4668 : 0 : && pFSysBegin[1] == ':'
4669 : : && (pFSysEnd - pFSysBegin == 2
4670 : 0 : || pFSysBegin[2] == '/'
4671 : 0 : || pFSysBegin[2] == '\\'))
4672 : : {
4673 : 0 : eStyle = FSYS_DOS; // Productions T4, T5
4674 : 0 : break;
4675 : : }
4676 : :
4677 [ # # ]: 0 : if (!(eStyle & (FSYS_UNX | FSYS_DOS | FSYS_MAC)))
4678 : 0 : return false;
4679 : :
4680 : 0 : eStyle = guessFSysStyleByCounting(pFSysBegin, pFSysEnd, eStyle);
4681 : : // Production T6
4682 : 0 : break;
4683 : : }
4684 : :
4685 [ + - ][ + - ]: 20 : rtl::OUStringBuffer aSynAbsURIRef(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file://")));
4686 : :
4687 [ + - + - : 20 : switch (eStyle)
- ]
4688 : : {
4689 : : case FSYS_VOS:
4690 : : {
4691 : 10 : sal_Unicode const * p = pFSysBegin;
4692 [ + - ][ + - ]: 10 : if (pFSysEnd - p < 2 || *p++ != '/' || *p++ != '/')
[ - + ][ - + ]
4693 : 0 : return false;
4694 [ + - ][ - + ]: 10 : if (p != pFSysEnd && *p == '.'
[ # # ][ # # ]
4695 : 0 : && (pFSysEnd - p == 1 || p[1] == '/'))
4696 : 0 : ++p;
4697 [ + + ]: 310 : for (; p != pFSysEnd; ++p)
4698 [ - + ]: 300 : switch (*p)
4699 : : {
4700 : : case '#':
4701 : : case '%':
4702 [ # # ]: 0 : appendEscape(aSynAbsURIRef, '%', *p);
4703 : 0 : break;
4704 : :
4705 : : default:
4706 [ + - ]: 300 : aSynAbsURIRef.append(*p);
4707 : 300 : break;
4708 : : }
4709 : 10 : break;
4710 : : }
4711 : :
4712 : : case FSYS_UNX:
4713 : : {
4714 : 0 : sal_Unicode const * p = pFSysBegin;
4715 [ # # ][ # # ]: 0 : if (p != pFSysEnd && *p != '/')
4716 : 0 : return false;
4717 [ # # ]: 0 : for (; p != pFSysEnd; ++p)
4718 [ # # ]: 0 : switch (*p)
4719 : : {
4720 : : case '|':
4721 : : case '#':
4722 : : case '%':
4723 [ # # ]: 0 : appendEscape(aSynAbsURIRef, '%', *p);
4724 : 0 : break;
4725 : :
4726 : : default:
4727 [ # # ]: 0 : aSynAbsURIRef.append(*p);
4728 : 0 : break;
4729 : : }
4730 : 0 : break;
4731 : : }
4732 : :
4733 : : case FSYS_DOS:
4734 : : {
4735 : 10 : sal_uInt32 nAltDelimiter = 0x80000000;
4736 : 10 : sal_Unicode const * p = pFSysBegin;
4737 [ + - ][ + - ]: 10 : if (pFSysEnd - p >= 3 && p[0] == '\\' && p[1] == '\\')
[ + - ]
4738 : 10 : p += 2;
4739 : : else
4740 : : {
4741 [ # # ]: 0 : aSynAbsURIRef.append(sal_Unicode('/'));
4742 [ # # # # ]: 0 : if (pFSysEnd - p >= 2
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
4743 : 0 : && INetMIME::isAlpha(p[0])
4744 : 0 : && p[1] == ':'
4745 : 0 : && (pFSysEnd - p == 2 || p[2] == '\\' || p[2] == '/'))
4746 : 0 : nAltDelimiter = '/';
4747 : : }
4748 [ + + ]: 310 : for (; p != pFSysEnd; ++p)
4749 [ + + ][ - + ]: 300 : if (*p == '\\' || *p == nAltDelimiter)
4750 [ + - ]: 20 : aSynAbsURIRef.append(sal_Unicode('/'));
4751 : : else
4752 [ - + ]: 280 : switch (*p)
4753 : : {
4754 : : case '/':
4755 : : case '#':
4756 : : case '%':
4757 [ # # ]: 0 : appendEscape(aSynAbsURIRef, '%', *p);
4758 : 0 : break;
4759 : :
4760 : : default:
4761 [ + - ]: 280 : aSynAbsURIRef.append(*p);
4762 : 280 : break;
4763 : : }
4764 : 10 : break;
4765 : : }
4766 : :
4767 : : case FSYS_MAC:
4768 [ # # ]: 0 : aSynAbsURIRef.append(sal_Unicode('/'));
4769 [ # # ]: 0 : {for (sal_Unicode const * p = pFSysBegin; p != pFSysEnd; ++p)
4770 [ # # # ]: 0 : switch (*p)
4771 : : {
4772 : : case ':':
4773 [ # # ]: 0 : aSynAbsURIRef.append(sal_Unicode('/'));
4774 : 0 : break;
4775 : :
4776 : : case '/':
4777 : : case '|':
4778 : : case '#':
4779 : : case '%':
4780 [ # # ]: 0 : appendEscape(aSynAbsURIRef, '%', *p);
4781 : 0 : break;
4782 : :
4783 : : default:
4784 [ # # ]: 0 : aSynAbsURIRef.append(*p);
4785 : 0 : break;
4786 : : }
4787 : : }
4788 : 0 : break;
4789 : :
4790 : : default:
4791 : : OSL_ASSERT(false);
4792 : 0 : break;
4793 : : }
4794 : :
4795 : : INetURLObject aTemp(aSynAbsURIRef.makeStringAndClear(), WAS_ENCODED,
4796 [ + - ][ + - ]: 20 : RTL_TEXTENCODING_UTF8);
4797 [ - + ]: 20 : if (aTemp.HasError())
4798 : 0 : return false;
4799 : :
4800 [ + - ]: 20 : *this = aTemp;
4801 [ + - ]: 20 : return true;
4802 : : }
4803 : :
4804 : 33 : rtl::OUString INetURLObject::getFSysPath(FSysStyle eStyle,
4805 : : sal_Unicode * pDelimiter) const
4806 : : {
4807 [ - + ]: 33 : if (m_eScheme != INET_PROT_FILE)
4808 : 0 : return rtl::OUString();
4809 : :
4810 [ + + ][ + - ]: 33 : if ((eStyle & FSYS_VOS ? 1 : 0)
[ - + ][ + + ]
4811 : : + (eStyle & FSYS_UNX ? 1 : 0)
4812 : : + (eStyle & FSYS_DOS ? 1 : 0)
4813 : : + (eStyle & FSYS_MAC ? 1 : 0)
4814 : : > 1)
4815 : : {
4816 : : eStyle = eStyle & FSYS_VOS
4817 : 28 : && m_aHost.isPresent()
4818 : 28 : && m_aHost.getLength() > 0 ?
4819 : : FSYS_VOS :
4820 : 28 : hasDosVolume(eStyle)
4821 : : || ((eStyle & FSYS_DOS) != 0
4822 : 28 : && m_aHost.isPresent()
4823 : 28 : && m_aHost.getLength() > 0) ?
4824 : : FSYS_DOS :
4825 : : eStyle & FSYS_UNX
4826 : 56 : && (!m_aHost.isPresent() || m_aHost.getLength() == 0) ?
4827 : : FSYS_UNX :
4828 [ + - + - : 224 : FSysStyle(0);
+ - + - ]
[ + - + -
+ - ][ + -
+ - + - ]
4829 : : }
4830 : :
4831 [ - + + - : 33 : switch (eStyle)
- ]
4832 : : {
4833 : : case FSYS_VOS:
4834 : : {
4835 [ # # ]: 0 : if (pDelimiter)
4836 : 0 : *pDelimiter = '/';
4837 : :
4838 : 0 : rtl::OUStringBuffer aSynFSysPath;
4839 [ # # ]: 0 : aSynFSysPath.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
4840 [ # # ][ # # ]: 0 : if (m_aHost.isPresent() && m_aHost.getLength() > 0)
[ # # ]
4841 : : aSynFSysPath.append(decode(m_aHost, '%', DECODE_WITH_CHARSET,
4842 [ # # ][ # # ]: 0 : RTL_TEXTENCODING_UTF8));
4843 : : else
4844 [ # # ]: 0 : aSynFSysPath.append(sal_Unicode('.'));
4845 : : aSynFSysPath.append(decode(m_aPath, '%', DECODE_WITH_CHARSET,
4846 [ # # ][ # # ]: 0 : RTL_TEXTENCODING_UTF8));
4847 [ # # ]: 0 : return aSynFSysPath.makeStringAndClear();
4848 : : }
4849 : :
4850 : : case FSYS_UNX:
4851 : : {
4852 [ + - ][ - + ]: 28 : if (m_aHost.isPresent() && m_aHost.getLength() > 0)
[ - + ]
4853 : 0 : return rtl::OUString();
4854 : :
4855 [ - + ]: 28 : if (pDelimiter)
4856 : 0 : *pDelimiter = '/';
4857 : :
4858 : : return decode(m_aPath, '%', DECODE_WITH_CHARSET,
4859 : 28 : RTL_TEXTENCODING_UTF8);
4860 : : }
4861 : :
4862 : : case FSYS_DOS:
4863 : : {
4864 [ - + ]: 5 : if (pDelimiter)
4865 : 0 : *pDelimiter = '\\';
4866 : :
4867 : 5 : rtl::OUStringBuffer aSynFSysPath;
4868 [ - + ][ - + ]: 5 : if (m_aHost.isPresent() && m_aHost.getLength() > 0)
[ + - ]
4869 : : {
4870 [ # # ]: 0 : aSynFSysPath.appendAscii(RTL_CONSTASCII_STRINGPARAM("\\\\"));
4871 : : aSynFSysPath.append(decode(m_aHost, '%', DECODE_WITH_CHARSET,
4872 [ # # ][ # # ]: 0 : RTL_TEXTENCODING_UTF8));
4873 [ # # ]: 0 : aSynFSysPath.append(sal_Unicode('\\'));
4874 : : }
4875 : : sal_Unicode const * p
4876 : 5 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
4877 : 5 : sal_Unicode const * pEnd = p + m_aPath.getLength();
4878 : : DBG_ASSERT(p < pEnd && *p == '/',
4879 : : "INetURLObject::getFSysPath(): Bad path");
4880 : 5 : ++p;
4881 [ + + ]: 25 : while (p < pEnd)
4882 : : {
4883 : : EscapeType eEscapeType;
4884 : : sal_uInt32 nUTF32 = getUTF32(p, pEnd, false, '%', WAS_ENCODED,
4885 : : RTL_TEXTENCODING_UTF8,
4886 [ + - ]: 20 : eEscapeType);
4887 [ + - ][ + + ]: 20 : if (eEscapeType == ESCAPE_NO && nUTF32 == '/')
4888 [ + - ]: 5 : aSynFSysPath.append(sal_Unicode('\\'));
4889 : : else
4890 [ + - ]: 20 : aSynFSysPath.appendUtf32(nUTF32);
4891 : : }
4892 [ + - ]: 5 : return aSynFSysPath.makeStringAndClear();
4893 : : }
4894 : :
4895 : : case FSYS_MAC:
4896 : : {
4897 [ # # ][ # # ]: 0 : if (m_aHost.isPresent() && m_aHost.getLength() > 0)
[ # # ]
4898 : 0 : return rtl::OUString();
4899 : :
4900 [ # # ]: 0 : if (pDelimiter)
4901 : 0 : *pDelimiter = ':';
4902 : :
4903 : 0 : rtl::OUStringBuffer aSynFSysPath;
4904 : : sal_Unicode const * p
4905 : 0 : = m_aAbsURIRef.getStr() + m_aPath.getBegin();
4906 : 0 : sal_Unicode const * pEnd = p + m_aPath.getLength();
4907 : : DBG_ASSERT(p < pEnd && *p == '/',
4908 : : "INetURLObject::getFSysPath(): Bad path");
4909 : 0 : ++p;
4910 [ # # ]: 0 : while (p < pEnd)
4911 : : {
4912 : : EscapeType eEscapeType;
4913 : : sal_uInt32 nUTF32 = getUTF32(p, pEnd, false, '%', WAS_ENCODED,
4914 : : RTL_TEXTENCODING_UTF8,
4915 [ # # ]: 0 : eEscapeType);
4916 [ # # ][ # # ]: 0 : if (eEscapeType == ESCAPE_NO && nUTF32 == '/')
4917 [ # # ]: 0 : aSynFSysPath.append(sal_Unicode(':'));
4918 : : else
4919 [ # # ]: 0 : aSynFSysPath.appendUtf32(nUTF32);
4920 : : }
4921 [ # # ]: 0 : return aSynFSysPath.makeStringAndClear();
4922 : : }
4923 : :
4924 : : default:
4925 : 33 : return rtl::OUString();
4926 : : }
4927 : : }
4928 : :
4929 : 3778 : rtl::OUString INetURLObject::GetMsgId(DecodeMechanism eMechanism,
4930 : : rtl_TextEncoding eCharset) const
4931 : : {
4932 [ + - ]: 3778 : if (m_eScheme != INET_PROT_POP3)
4933 : 3778 : return rtl::OUString();
4934 : 0 : sal_Unicode const * p = m_aAbsURIRef.getStr() + m_aPath.getBegin();
4935 : 0 : sal_Unicode const * pEnd = p + m_aPath.getLength();
4936 [ # # ]: 0 : for (; p < pEnd; ++p)
4937 [ # # ]: 0 : if (*p == '<')
4938 : 0 : return decode(p, pEnd, getEscapePrefix(), eMechanism, eCharset);
4939 : 3778 : return rtl::OUString();
4940 : : }
4941 : :
4942 : : // static
4943 : 1645 : void INetURLObject::appendUCS4Escape(rtl::OUStringBuffer & rTheText,
4944 : : sal_Char cEscapePrefix, sal_uInt32 nUCS4)
4945 : : {
4946 : : DBG_ASSERT(nUCS4 < 0x80000000,
4947 : : "INetURLObject::appendUCS4Escape(): Bad char");
4948 [ + - ]: 1645 : if (nUCS4 < 0x80)
4949 : 1645 : appendEscape(rTheText, cEscapePrefix, nUCS4);
4950 [ # # ]: 0 : else if (nUCS4 < 0x800)
4951 : : {
4952 : 0 : appendEscape(rTheText, cEscapePrefix, nUCS4 >> 6 | 0xC0);
4953 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 & 0x3F) | 0x80);
4954 : : }
4955 [ # # ]: 0 : else if (nUCS4 < 0x10000)
4956 : : {
4957 : 0 : appendEscape(rTheText, cEscapePrefix, nUCS4 >> 12 | 0xE0);
4958 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 6 & 0x3F) | 0x80);
4959 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 & 0x3F) | 0x80);
4960 : : }
4961 [ # # ]: 0 : else if (nUCS4 < 0x200000)
4962 : : {
4963 : 0 : appendEscape(rTheText, cEscapePrefix, nUCS4 >> 18 | 0xF0);
4964 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 12 & 0x3F) | 0x80);
4965 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 6 & 0x3F) | 0x80);
4966 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 & 0x3F) | 0x80);
4967 : : }
4968 [ # # ]: 0 : else if (nUCS4 < 0x4000000)
4969 : : {
4970 : 0 : appendEscape(rTheText, cEscapePrefix, nUCS4 >> 24 | 0xF8);
4971 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 18 & 0x3F) | 0x80);
4972 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 12 & 0x3F) | 0x80);
4973 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 6 & 0x3F) | 0x80);
4974 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 & 0x3F) | 0x80);
4975 : : }
4976 : : else
4977 : : {
4978 : 0 : appendEscape(rTheText, cEscapePrefix, nUCS4 >> 30 | 0xFC);
4979 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 24 & 0x3F) | 0x80);
4980 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 18 & 0x3F) | 0x80);
4981 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 12 & 0x3F) | 0x80);
4982 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 >> 6 & 0x3F) | 0x80);
4983 : 0 : appendEscape(rTheText, cEscapePrefix, (nUCS4 & 0x3F) | 0x80);
4984 : : }
4985 : 1645 : }
4986 : :
4987 : : // static
4988 : 15733615 : void INetURLObject::appendUCS4(rtl::OUStringBuffer& rTheText, sal_uInt32 nUCS4,
4989 : : EscapeType eEscapeType, bool bOctets,
4990 : : Part ePart, sal_Char cEscapePrefix,
4991 : : rtl_TextEncoding eCharset,
4992 : : bool bKeepVisibleEscapes)
4993 : : {
4994 : : bool bEscape;
4995 : 15733615 : rtl_TextEncoding eTargetCharset = RTL_TEXTENCODING_DONTKNOW;
4996 [ + + + - ]: 15733615 : switch (eEscapeType)
4997 : : {
4998 : : case ESCAPE_NO:
4999 [ + + ]: 15729872 : if (mustEncode(nUCS4, ePart))
5000 : : {
5001 : 502 : bEscape = true;
5002 : : eTargetCharset = bOctets ? RTL_TEXTENCODING_ISO_8859_1 :
5003 [ - + ]: 502 : RTL_TEXTENCODING_UTF8;
5004 : : }
5005 : : else
5006 : 15729370 : bEscape = false;
5007 : 15729872 : break;
5008 : :
5009 : : case ESCAPE_OCTET:
5010 : 1272 : bEscape = true;
5011 : 1272 : eTargetCharset = RTL_TEXTENCODING_ISO_8859_1;
5012 : 1272 : break;
5013 : :
5014 : : case ESCAPE_UTF32:
5015 [ + + ]: 2471 : if (mustEncode(nUCS4, ePart))
5016 : : {
5017 : 1143 : bEscape = true;
5018 : 1143 : eTargetCharset = eCharset;
5019 : : }
5020 [ + - ][ + - ]: 1328 : else if (bKeepVisibleEscapes && INetMIME::isVisible(nUCS4))
[ + - ]
5021 : : {
5022 : 1328 : bEscape = true;
5023 : 1328 : eTargetCharset = RTL_TEXTENCODING_ASCII_US;
5024 : : }
5025 : : else
5026 : 0 : bEscape = false;
5027 : 2471 : break;
5028 : : default:
5029 : 0 : bEscape = false;
5030 : : }
5031 : :
5032 [ + + ]: 15733615 : if (bEscape)
5033 : : {
5034 [ + + ]: 4245 : switch (eTargetCharset)
5035 : : {
5036 : : default:
5037 : : OSL_FAIL("INetURLObject::appendUCS4(): Unsupported charset");
5038 : : case RTL_TEXTENCODING_ASCII_US:
5039 : : case RTL_TEXTENCODING_ISO_8859_1:
5040 : 2600 : appendEscape(rTheText, cEscapePrefix, nUCS4);
5041 : 2600 : break;
5042 : :
5043 : : case RTL_TEXTENCODING_UTF8:
5044 : 1645 : appendUCS4Escape(rTheText, cEscapePrefix, nUCS4);
5045 : 4245 : break;
5046 : : }
5047 : : }
5048 : : else
5049 : 15729370 : rTheText.append(sal_Unicode(nUCS4));
5050 : 15733615 : }
5051 : :
5052 : : // static
5053 : 18209462 : sal_uInt32 INetURLObject::getUTF32(sal_Unicode const *& rBegin,
5054 : : sal_Unicode const * pEnd, bool bOctets,
5055 : : sal_Char cEscapePrefix,
5056 : : EncodeMechanism eMechanism,
5057 : : rtl_TextEncoding eCharset,
5058 : : EscapeType & rEscapeType)
5059 : : {
5060 : : DBG_ASSERT(rBegin < pEnd, "INetURLObject::getUTF32(): Bad sequence");
5061 : : sal_uInt32 nUTF32 = bOctets ? *rBegin++ :
5062 [ + + ]: 18209462 : INetMIME::getUTF32Character(rBegin, pEnd);
5063 [ + + + - ]: 18209462 : switch (eMechanism)
5064 : : {
5065 : : case ENCODE_ALL:
5066 : 62871 : rEscapeType = ESCAPE_NO;
5067 : 62871 : break;
5068 : :
5069 : : case WAS_ENCODED:
5070 : : {
5071 : : int nWeight1;
5072 : : int nWeight2;
5073 [ + + ][ + - ]: 16407560 : if (nUTF32 == sal_uChar(cEscapePrefix) && rBegin + 1 < pEnd
[ + - ][ + - ]
[ + + ]
5074 : 2688 : && (nWeight1 = INetMIME::getHexWeight(rBegin[0])) >= 0
5075 : 2688 : && (nWeight2 = INetMIME::getHexWeight(rBegin[1])) >= 0)
5076 : : {
5077 : 2688 : rBegin += 2;
5078 : 2688 : nUTF32 = nWeight1 << 4 | nWeight2;
5079 [ - - + ]: 2688 : switch (eCharset)
5080 : : {
5081 : : default:
5082 : : OSL_FAIL(
5083 : : "INetURLObject::getUTF32(): Unsupported charset");
5084 : : case RTL_TEXTENCODING_ASCII_US:
5085 : 0 : rEscapeType = INetMIME::isUSASCII(nUTF32) ?
5086 [ # # ]: 0 : ESCAPE_UTF32 : ESCAPE_OCTET;
5087 : 0 : break;
5088 : :
5089 : : case RTL_TEXTENCODING_ISO_8859_1:
5090 : 0 : rEscapeType = ESCAPE_UTF32;
5091 : 0 : break;
5092 : :
5093 : : case RTL_TEXTENCODING_UTF8:
5094 [ + - ]: 2688 : if (INetMIME::isUSASCII(nUTF32))
5095 : 2688 : rEscapeType = ESCAPE_UTF32;
5096 : : else
5097 : : {
5098 [ # # ][ # # ]: 0 : if (nUTF32 >= 0xC0 && nUTF32 <= 0xF4)
5099 : : {
5100 : : sal_uInt32 nEncoded;
5101 : : int nShift;
5102 : : sal_uInt32 nMin;
5103 [ # # ]: 0 : if (nUTF32 <= 0xDF)
5104 : : {
5105 : 0 : nEncoded = (nUTF32 & 0x1F) << 6;
5106 : 0 : nShift = 0;
5107 : 0 : nMin = 0x80;
5108 : : }
5109 [ # # ]: 0 : else if (nUTF32 <= 0xEF)
5110 : : {
5111 : 0 : nEncoded = (nUTF32 & 0x0F) << 12;
5112 : 0 : nShift = 6;
5113 : 0 : nMin = 0x800;
5114 : : }
5115 : : else
5116 : : {
5117 : 0 : nEncoded = (nUTF32 & 0x07) << 18;
5118 : 0 : nShift = 12;
5119 : 0 : nMin = 0x10000;
5120 : : }
5121 : 0 : sal_Unicode const * p = rBegin;
5122 : 0 : bool bUTF8 = true;
5123 : 0 : for (;;)
5124 : : {
5125 [ # # ][ # # ]: 0 : if (pEnd - p < 3
[ # # ][ # # ]
[ # # ][ # # ]
5126 : 0 : || p[0] != cEscapePrefix
5127 : : || (nWeight1
5128 : 0 : = INetMIME::getHexWeight(p[1]))
5129 : : < 8
5130 : : || nWeight1 > 11
5131 : : || (nWeight2
5132 : 0 : = INetMIME::getHexWeight(p[2]))
5133 : : < 0)
5134 : : {
5135 : 0 : bUTF8 = false;
5136 : 0 : break;
5137 : : }
5138 : 0 : p += 3;
5139 : : nEncoded
5140 : : |= ((nWeight1 & 3) << 4 | nWeight2)
5141 : 0 : << nShift;
5142 [ # # ]: 0 : if (nShift == 0)
5143 : 0 : break;
5144 : 0 : nShift -= 6;
5145 : : }
5146 [ # # ][ # # : 0 : if (bUTF8 && nEncoded >= nMin
# # # # ]
[ # # ][ # # ]
5147 : 0 : && !INetMIME::isHighSurrogate(nEncoded)
5148 : 0 : && !INetMIME::isLowSurrogate(nEncoded)
5149 : : && nEncoded <= 0x10FFFF)
5150 : : {
5151 : 0 : rBegin = p;
5152 : 0 : nUTF32 = nEncoded;
5153 : 0 : rEscapeType = ESCAPE_UTF32;
5154 : 0 : break;
5155 : : }
5156 : : }
5157 : 0 : rEscapeType = ESCAPE_OCTET;
5158 : : }
5159 : 2688 : break;
5160 : : }
5161 : : }
5162 : : else
5163 : 16404872 : rEscapeType = ESCAPE_NO;
5164 : 16407560 : break;
5165 : : }
5166 : :
5167 : : case NOT_CANONIC:
5168 : : {
5169 : : int nWeight1;
5170 : : int nWeight2;
5171 [ + + ][ + - ]: 1739031 : if (nUTF32 == sal_uChar(cEscapePrefix) && rBegin + 1 < pEnd
[ + - ][ + - ]
[ + + ]
5172 : 1272 : && ((nWeight1 = INetMIME::getHexWeight(rBegin[0])) >= 0)
5173 : 1272 : && ((nWeight2 = INetMIME::getHexWeight(rBegin[1])) >= 0))
5174 : : {
5175 : 1272 : rBegin += 2;
5176 : 1272 : nUTF32 = nWeight1 << 4 | nWeight2;
5177 : 1272 : rEscapeType = ESCAPE_OCTET;
5178 : : }
5179 : : else
5180 : 1737759 : rEscapeType = ESCAPE_NO;
5181 : 1739031 : break;
5182 : : }
5183 : : }
5184 : 18209462 : return nUTF32;
5185 : : }
5186 : :
5187 : : // static
5188 : 1110 : sal_uInt32 INetURLObject::scanDomain(sal_Unicode const *& rBegin,
5189 : : sal_Unicode const * pEnd,
5190 : : bool bEager)
5191 : : {
5192 : : enum State { STATE_DOT, STATE_LABEL, STATE_HYPHEN };
5193 : 1110 : State eState = STATE_DOT;
5194 : 1110 : sal_Int32 nLabels = 0;
5195 : 1110 : sal_Unicode const * pLastAlphanumeric = 0;
5196 : 9523 : for (sal_Unicode const * p = rBegin;; ++p)
5197 [ + + - - ]: 8413 : switch (eState)
5198 : : {
5199 : : case STATE_DOT:
5200 [ + + ][ + + ]: 1652 : if (p != pEnd && (INetMIME::isAlphanumeric(*p) || *p == '_'))
[ - + ][ + + ]
5201 : : {
5202 : 1332 : ++nLabels;
5203 : 1332 : eState = STATE_LABEL;
5204 : 1332 : break;
5205 : : }
5206 [ + + ][ - + ]: 320 : if (bEager || nLabels == 0)
5207 : 310 : return 0;
5208 : 10 : rBegin = p - 1;
5209 : 10 : return nLabels;
5210 : :
5211 : : case STATE_LABEL:
5212 [ + + ]: 6761 : if (p != pEnd)
5213 : : {
5214 [ + + ][ + + ]: 6285 : if (INetMIME::isAlphanumeric(*p) || *p == '_')
[ + + ]
5215 : 5429 : break;
5216 [ + + ]: 856 : else if (*p == '.')
5217 : : {
5218 : 542 : eState = STATE_DOT;
5219 : 542 : break;
5220 : : }
5221 [ - + ]: 314 : else if (*p == '-')
5222 : : {
5223 : 0 : pLastAlphanumeric = p;
5224 : 0 : eState = STATE_HYPHEN;
5225 : 0 : break;
5226 : : }
5227 : : }
5228 : 790 : rBegin = p;
5229 : 790 : return nLabels;
5230 : :
5231 : : case STATE_HYPHEN:
5232 [ # # ]: 0 : if (p != pEnd)
5233 : : {
5234 [ # # ][ # # ]: 0 : if (INetMIME::isAlphanumeric(*p) || *p == '_')
[ # # ]
5235 : : {
5236 : 0 : eState = STATE_LABEL;
5237 : 0 : break;
5238 : : }
5239 [ # # ]: 0 : else if (*p == '-')
5240 : 0 : break;
5241 : : }
5242 [ # # ]: 0 : if (bEager)
5243 : 0 : return 0;
5244 : 0 : rBegin = pLastAlphanumeric;
5245 : 0 : return nLabels;
5246 : : }
5247 : : }
5248 : :
5249 : : // static
5250 : 0 : bool INetURLObject::scanIPv6reference(sal_Unicode const *& rBegin,
5251 : : sal_Unicode const * pEnd)
5252 : : {
5253 [ # # ][ # # ]: 0 : if (rBegin != pEnd && *rBegin == '[') {
5254 : 0 : sal_Unicode const * p = rBegin + 1;
5255 : : //TODO: check for valid IPv6address (RFC 2373):
5256 [ # # ][ # # ]: 0 : while (p != pEnd && (INetMIME::isHexDigit(*p) || *p == ':' || *p == '.'))
[ # # ][ # # ]
[ # # ]
5257 : : {
5258 : 0 : ++p;
5259 : : }
5260 [ # # ][ # # ]: 0 : if (p != pEnd && *p == ']') {
5261 : 0 : rBegin = p + 1;
5262 : 0 : return true;
5263 : : }
5264 : : }
5265 : 0 : return false;
5266 : : }
5267 : :
5268 : 194 : rtl::OUString INetURLObject::GetPartBeforeLastName(DecodeMechanism eMechanism,
5269 : : rtl_TextEncoding eCharset)
5270 : : const
5271 : : {
5272 [ - + ]: 194 : if (!checkHierarchical())
5273 : 0 : return rtl::OUString();
5274 [ + - ]: 194 : INetURLObject aTemp(*this);
5275 [ + - ]: 194 : aTemp.clearFragment();
5276 [ + - ]: 194 : aTemp.clearQuery();
5277 [ + - ]: 194 : aTemp.removeSegment(LAST_SEGMENT, false);
5278 [ + - ]: 194 : aTemp.setFinalSlash();
5279 [ + - ][ + - ]: 194 : return aTemp.GetMainURL(eMechanism, eCharset);
5280 : : }
5281 : :
5282 : 551243 : rtl::OUString INetURLObject::GetLastName(DecodeMechanism eMechanism,
5283 : : rtl_TextEncoding eCharset) const
5284 : : {
5285 : 551243 : return getName(LAST_SEGMENT, true, eMechanism, eCharset);
5286 : : }
5287 : :
5288 : 15 : rtl::OUString INetURLObject::GetFileExtension(DecodeMechanism eMechanism,
5289 : : rtl_TextEncoding eCharset) const
5290 : : {
5291 : 15 : return getExtension(LAST_SEGMENT, false, eMechanism, eCharset);
5292 : : }
5293 : :
5294 : 0 : bool INetURLObject::CutLastName()
5295 : : {
5296 [ # # ]: 0 : INetURLObject aTemp(*this);
5297 [ # # ]: 0 : aTemp.clearFragment();
5298 [ # # ]: 0 : aTemp.clearQuery();
5299 [ # # ][ # # ]: 0 : if (!aTemp.removeSegment(LAST_SEGMENT, false))
5300 : 0 : return false;
5301 [ # # ]: 0 : *this = aTemp;
5302 [ # # ]: 0 : return true;
5303 : : }
5304 : :
5305 : 4721 : rtl::OUString INetURLObject::PathToFileName() const
5306 : : {
5307 [ - + ]: 4721 : if (m_eScheme != INET_PROT_FILE)
5308 : 0 : return rtl::OUString();
5309 : 4721 : rtl::OUString aSystemPath;
5310 [ - + ]: 4721 : if (osl::FileBase::getSystemPathFromFileURL(
5311 : : decode(m_aAbsURIRef.getStr(),
5312 : 4721 : m_aAbsURIRef.getStr() + m_aPath.getEnd(),
5313 : 4721 : getEscapePrefix(), NO_DECODE, RTL_TEXTENCODING_UTF8),
5314 [ + - ][ + - ]: 4721 : aSystemPath)
5315 : : != osl::FileBase::E_None)
5316 : 0 : return rtl::OUString();
5317 : 4721 : return aSystemPath;
5318 : : }
5319 : :
5320 : 10 : rtl::OUString INetURLObject::GetFull() const
5321 : : {
5322 [ + - ]: 10 : INetURLObject aTemp(*this);
5323 [ + - ]: 10 : aTemp.removeFinalSlash();
5324 [ + - ][ + - ]: 10 : return aTemp.PathToFileName();
5325 : : }
5326 : :
5327 : 0 : rtl::OUString INetURLObject::GetPath() const
5328 : : {
5329 [ # # ]: 0 : INetURLObject aTemp(*this);
5330 [ # # ]: 0 : aTemp.removeSegment(LAST_SEGMENT, true);
5331 [ # # ]: 0 : aTemp.removeFinalSlash();
5332 [ # # ][ # # ]: 0 : return aTemp.PathToFileName();
5333 : : }
5334 : :
5335 : 0 : void INetURLObject::SetBase(rtl::OUString const & rTheBase)
5336 : : {
5337 : 0 : setBase(rTheBase, LAST_SEGMENT, true, ENCODE_ALL);
5338 : 0 : }
5339 : :
5340 : 2139 : rtl::OUString INetURLObject::GetBase() const
5341 : : {
5342 : 2139 : return getBase(LAST_SEGMENT, true, DECODE_WITH_CHARSET);
5343 : : }
5344 : :
5345 : 0 : void INetURLObject::SetName(rtl::OUString const & rTheName,
5346 : : EncodeMechanism eMechanism,
5347 : : rtl_TextEncoding eCharset)
5348 : : {
5349 [ # # ]: 0 : INetURLObject aTemp(*this);
5350 [ # # ][ # # ]: 0 : if (aTemp.removeSegment(LAST_SEGMENT, true)
[ # # ][ # # ]
5351 : : && aTemp.insertName(rTheName, false, LAST_SEGMENT, true, eMechanism,
5352 [ # # ]: 0 : eCharset))
5353 [ # # ][ # # ]: 0 : *this = aTemp;
5354 : 0 : }
5355 : :
5356 : 166 : void INetURLObject::SetExtension(rtl::OUString const & rTheExtension,
5357 : : EncodeMechanism eMechanism,
5358 : : rtl_TextEncoding eCharset)
5359 : : {
5360 : 166 : setExtension(rTheExtension, LAST_SEGMENT, false, eMechanism, eCharset);
5361 : 166 : }
5362 : :
5363 : 2 : rtl::OUString INetURLObject::CutExtension(DecodeMechanism eMechanism,
5364 : : rtl_TextEncoding eCharset)
5365 : : {
5366 : : rtl::OUString aTheExtension(getExtension(LAST_SEGMENT, false, eMechanism,
5367 [ + - ]: 2 : eCharset));
5368 [ + - ]: 2 : return removeExtension(LAST_SEGMENT, false)
5369 [ + - ]: 2 : ? aTheExtension : rtl::OUString();
5370 : : }
5371 : :
5372 : 905 : bool INetURLObject::IsCaseSensitive() const
5373 : : {
5374 : 905 : return true;
5375 : : }
5376 : :
5377 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|