LCOV - code coverage report
Current view: top level - uriloader/exthandler - nsMIMEInfoImpl.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 70 196 35.7 %
Date: 2017-07-14 16:53:18 Functions: 16 38 42.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim:set ts=2 sw=2 sts=2 et: */
       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             : #include "nsMIMEInfoImpl.h"
       8             : #include "nsXPIDLString.h"
       9             : #include "nsReadableUtils.h"
      10             : #include "nsStringEnumerator.h"
      11             : #include "nsIFile.h"
      12             : #include "nsIFileURL.h"
      13             : #include "nsEscape.h"
      14             : #include "nsIURILoader.h"
      15             : #include "nsCURILoader.h"
      16             : 
      17             : // nsISupports methods
      18          34 : NS_IMPL_ADDREF(nsMIMEInfoBase)
      19          24 : NS_IMPL_RELEASE(nsMIMEInfoBase)
      20             : 
      21          48 : NS_INTERFACE_MAP_BEGIN(nsMIMEInfoBase)
      22          48 :     NS_INTERFACE_MAP_ENTRY(nsIHandlerInfo)
      23             :     // This is only an nsIMIMEInfo if it's a MIME handler.
      24          46 :     NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIMIMEInfo, mClass == eMIMEInfo)
      25          36 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHandlerInfo)
      26          30 : NS_INTERFACE_MAP_END_THREADSAFE
      27             : 
      28             : // nsMIMEInfoImpl methods
      29             : 
      30             : // Constructors for a MIME handler.
      31           0 : nsMIMEInfoBase::nsMIMEInfoBase(const char *aMIMEType) :
      32             :     mSchemeOrType(aMIMEType),
      33             :     mClass(eMIMEInfo),
      34             :     mPreferredAction(nsIMIMEInfo::saveToDisk),
      35           0 :     mAlwaysAskBeforeHandling(true)
      36             : {
      37           0 : }
      38             : 
      39           4 : nsMIMEInfoBase::nsMIMEInfoBase(const nsACString& aMIMEType) :
      40             :     mSchemeOrType(aMIMEType),
      41             :     mClass(eMIMEInfo),
      42             :     mPreferredAction(nsIMIMEInfo::saveToDisk),
      43           4 :     mAlwaysAskBeforeHandling(true)
      44             : {
      45           4 : }
      46             : 
      47             : // Constructor for a handler that lets the caller specify whether this is a
      48             : // MIME handler or a protocol handler.  In the long run, these will be distinct
      49             : // classes (f.e. nsMIMEInfo and nsProtocolInfo), but for now we reuse this class
      50             : // for both and distinguish between the two kinds of handlers via the aClass
      51             : // argument to this method, which can be either eMIMEInfo or eProtocolInfo.
      52           0 : nsMIMEInfoBase::nsMIMEInfoBase(const nsACString& aType, HandlerClass aClass) :
      53             :     mSchemeOrType(aType),
      54             :     mClass(aClass),
      55             :     mPreferredAction(nsIMIMEInfo::saveToDisk),
      56           0 :     mAlwaysAskBeforeHandling(true)
      57             : {
      58           0 : }
      59             : 
      60           2 : nsMIMEInfoBase::~nsMIMEInfoBase()
      61             : {
      62           2 : }
      63             : 
      64             : NS_IMETHODIMP
      65           0 : nsMIMEInfoBase::GetFileExtensions(nsIUTF8StringEnumerator** aResult)
      66             : {
      67           0 :   return NS_NewUTF8StringEnumerator(aResult, &mExtensions, this);
      68             : }
      69             : 
      70             : NS_IMETHODIMP
      71           2 : nsMIMEInfoBase::ExtensionExists(const nsACString& aExtension, bool *_retval)
      72             : {
      73           2 :     NS_ASSERTION(!aExtension.IsEmpty(), "no extension");
      74           2 :     bool found = false;
      75           2 :     uint32_t extCount = mExtensions.Length();
      76           2 :     if (extCount < 1) return NS_OK;
      77             : 
      78           2 :     for (uint8_t i=0; i < extCount; i++) {
      79           2 :         const nsCString& ext = mExtensions[i];
      80           2 :         if (ext.Equals(aExtension, nsCaseInsensitiveCStringComparator())) {
      81           2 :             found = true;
      82           2 :             break;
      83             :         }
      84             :     }
      85             : 
      86           2 :     *_retval = found;
      87           2 :     return NS_OK;
      88             : }
      89             : 
      90             : NS_IMETHODIMP
      91           0 : nsMIMEInfoBase::GetPrimaryExtension(nsACString& _retval)
      92             : {
      93           0 :     if (!mExtensions.Length())
      94           0 :       return NS_ERROR_NOT_INITIALIZED;
      95             : 
      96           0 :     _retval = mExtensions[0];
      97           0 :     return NS_OK;    
      98             : }
      99             : 
     100             : NS_IMETHODIMP
     101           2 : nsMIMEInfoBase::SetPrimaryExtension(const nsACString& aExtension)
     102             : {
     103           2 :   NS_ASSERTION(!aExtension.IsEmpty(), "no extension");
     104           2 :   uint32_t extCount = mExtensions.Length();
     105             :   uint8_t i;
     106           2 :   bool found = false;
     107           2 :   for (i=0; i < extCount; i++) {
     108           2 :     const nsCString& ext = mExtensions[i];
     109           2 :     if (ext.Equals(aExtension, nsCaseInsensitiveCStringComparator())) {
     110           2 :       found = true;
     111           2 :       break;
     112             :     }
     113             :   }
     114           2 :   if (found) {
     115           2 :     mExtensions.RemoveElementAt(i);
     116             :   }
     117             : 
     118           2 :   mExtensions.InsertElementAt(0, aExtension);
     119             :   
     120           2 :   return NS_OK;
     121             : }
     122             : 
     123             : NS_IMETHODIMP
     124           2 : nsMIMEInfoBase::AppendExtension(const nsACString& aExtension)
     125             : {
     126           2 :   mExtensions.AppendElement(aExtension);
     127           2 :   return NS_OK;
     128             : }
     129             : 
     130             : NS_IMETHODIMP
     131          10 : nsMIMEInfoBase::GetType(nsACString& aType)
     132             : {
     133          10 :     if (mSchemeOrType.IsEmpty())
     134           0 :         return NS_ERROR_NOT_INITIALIZED;
     135             : 
     136          10 :     aType = mSchemeOrType;
     137          10 :     return NS_OK;
     138             : }
     139             : 
     140             : NS_IMETHODIMP
     141           0 : nsMIMEInfoBase::GetMIMEType(nsACString& aMIMEType)
     142             : {
     143           0 :     if (mSchemeOrType.IsEmpty())
     144           0 :         return NS_ERROR_NOT_INITIALIZED;
     145             : 
     146           0 :     aMIMEType = mSchemeOrType;
     147           0 :     return NS_OK;
     148             : }
     149             : 
     150             : NS_IMETHODIMP
     151           0 : nsMIMEInfoBase::GetDescription(nsAString& aDescription)
     152             : {
     153           0 :     aDescription = mDescription;
     154           0 :     return NS_OK;
     155             : }
     156             : 
     157             : NS_IMETHODIMP
     158           4 : nsMIMEInfoBase::SetDescription(const nsAString& aDescription) 
     159             : {
     160           4 :     mDescription = aDescription;
     161           4 :     return NS_OK;
     162             : }
     163             : 
     164             : NS_IMETHODIMP
     165           0 : nsMIMEInfoBase::Equals(nsIMIMEInfo *aMIMEInfo, bool *_retval)
     166             : {
     167           0 :     if (!aMIMEInfo) return NS_ERROR_NULL_POINTER;
     168             : 
     169           0 :     nsAutoCString type;
     170           0 :     nsresult rv = aMIMEInfo->GetMIMEType(type);
     171           0 :     if (NS_FAILED(rv)) return rv;
     172             : 
     173           0 :     *_retval = mSchemeOrType.Equals(type);
     174             : 
     175           0 :     return NS_OK;
     176             : }
     177             : 
     178             : NS_IMETHODIMP
     179           2 : nsMIMEInfoBase::SetFileExtensions(const nsACString& aExtensions)
     180             : {
     181           2 :     mExtensions.Clear();
     182           4 :     nsCString extList( aExtensions );
     183             :     
     184           2 :     int32_t breakLocation = -1;
     185           2 :     while ( (breakLocation= extList.FindChar(',') )!= -1)
     186             :     {
     187           0 :         mExtensions.AppendElement(Substring(extList.get(), extList.get() + breakLocation));
     188           0 :         extList.Cut(0, breakLocation+1 );
     189             :     }
     190           2 :     if ( !extList.IsEmpty() )
     191           2 :         mExtensions.AppendElement( extList );
     192           4 :     return NS_OK;
     193             : }
     194             : 
     195             : NS_IMETHODIMP
     196           0 : nsMIMEInfoBase::GetDefaultDescription(nsAString& aDefaultDescription)
     197             : {
     198           0 :   aDefaultDescription = mDefaultAppDescription;
     199           0 :   return NS_OK;
     200             : }
     201             : 
     202             : NS_IMETHODIMP
     203           0 : nsMIMEInfoBase::GetPreferredApplicationHandler(nsIHandlerApp ** aPreferredAppHandler)
     204             : {
     205           0 :   *aPreferredAppHandler = mPreferredApplication;
     206           0 :   NS_IF_ADDREF(*aPreferredAppHandler);
     207           0 :   return NS_OK;
     208             : }
     209             :  
     210             : NS_IMETHODIMP
     211           2 : nsMIMEInfoBase::SetPreferredApplicationHandler(nsIHandlerApp * aPreferredAppHandler)
     212             : {
     213           2 :   mPreferredApplication = aPreferredAppHandler;
     214           2 :   return NS_OK;
     215             : }
     216             : 
     217             : NS_IMETHODIMP
     218           0 : nsMIMEInfoBase::GetPossibleApplicationHandlers(nsIMutableArray ** aPossibleAppHandlers)
     219             : {
     220           0 :   if (!mPossibleApplications)
     221           0 :     mPossibleApplications = do_CreateInstance(NS_ARRAY_CONTRACTID);
     222             : 
     223           0 :   if (!mPossibleApplications)
     224           0 :     return NS_ERROR_OUT_OF_MEMORY;
     225             : 
     226           0 :   *aPossibleAppHandlers = mPossibleApplications;
     227           0 :   NS_IF_ADDREF(*aPossibleAppHandlers);
     228           0 :   return NS_OK;
     229             : }
     230             : 
     231             : NS_IMETHODIMP
     232           2 : nsMIMEInfoBase::GetPreferredAction(nsHandlerInfoAction * aPreferredAction)
     233             : {
     234           2 :   *aPreferredAction = mPreferredAction;
     235           2 :   return NS_OK;
     236             : }
     237             :  
     238             : NS_IMETHODIMP
     239           6 : nsMIMEInfoBase::SetPreferredAction(nsHandlerInfoAction aPreferredAction)
     240             : {
     241           6 :   mPreferredAction = aPreferredAction;
     242           6 :   return NS_OK;
     243             : }
     244             : 
     245             : NS_IMETHODIMP
     246           2 : nsMIMEInfoBase::GetAlwaysAskBeforeHandling(bool * aAlwaysAsk)
     247             : {
     248           2 :   *aAlwaysAsk = mAlwaysAskBeforeHandling;
     249             : 
     250           2 :   return NS_OK;
     251             : }
     252             : 
     253             : NS_IMETHODIMP
     254           2 : nsMIMEInfoBase::SetAlwaysAskBeforeHandling(bool aAlwaysAsk)
     255             : {
     256           2 :   mAlwaysAskBeforeHandling = aAlwaysAsk;
     257           2 :   return NS_OK;
     258             : }
     259             : 
     260             : /* static */
     261             : nsresult 
     262           0 : nsMIMEInfoBase::GetLocalFileFromURI(nsIURI *aURI, nsIFile **aFile)
     263             : {
     264             :   nsresult rv;
     265             : 
     266           0 :   nsCOMPtr<nsIFileURL> fileUrl = do_QueryInterface(aURI, &rv);
     267           0 :   if (NS_FAILED(rv)) {
     268           0 :     return rv;
     269             :   }
     270             : 
     271           0 :   nsCOMPtr<nsIFile> file;
     272           0 :   rv = fileUrl->GetFile(getter_AddRefs(file));
     273           0 :   if (NS_FAILED(rv)) {
     274           0 :     return rv;
     275             :   }
     276             : 
     277           0 :   file.forget(aFile);
     278           0 :   return NS_OK;
     279             : }
     280             : 
     281             : NS_IMETHODIMP
     282           0 : nsMIMEInfoBase::LaunchWithFile(nsIFile* aFile)
     283             : {
     284             :   nsresult rv;
     285             : 
     286             :   // it doesn't make any sense to call this on protocol handlers
     287           0 :   NS_ASSERTION(mClass == eMIMEInfo,
     288             :                "nsMIMEInfoBase should have mClass == eMIMEInfo");
     289             : 
     290           0 :   if (mPreferredAction == useSystemDefault) {
     291           0 :     return LaunchDefaultWithFile(aFile);
     292             :   }
     293             : 
     294           0 :   if (mPreferredAction == useHelperApp) {
     295           0 :     if (!mPreferredApplication)
     296           0 :       return NS_ERROR_FILE_NOT_FOUND;
     297             : 
     298             :     // at the moment, we only know how to hand files off to local handlers
     299             :     nsCOMPtr<nsILocalHandlerApp> localHandler = 
     300           0 :       do_QueryInterface(mPreferredApplication, &rv);
     301           0 :     NS_ENSURE_SUCCESS(rv, rv);
     302             : 
     303           0 :     nsCOMPtr<nsIFile> executable;
     304           0 :     rv = localHandler->GetExecutable(getter_AddRefs(executable));
     305           0 :     NS_ENSURE_SUCCESS(rv, rv);
     306             : 
     307           0 :     nsAutoCString path;
     308           0 :     aFile->GetNativePath(path);
     309           0 :     return LaunchWithIProcess(executable, path);
     310             :   }
     311             : 
     312           0 :   return NS_ERROR_INVALID_ARG;
     313             : }
     314             : 
     315             : NS_IMETHODIMP
     316           0 : nsMIMEInfoBase::LaunchWithURI(nsIURI* aURI,
     317             :                               nsIInterfaceRequestor* aWindowContext)
     318             : {
     319             :   // for now, this is only being called with protocol handlers; that
     320             :   // will change once we get to more general registerContentHandler
     321             :   // support
     322           0 :   NS_ASSERTION(mClass == eProtocolInfo,
     323             :                "nsMIMEInfoBase should be a protocol handler");
     324             : 
     325           0 :   if (mPreferredAction == useSystemDefault) {
     326           0 :     return LoadUriInternal(aURI);
     327             :   }
     328             : 
     329           0 :   if (mPreferredAction == useHelperApp) {
     330           0 :     if (!mPreferredApplication)
     331           0 :       return NS_ERROR_FILE_NOT_FOUND;
     332             : 
     333           0 :     return mPreferredApplication->LaunchWithURI(aURI, aWindowContext);
     334             :   } 
     335             : 
     336           0 :   return NS_ERROR_INVALID_ARG;
     337             : }
     338             : 
     339             : void
     340           0 : nsMIMEInfoBase::CopyBasicDataTo(nsMIMEInfoBase* aOther)
     341             : {
     342           0 :   aOther->mSchemeOrType = mSchemeOrType;
     343           0 :   aOther->mDefaultAppDescription = mDefaultAppDescription;
     344           0 :   aOther->mExtensions = mExtensions;
     345           0 : }
     346             : 
     347             : /* static */
     348             : already_AddRefed<nsIProcess>
     349           0 : nsMIMEInfoBase::InitProcess(nsIFile* aApp, nsresult* aResult)
     350             : {
     351           0 :   NS_ASSERTION(aApp, "Unexpected null pointer, fix caller");
     352             : 
     353           0 :   nsCOMPtr<nsIProcess> process = do_CreateInstance(NS_PROCESS_CONTRACTID,
     354           0 :                                                    aResult);
     355           0 :   if (NS_FAILED(*aResult))
     356           0 :     return nullptr;
     357             : 
     358           0 :   *aResult = process->Init(aApp);
     359           0 :   if (NS_FAILED(*aResult))
     360           0 :     return nullptr;
     361             : 
     362           0 :   return process.forget();
     363             : }
     364             : 
     365             : /* static */
     366             : nsresult
     367           0 : nsMIMEInfoBase::LaunchWithIProcess(nsIFile* aApp, const nsCString& aArg)
     368             : {
     369             :   nsresult rv;
     370           0 :   nsCOMPtr<nsIProcess> process = InitProcess(aApp, &rv);
     371           0 :   if (NS_FAILED(rv))
     372           0 :     return rv;
     373             : 
     374           0 :   const char *string = aArg.get();
     375             : 
     376           0 :   return process->Run(false, &string, 1);
     377             : }
     378             : 
     379             : /* static */
     380             : nsresult
     381           0 : nsMIMEInfoBase::LaunchWithIProcess(nsIFile* aApp, const nsString& aArg)
     382             : {
     383             :   nsresult rv;
     384           0 :   nsCOMPtr<nsIProcess> process = InitProcess(aApp, &rv);
     385           0 :   if (NS_FAILED(rv))
     386           0 :     return rv;
     387             : 
     388           0 :   const char16_t *string = aArg.get();
     389             : 
     390           0 :   return process->Runw(false, &string, 1);
     391             : }
     392             : 
     393             : // nsMIMEInfoImpl implementation
     394             : NS_IMETHODIMP
     395           0 : nsMIMEInfoImpl::GetDefaultDescription(nsAString& aDefaultDescription)
     396             : {
     397           0 :   if (mDefaultAppDescription.IsEmpty() && mDefaultApplication) {
     398             :     // Don't want to cache this, just in case someone resets the app
     399             :     // without changing the description....
     400           0 :     mDefaultApplication->GetLeafName(aDefaultDescription);
     401             :   } else {
     402           0 :     aDefaultDescription = mDefaultAppDescription;
     403             :   }
     404             :   
     405           0 :   return NS_OK;
     406             : }
     407             : 
     408             : NS_IMETHODIMP
     409           0 : nsMIMEInfoImpl::GetHasDefaultHandler(bool * _retval)
     410             : {
     411           0 :   *_retval = !mDefaultAppDescription.IsEmpty();
     412           0 :   if (mDefaultApplication) {
     413             :     bool exists;
     414           0 :     *_retval = NS_SUCCEEDED(mDefaultApplication->Exists(&exists)) && exists;
     415             :   }
     416           0 :   return NS_OK;
     417             : }
     418             : 
     419             : nsresult
     420           0 : nsMIMEInfoImpl::LaunchDefaultWithFile(nsIFile* aFile)
     421             : {
     422           0 :   if (!mDefaultApplication)
     423           0 :     return NS_ERROR_FILE_NOT_FOUND;
     424             : 
     425           0 :   nsAutoCString nativePath;
     426           0 :   aFile->GetNativePath(nativePath);
     427             :   
     428           0 :   return LaunchWithIProcess(mDefaultApplication, nativePath);
     429             : }
     430             : 
     431             : NS_IMETHODIMP
     432           0 : nsMIMEInfoBase::GetPossibleLocalHandlers(nsIArray **_retval)
     433             : {
     434           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     435             : }

Generated by: LCOV version 1.13