nsresult
net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result)
{
    // NOTE: See also the implementation in nsURLHelperOSX.cpp,
    // which is based on this.

    nsresult rv;

    nsCOMPtr<nsILocalFile> localFile;
    rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(localFile));
    if (NS_FAILED(rv))
      return rv;
    
    nsCAutoString directory, fileBaseName, fileExtension, path;

    rv = net_ParseFileURL(aURL, directory, fileBaseName, fileExtension);
    if (NS_FAILED(rv)) return rv;

    if (!directory.IsEmpty())
        NS_EscapeURL(directory, esc_Directory|esc_AlwaysCopy, path);
    if (!fileBaseName.IsEmpty())
        NS_EscapeURL(fileBaseName, esc_FileBaseName|esc_AlwaysCopy, path);
    if (!fileExtension.IsEmpty()) {
        path += '.';
        NS_EscapeURL(fileExtension, esc_FileExtension|esc_AlwaysCopy, path);
    }
    
    NS_UnescapeURL(path);
    if (path.Length() != strlen(path.get()))
        return NS_ERROR_FILE_INVALID_PATH;

    if (IsUTF8(path)) {
        // speed up the start-up where UTF-8 is the native charset
        // (e.g. on recent Linux distributions)
        if (NS_IsNativeUTF8())
            rv = localFile->InitWithNativePath(path);
        else
            rv = localFile->InitWithPath(NS_ConvertUTF8toUTF16(path));
            // XXX In rare cases, a valid UTF-8 string can be valid as a native 
            // encoding (e.g. 0xC5 0x83 is valid both as UTF-8 and Windows-125x).
            // However, the chance is very low that a meaningful word in a legacy
            // encoding is valid as UTF-8.
    }
    else 
        // if path is not in UTF-8, assume it is encoded in the native charset
        rv = localFile->InitWithNativePath(path);

    if (NS_FAILED(rv)) return rv;

    NS_ADDREF(*result = localFile);
    return NS_OK;
}
Example #2
0
nsresult
net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result)
{
    nsresult rv;

    nsCOMPtr<nsIFile> localFile(
            do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
    if (NS_FAILED(rv)) {
        NS_ERROR("Only nsIFile supported right now");
        return rv;
    }

    localFile->SetFollowLinks(true);

    const nsACString *specPtr;

    nsAutoCString buf;
    if (net_NormalizeFileURL(aURL, buf))
        specPtr = &buf;
    else
        specPtr = &aURL;
    
    nsAutoCString directory, fileBaseName, fileExtension;
    
    rv = net_ParseFileURL(*specPtr, directory, fileBaseName, fileExtension);
    if (NS_FAILED(rv)) return rv;

    nsAutoCString path;

    if (!directory.IsEmpty()) {
        NS_EscapeURL(directory, esc_Directory|esc_AlwaysCopy, path);
        if (path.Length() > 2 && path.CharAt(2) == '|')
            path.SetCharAt(':', 2);
        path.ReplaceChar('/', '\\');
    }    
    if (!fileBaseName.IsEmpty())
        NS_EscapeURL(fileBaseName, esc_FileBaseName|esc_AlwaysCopy, path);
    if (!fileExtension.IsEmpty()) {
        path += '.';
        NS_EscapeURL(fileExtension, esc_FileExtension|esc_AlwaysCopy, path);
    }
    
    NS_UnescapeURL(path);
    if (path.Length() != strlen(path.get()))
        return NS_ERROR_FILE_INVALID_PATH;

    // remove leading '\'
    if (path.CharAt(0) == '\\')
        path.Cut(0, 1);

    if (IsUTF8(path))
        rv = localFile->InitWithPath(NS_ConvertUTF8toUTF16(path));
        // XXX In rare cases, a valid UTF-8 string can be valid as a native 
        // encoding (e.g. 0xC5 0x83 is valid both as UTF-8 and Windows-125x).
        // However, the chance is very low that a meaningful word in a legacy
        // encoding is valid as UTF-8.
    else 
        // if path is not in UTF-8, assume it is encoded in the native charset
        rv = localFile->InitWithNativePath(path);

    if (NS_FAILED(rv)) return rv;

    NS_ADDREF(*result = localFile);
    return NS_OK;
}
Example #3
0
nsresult
net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result)
{
  // NOTE: See also the implementation in nsURLHelperUnix.cpp
  // This matches it except for the HFS path handling and file
  // system charset conversion.

  nsresult rv;

  nsCOMPtr<nsILocalFile> localFile;
  rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(localFile));
  if (NS_FAILED(rv))
    return rv;
  
  nsCAutoString directory, fileBaseName, fileExtension, path;
  PRBool bHFSPath = PR_FALSE;

  rv = net_ParseFileURL(aURL, directory, fileBaseName, fileExtension);
  if (NS_FAILED(rv))
    return rv;

  if (!directory.IsEmpty()) {
    NS_EscapeURL(directory, esc_Directory|esc_AlwaysCopy, path);

    // The canonical form of file URLs on OSX use POSIX paths:
    //   file:///path-name.
    // But, we still encounter file URLs that use HFS paths:
    //   file:///volume-name/path-name
    // Determine that here and normalize HFS paths to POSIX.
    nsCAutoString possibleVolName;
    if (pathBeginsWithVolName(directory, possibleVolName)) {        
      // Though we know it begins with a volume name, it could still
      // be a valid POSIX path if the boot drive is named "Mac HD"
      // and there is a directory "Mac HD" at its root. If such a
      // directory doesn't exist, we'll assume this is an HFS path.
      FSRef testRef;
      possibleVolName.Insert("/", 0);
      if (::FSPathMakeRef((UInt8*)possibleVolName.get(), &testRef, nsnull) != noErr)
        bHFSPath = PR_TRUE;
    }

    if (bHFSPath) {
      // "%2F"s need to become slashes, while all other slashes need to
      // become colons. If we start out by changing "%2F"s to colons, we
      // can reply on SwapSlashColon() to do what we need
      path.ReplaceSubstring("%2F", ":");
      path.Cut(0, 1); // directory begins with '/'
      SwapSlashColon((char *)path.get());
      // At this point, path is an HFS path made using the same
      // algorithm as nsURLHelperMac. We'll convert to POSIX below.
    }
  }
  if (!fileBaseName.IsEmpty())
    NS_EscapeURL(fileBaseName, esc_FileBaseName|esc_AlwaysCopy, path);
  if (!fileExtension.IsEmpty()) {
    path += '.';
    NS_EscapeURL(fileExtension, esc_FileExtension|esc_AlwaysCopy, path);
  }

  NS_UnescapeURL(path);
  if (path.Length() != strlen(path.get()))
    return NS_ERROR_FILE_INVALID_PATH;

  if (bHFSPath)
    convertHFSPathtoPOSIX(path, path);

  // assuming path is encoded in the native charset
  rv = localFile->InitWithNativePath(path);
  if (NS_FAILED(rv))
    return rv;

  NS_ADDREF(*result = localFile);
  return NS_OK;
}