Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim:set ts=4 sw=4 et cindent: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : /* Unix-specific local file uri parsing */
8 : #include "nsURLHelper.h"
9 : #include "nsEscape.h"
10 : #include "nsIFile.h"
11 : #include "nsNativeCharsetUtils.h"
12 :
13 : nsresult
14 2467 : net_GetURLSpecFromActualFile(nsIFile *aFile, nsACString &result)
15 : {
16 : nsresult rv;
17 4934 : nsAutoCString nativePath, ePath;
18 4934 : nsAutoString path;
19 :
20 2467 : rv = aFile->GetNativePath(nativePath);
21 2467 : if (NS_FAILED(rv)) return rv;
22 :
23 : // Convert to unicode and back to check correct conversion to native charset
24 2467 : NS_CopyNativeToUnicode(nativePath, path);
25 2467 : NS_CopyUnicodeToNative(path, ePath);
26 :
27 : // Use UTF8 version if conversion was successful
28 2467 : if (nativePath == ePath)
29 2467 : CopyUTF16toUTF8(path, ePath);
30 : else
31 0 : ePath = nativePath;
32 :
33 4934 : nsAutoCString escPath;
34 2467 : NS_NAMED_LITERAL_CSTRING(prefix, "file://");
35 :
36 : // Escape the path with the directory mask
37 2467 : if (NS_EscapeURL(ePath.get(), -1, esc_Directory+esc_Forced, escPath))
38 1 : escPath.Insert(prefix, 0);
39 : else
40 2466 : escPath.Assign(prefix + ePath);
41 :
42 : // esc_Directory does not escape the semicolons, so if a filename
43 : // contains semicolons we need to manually escape them.
44 : // This replacement should be removed in bug #473280
45 2467 : escPath.ReplaceSubstring(";", "%3b");
46 2467 : result = escPath;
47 2467 : return NS_OK;
48 : }
49 :
50 : nsresult
51 2655 : net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result)
52 : {
53 : // NOTE: See also the implementation in nsURLHelperOSX.cpp,
54 : // which is based on this.
55 :
56 : nsresult rv;
57 :
58 5310 : nsCOMPtr<nsIFile> localFile;
59 2655 : rv = NS_NewNativeLocalFile(EmptyCString(), true, getter_AddRefs(localFile));
60 2655 : if (NS_FAILED(rv))
61 0 : return rv;
62 :
63 5310 : nsAutoCString directory, fileBaseName, fileExtension, path;
64 :
65 2655 : rv = net_ParseFileURL(aURL, directory, fileBaseName, fileExtension);
66 2655 : if (NS_FAILED(rv)) return rv;
67 :
68 2655 : if (!directory.IsEmpty()) {
69 : rv = NS_EscapeURL(directory, esc_Directory|esc_AlwaysCopy, path,
70 2655 : mozilla::fallible);
71 2655 : if (NS_FAILED(rv))
72 0 : return rv;
73 : }
74 2655 : if (!fileBaseName.IsEmpty()) {
75 : rv = NS_EscapeURL(fileBaseName, esc_FileBaseName|esc_AlwaysCopy, path,
76 2655 : mozilla::fallible);
77 2655 : if (NS_FAILED(rv))
78 0 : return rv;
79 : }
80 2655 : if (!fileExtension.IsEmpty()) {
81 2653 : path += '.';
82 : rv = NS_EscapeURL(fileExtension, esc_FileExtension|esc_AlwaysCopy, path,
83 2653 : mozilla::fallible);
84 2653 : if (NS_FAILED(rv))
85 0 : return rv;
86 : }
87 :
88 2655 : NS_UnescapeURL(path);
89 2655 : if (path.Length() != strlen(path.get()))
90 0 : return NS_ERROR_FILE_INVALID_PATH;
91 :
92 2655 : if (IsUTF8(path)) {
93 : // speed up the start-up where UTF-8 is the native charset
94 : // (e.g. on recent Linux distributions)
95 2655 : if (NS_IsNativeUTF8())
96 2655 : rv = localFile->InitWithNativePath(path);
97 : else
98 0 : rv = localFile->InitWithPath(NS_ConvertUTF8toUTF16(path));
99 : // XXX In rare cases, a valid UTF-8 string can be valid as a native
100 : // encoding (e.g. 0xC5 0x83 is valid both as UTF-8 and Windows-125x).
101 : // However, the chance is very low that a meaningful word in a legacy
102 : // encoding is valid as UTF-8.
103 : }
104 : else
105 : // if path is not in UTF-8, assume it is encoded in the native charset
106 0 : rv = localFile->InitWithNativePath(path);
107 :
108 2655 : if (NS_FAILED(rv)) return rv;
109 :
110 2655 : localFile.forget(result);
111 2655 : return NS_OK;
112 : }
|