1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim:set ts=4 sw=4 et cindent: */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Netscape Communications Corporation.
20 : * Portions created by the Initial Developer are Copyright (C) 1998
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Alec Flett <alecf@netscape.com>
25 : * Darin Fisher <darin@netscape.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either the GNU General Public License Version 2 or later (the "GPL"), or
29 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : /* Unix-specific local file uri parsing */
42 : #include "nsURLHelper.h"
43 : #include "nsEscape.h"
44 : #include "nsILocalFile.h"
45 : #include "nsNativeCharsetUtils.h"
46 :
47 : nsresult
48 186639 : net_GetURLSpecFromActualFile(nsIFile *aFile, nsACString &result)
49 : {
50 : nsresult rv;
51 373278 : nsCAutoString nativePath, ePath;
52 373278 : nsAutoString path;
53 :
54 186639 : rv = aFile->GetNativePath(nativePath);
55 186639 : if (NS_FAILED(rv)) return rv;
56 :
57 : // Convert to unicode and back to check correct conversion to native charset
58 186639 : NS_CopyNativeToUnicode(nativePath, path);
59 186639 : NS_CopyUnicodeToNative(path, ePath);
60 :
61 : // Use UTF8 version if conversion was successful
62 186639 : if (nativePath == ePath)
63 186639 : CopyUTF16toUTF8(path, ePath);
64 : else
65 0 : ePath = nativePath;
66 :
67 373278 : nsCAutoString escPath;
68 373278 : NS_NAMED_LITERAL_CSTRING(prefix, "file://");
69 :
70 : // Escape the path with the directory mask
71 186639 : if (NS_EscapeURL(ePath.get(), -1, esc_Directory+esc_Forced, escPath))
72 29 : escPath.Insert(prefix, 0);
73 : else
74 186610 : escPath.Assign(prefix + ePath);
75 :
76 : // esc_Directory does not escape the semicolons, so if a filename
77 : // contains semicolons we need to manually escape them.
78 : // This replacement should be removed in bug #473280
79 186639 : escPath.ReplaceSubstring(";", "%3b");
80 186639 : result = escPath;
81 186639 : return NS_OK;
82 : }
83 :
84 : nsresult
85 61809 : net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result)
86 : {
87 : // NOTE: See also the implementation in nsURLHelperOSX.cpp,
88 : // which is based on this.
89 :
90 : nsresult rv;
91 :
92 123618 : nsCOMPtr<nsILocalFile> localFile;
93 61809 : rv = NS_NewNativeLocalFile(EmptyCString(), true, getter_AddRefs(localFile));
94 61809 : if (NS_FAILED(rv))
95 0 : return rv;
96 :
97 123618 : nsCAutoString directory, fileBaseName, fileExtension, path;
98 :
99 61809 : rv = net_ParseFileURL(aURL, directory, fileBaseName, fileExtension);
100 61809 : if (NS_FAILED(rv)) return rv;
101 :
102 61809 : if (!directory.IsEmpty())
103 61809 : NS_EscapeURL(directory, esc_Directory|esc_AlwaysCopy, path);
104 61809 : if (!fileBaseName.IsEmpty())
105 61806 : NS_EscapeURL(fileBaseName, esc_FileBaseName|esc_AlwaysCopy, path);
106 61809 : if (!fileExtension.IsEmpty()) {
107 61790 : path += '.';
108 61790 : NS_EscapeURL(fileExtension, esc_FileExtension|esc_AlwaysCopy, path);
109 : }
110 :
111 61809 : NS_UnescapeURL(path);
112 61809 : if (path.Length() != strlen(path.get()))
113 0 : return NS_ERROR_FILE_INVALID_PATH;
114 :
115 61809 : if (IsUTF8(path)) {
116 : // speed up the start-up where UTF-8 is the native charset
117 : // (e.g. on recent Linux distributions)
118 61809 : if (NS_IsNativeUTF8())
119 61809 : rv = localFile->InitWithNativePath(path);
120 : else
121 0 : rv = localFile->InitWithPath(NS_ConvertUTF8toUTF16(path));
122 : // XXX In rare cases, a valid UTF-8 string can be valid as a native
123 : // encoding (e.g. 0xC5 0x83 is valid both as UTF-8 and Windows-125x).
124 : // However, the chance is very low that a meaningful word in a legacy
125 : // encoding is valid as UTF-8.
126 : }
127 : else
128 : // if path is not in UTF-8, assume it is encoded in the native charset
129 0 : rv = localFile->InitWithNativePath(path);
130 :
131 61809 : if (NS_FAILED(rv)) return rv;
132 :
133 61809 : NS_ADDREF(*result = localFile);
134 61809 : return NS_OK;
135 : }
|