tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsURLHelperWin.cpp (3190B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=4 sw=2 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 /* Windows-specific local file uri parsing */
      8 #include "nsComponentManagerUtils.h"
      9 #include "nsURLHelper.h"
     10 #include "nsEscape.h"
     11 #include "nsIFile.h"
     12 #include <windows.h>
     13 #include "mozilla/StaticPrefs_network.h"
     14 #include "mozilla/Utf8.h"
     15 
     16 using namespace mozilla;
     17 
     18 nsresult net_GetURLSpecFromActualFile(nsIFile* aFile, nsACString& result) {
     19  nsresult rv;
     20  nsAutoString path;
     21 
     22  // construct URL spec from file path
     23  rv = aFile->GetPath(path);
     24  if (NS_FAILED(rv)) return rv;
     25 
     26  // Replace \ with / to convert to an url
     27  path.ReplaceChar(char16_t(0x5Cu), char16_t(0x2Fu));
     28 
     29  nsAutoCString escPath;
     30 
     31  // Windows Desktop paths begin with a drive letter, so need an 'extra'
     32  // slash at the begining
     33  // C:\Windows =>  file:///C:/Windows
     34  constexpr auto prefix = "file:///"_ns;
     35 
     36  // Escape the path with the directory mask
     37  NS_ConvertUTF16toUTF8 ePath(path);
     38  if (NS_EscapeURL(ePath.get(), -1, esc_Directory + esc_Forced, escPath))
     39    escPath.Insert(prefix, 0);
     40  else
     41    escPath.Assign(prefix + ePath);
     42 
     43  // esc_Directory does not escape the semicolons, so if a filename
     44  // contains semicolons we need to manually escape them.
     45  // This replacement should be removed in bug #473280
     46  escPath.ReplaceSubstring(";", "%3b");
     47 
     48  result = escPath;
     49  return NS_OK;
     50 }
     51 
     52 nsresult net_GetFileFromURLSpec(const nsACString& aURL, nsIFile** result) {
     53  nsresult rv;
     54 
     55  if (aURL.Length() > StaticPrefs::network_standard_url_max_length()) {
     56    return NS_ERROR_MALFORMED_URI;
     57  }
     58 
     59  const nsACString* specPtr;
     60 
     61  nsAutoCString buf;
     62  if (net_NormalizeFileURL(aURL, buf))
     63    specPtr = &buf;
     64  else
     65    specPtr = &aURL;
     66 
     67  nsAutoCString directory, fileBaseName, fileExtension;
     68 
     69  rv = net_ParseFileURL(*specPtr, directory, fileBaseName, fileExtension);
     70  if (NS_FAILED(rv)) return rv;
     71 
     72  nsAutoCString path;
     73 
     74  if (!directory.IsEmpty()) {
     75    NS_EscapeURL(directory, esc_Directory | esc_AlwaysCopy, path);
     76    if (path.Length() > 2 && path.CharAt(2) == '|') path.SetCharAt(':', 2);
     77    path.ReplaceChar('/', '\\');
     78  }
     79  if (!fileBaseName.IsEmpty())
     80    NS_EscapeURL(fileBaseName, esc_FileBaseName | esc_AlwaysCopy, path);
     81  if (!fileExtension.IsEmpty()) {
     82    path += '.';
     83    NS_EscapeURL(fileExtension, esc_FileExtension | esc_AlwaysCopy, path);
     84  }
     85 
     86  NS_UnescapeURL(path);
     87  if (path.Length() != strlen(path.get())) return NS_ERROR_FILE_INVALID_PATH;
     88 
     89  // remove leading '\'
     90  if (path.CharAt(0) == '\\') path.Cut(0, 1);
     91 
     92  if (IsUtf8(path)) {
     93    return NS_NewUTF8LocalFile(path, result);
     94  }
     95  // XXX In rare cases, a valid UTF-8 string can be valid as a native
     96  // encoding (e.g. 0xC5 0x83 is valid both as UTF-8 and Windows-125x).
     97  // However, the chance is very low that a meaningful word in a legacy
     98  // encoding is valid as UTF-8.
     99 
    100  // if path is not in UTF-8, assume it is encoded in the native charset
    101  return NS_NewNativeLocalFile(path, result);
    102 }