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