LCOV - code coverage report
Current view: top level - extensions/pref/autoconfig/src - nsAutoConfig.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 242 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 21 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "nsAutoConfig.h"
       7             : #include "nsIURI.h"
       8             : #include "nsIHttpChannel.h"
       9             : #include "nsIFileStreams.h"
      10             : #include "nsThreadUtils.h"
      11             : #include "nsAppDirectoryServiceDefs.h"
      12             : #include "nsIObserverService.h"
      13             : #include "nsLiteralString.h"
      14             : #include "nsIPromptService.h"
      15             : #include "nsIServiceManager.h"
      16             : #include "nsIStringBundle.h"
      17             : #include "nsContentUtils.h"
      18             : #include "nsCRT.h"
      19             : #include "nsNetCID.h"
      20             : #include "nsNetUtil.h"
      21             : #include "nspr.h"
      22             : #include <algorithm>
      23             : 
      24             : #include "mozilla/IntegerPrintfMacros.h"
      25             : #include "mozilla/Logging.h"
      26             : 
      27             : using mozilla::LogLevel;
      28             : 
      29             : mozilla::LazyLogModule MCD("MCD");
      30             : 
      31             : extern nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
      32             :                                           const char *filename,
      33             :                                           bool bGlobalContext,
      34             :                                           bool bCallbacks,
      35             :                                           bool skipFirstLine);
      36             : 
      37             : // nsISupports Implementation
      38             : 
      39           0 : NS_IMPL_ISUPPORTS(nsAutoConfig, nsIAutoConfig, nsITimerCallback, nsIStreamListener, nsIObserver, nsIRequestObserver, nsISupportsWeakReference)
      40             : 
      41           0 : nsAutoConfig::nsAutoConfig()
      42             : {
      43           0 : }
      44             : 
      45           0 : nsresult nsAutoConfig::Init()
      46             : {
      47             :     // member initializers and constructor code
      48             : 
      49             :     nsresult rv;
      50           0 :     mLoaded = false;
      51             : 
      52             :     // Registering the object as an observer to the profile-after-change topic
      53             :     nsCOMPtr<nsIObserverService> observerService =
      54           0 :         do_GetService("@mozilla.org/observer-service;1", &rv);
      55           0 :     if (NS_FAILED(rv))
      56           0 :         return rv;
      57             : 
      58           0 :     rv = observerService->AddObserver(this,"profile-after-change", true);
      59             : 
      60           0 :     return rv;
      61             : }
      62             : 
      63           0 : nsAutoConfig::~nsAutoConfig()
      64             : {
      65           0 : }
      66             : 
      67             : // attribute string configURL
      68           0 : NS_IMETHODIMP nsAutoConfig::GetConfigURL(char **aConfigURL)
      69             : {
      70           0 :     if (!aConfigURL)
      71           0 :         return NS_ERROR_NULL_POINTER;
      72             : 
      73           0 :     if (mConfigURL.IsEmpty()) {
      74           0 :         *aConfigURL = nullptr;
      75           0 :         return NS_OK;
      76             :     }
      77             : 
      78           0 :     *aConfigURL = ToNewCString(mConfigURL);
      79           0 :     if (!*aConfigURL)
      80           0 :         return NS_ERROR_OUT_OF_MEMORY;
      81           0 :     return NS_OK;
      82             : }
      83           0 : NS_IMETHODIMP nsAutoConfig::SetConfigURL(const char *aConfigURL)
      84             : {
      85           0 :     if (!aConfigURL)
      86           0 :         return NS_ERROR_NULL_POINTER;
      87           0 :     mConfigURL.Assign(aConfigURL);
      88           0 :     return NS_OK;
      89             : }
      90             : 
      91             : NS_IMETHODIMP
      92           0 : nsAutoConfig::OnStartRequest(nsIRequest *request, nsISupports *context)
      93             : {
      94           0 :     return NS_OK;
      95             : }
      96             : 
      97             : 
      98             : NS_IMETHODIMP
      99           0 : nsAutoConfig::OnDataAvailable(nsIRequest *request,
     100             :                               nsISupports *context,
     101             :                               nsIInputStream *aIStream,
     102             :                               uint64_t aSourceOffset,
     103             :                               uint32_t aLength)
     104             : {
     105             :     uint32_t amt, size;
     106             :     nsresult rv;
     107             :     char buf[1024];
     108             : 
     109           0 :     while (aLength) {
     110           0 :         size = std::min<size_t>(aLength, sizeof(buf));
     111           0 :         rv = aIStream->Read(buf, size, &amt);
     112           0 :         if (NS_FAILED(rv))
     113           0 :             return rv;
     114           0 :         mBuf.Append(buf, amt);
     115           0 :         aLength -= amt;
     116             :     }
     117           0 :     return NS_OK;
     118             : }
     119             : 
     120             : 
     121             : NS_IMETHODIMP
     122           0 : nsAutoConfig::OnStopRequest(nsIRequest *request, nsISupports *context,
     123             :                             nsresult aStatus)
     124             : {
     125             :     nsresult rv;
     126             : 
     127             :     // If the request is failed, go read the failover.jsc file
     128           0 :     if (NS_FAILED(aStatus)) {
     129           0 :         MOZ_LOG(MCD, LogLevel::Debug, ("mcd request failed with status %" PRIx32 "\n",
     130             :                                        static_cast<uint32_t>(aStatus)));
     131           0 :         return readOfflineFile();
     132             :     }
     133             : 
     134             :     // Checking for the http response, if failure go read the failover file.
     135           0 :     nsCOMPtr<nsIHttpChannel> pHTTPCon(do_QueryInterface(request));
     136           0 :     if (pHTTPCon) {
     137             :         uint32_t httpStatus;
     138           0 :         rv = pHTTPCon->GetResponseStatus(&httpStatus);
     139           0 :         if (NS_FAILED(rv) || httpStatus != 200)
     140             :         {
     141           0 :             MOZ_LOG(MCD, LogLevel::Debug, ("mcd http request failed with status %x\n", httpStatus));
     142           0 :             return readOfflineFile();
     143             :         }
     144             :     }
     145             : 
     146             :     // Send the autoconfig.jsc to javascript engine.
     147             : 
     148           0 :     rv = EvaluateAdminConfigScript(mBuf.get(), mBuf.Length(),
     149           0 :                               nullptr, false,true, false);
     150           0 :     if (NS_SUCCEEDED(rv)) {
     151             : 
     152             :         // Write the autoconfig.jsc to failover.jsc (cached copy)
     153           0 :         rv = writeFailoverFile();
     154             : 
     155           0 :         if (NS_FAILED(rv))
     156           0 :             NS_WARNING("Error writing failover.jsc file");
     157             : 
     158             :         // Releasing the lock to allow the main thread to start execution
     159           0 :         mLoaded = true;
     160             : 
     161           0 :         return NS_OK;
     162             :     }
     163             :     // there is an error in parsing of the autoconfig file.
     164           0 :     NS_WARNING("Error reading autoconfig.jsc from the network, reading the offline version");
     165           0 :     return readOfflineFile();
     166             : }
     167             : 
     168             : // Notify method as a TimerCallBack function
     169           0 : NS_IMETHODIMP nsAutoConfig::Notify(nsITimer *timer)
     170             : {
     171           0 :     downloadAutoConfig();
     172           0 :     return NS_OK;
     173             : }
     174             : 
     175             : /* Observe() is called twice: once at the instantiation time and other
     176             :    after the profile is set. It doesn't do anything but return NS_OK during the
     177             :    creation time. Second time it calls  downloadAutoConfig().
     178             : */
     179             : 
     180           0 : NS_IMETHODIMP nsAutoConfig::Observe(nsISupports *aSubject,
     181             :                                     const char *aTopic,
     182             :                                     const char16_t *someData)
     183             : {
     184           0 :     nsresult rv = NS_OK;
     185           0 :     if (!nsCRT::strcmp(aTopic, "profile-after-change")) {
     186             : 
     187             :         // We will be calling downloadAutoConfig even if there is no profile
     188             :         // name. Nothing will be passed as a parameter to the URL and the
     189             :         // default case will be picked up by the script.
     190             : 
     191           0 :         rv = downloadAutoConfig();
     192             : 
     193             :     }
     194             : 
     195           0 :     return rv;
     196             : }
     197             : 
     198           0 : nsresult nsAutoConfig::downloadAutoConfig()
     199             : {
     200             :     nsresult rv;
     201           0 :     nsAutoCString emailAddr;
     202           0 :     nsXPIDLCString urlName;
     203             :     static bool firstTime = true;
     204             : 
     205           0 :     if (mConfigURL.IsEmpty()) {
     206           0 :         MOZ_LOG(MCD, LogLevel::Debug, ("global config url is empty - did you set autoadmin.global_config_url?\n"));
     207           0 :         NS_WARNING("AutoConfig called without global_config_url");
     208           0 :         return NS_OK;
     209             :     }
     210             : 
     211             :     // If there is an email address appended as an argument to the ConfigURL
     212             :     // in the previous read, we need to remove it when timer kicks in and
     213             :     // downloads the autoconfig file again.
     214             :     // If necessary, the email address will be added again as an argument.
     215           0 :     int32_t index = mConfigURL.RFindChar((char16_t)'?');
     216           0 :     if (index != -1)
     217           0 :         mConfigURL.Truncate(index);
     218             : 
     219             :     // Clean up the previous read, the new read is going to use the same buffer
     220           0 :     if (!mBuf.IsEmpty())
     221           0 :         mBuf.Truncate(0);
     222             : 
     223             :     // Get the preferences branch and save it to the member variable
     224           0 :     if (!mPrefBranch) {
     225             :         nsCOMPtr<nsIPrefService> prefs =
     226           0 :             do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
     227           0 :         if (NS_FAILED(rv))
     228           0 :             return rv;
     229             : 
     230           0 :         rv = prefs->GetBranch(nullptr,getter_AddRefs(mPrefBranch));
     231           0 :         if (NS_FAILED(rv))
     232           0 :             return rv;
     233             :     }
     234             : 
     235             :     // Check to see if the network is online/offline
     236           0 :     nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
     237           0 :     if (NS_FAILED(rv))
     238           0 :         return rv;
     239             : 
     240             :     bool offline;
     241           0 :     rv = ios->GetOffline(&offline);
     242           0 :     if (NS_FAILED(rv))
     243           0 :         return rv;
     244             : 
     245           0 :     if (offline) {
     246             :         bool offlineFailover;
     247           0 :         rv = mPrefBranch->GetBoolPref("autoadmin.offline_failover",
     248           0 :                                       &offlineFailover);
     249             :         // Read the failover.jsc if the network is offline and the pref says so
     250           0 :         if (NS_SUCCEEDED(rv) && offlineFailover)
     251           0 :             return readOfflineFile();
     252             :     }
     253             : 
     254             :     /* Append user's identity at the end of the URL if the pref says so.
     255             :        First we are checking for the user's email address but if it is not
     256             :        available in the case where the client is used without messenger, user's
     257             :        profile name will be used as an unique identifier
     258             :     */
     259             :     bool appendMail;
     260           0 :     rv = mPrefBranch->GetBoolPref("autoadmin.append_emailaddr", &appendMail);
     261           0 :     if (NS_SUCCEEDED(rv) && appendMail) {
     262           0 :         rv = getEmailAddr(emailAddr);
     263           0 :         if (NS_SUCCEEDED(rv) && emailAddr.get()) {
     264             :             /* Adding the unique identifier at the end of autoconfig URL.
     265             :                In this case the autoconfig URL is a script and
     266             :                emailAddr as passed as an argument
     267             :             */
     268           0 :             mConfigURL.Append('?');
     269           0 :             mConfigURL.Append(emailAddr);
     270             :         }
     271             :     }
     272             : 
     273             :     // create a new url
     274           0 :     nsCOMPtr<nsIURI> url;
     275           0 :     nsCOMPtr<nsIChannel> channel;
     276             : 
     277           0 :     rv = NS_NewURI(getter_AddRefs(url), mConfigURL.get(), nullptr, nullptr);
     278           0 :     if (NS_FAILED(rv))
     279             :     {
     280           0 :         MOZ_LOG(MCD, LogLevel::Debug, ("failed to create URL - is autoadmin.global_config_url valid? - %s\n", mConfigURL.get()));
     281           0 :         return rv;
     282             :     }
     283             : 
     284           0 :     MOZ_LOG(MCD, LogLevel::Debug, ("running MCD url %s\n", mConfigURL.get()));
     285             :     // open a channel for the url
     286           0 :     rv = NS_NewChannel(getter_AddRefs(channel),
     287             :                        url,
     288             :                        nsContentUtils::GetSystemPrincipal(),
     289             :                        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
     290             :                        nsIContentPolicy::TYPE_OTHER,
     291             :                        nullptr,  // loadGroup
     292             :                        nullptr,  // aCallbacks
     293             :                        nsIRequest::INHIBIT_PERSISTENT_CACHING |
     294             :                        nsIRequest::LOAD_BYPASS_CACHE);
     295             : 
     296           0 :     if (NS_FAILED(rv))
     297           0 :         return rv;
     298             : 
     299           0 :     rv = channel->AsyncOpen2(this);
     300           0 :     if (NS_FAILED(rv)) {
     301           0 :         readOfflineFile();
     302           0 :         return rv;
     303             :     }
     304             : 
     305             :     // Set a repeating timer if the pref is set.
     306             :     // This is to be done only once.
     307             :     // Also We are having the event queue processing only for the startup
     308             :     // It is not needed with the repeating timer.
     309           0 :     if (firstTime) {
     310           0 :         firstTime = false;
     311             : 
     312             :         /* process events until we're finished. AutoConfig.jsc reading needs
     313             :            to be finished before the browser starts loading up
     314             :            We are waiting for the mLoaded which will be set through
     315             :            onStopRequest or readOfflineFile methods
     316             :            There is a possibility of deadlock so we need to make sure
     317             :            that mLoaded will be set to true in any case (success/failure)
     318             :         */
     319             : 
     320           0 :         if (!mozilla::SpinEventLoopUntil([&]() { return mLoaded; })) {
     321           0 :             return NS_ERROR_FAILURE;
     322             :         }
     323             : 
     324             :         int32_t minutes;
     325           0 :         rv = mPrefBranch->GetIntPref("autoadmin.refresh_interval",
     326           0 :                                      &minutes);
     327           0 :         if (NS_SUCCEEDED(rv) && minutes > 0) {
     328             :             // Create a new timer and pass this nsAutoConfig
     329             :             // object as a timer callback.
     330           0 :             mTimer = do_CreateInstance("@mozilla.org/timer;1",&rv);
     331           0 :             if (NS_FAILED(rv))
     332           0 :                 return rv;
     333           0 :             rv = mTimer->InitWithCallback(this, minutes * 60 * 1000,
     334           0 :                              nsITimer::TYPE_REPEATING_SLACK);
     335           0 :             if (NS_FAILED(rv))
     336           0 :                 return rv;
     337             :         }
     338             :     } //first_time
     339             : 
     340           0 :     return NS_OK;
     341             : } // nsPref::downloadAutoConfig()
     342             : 
     343             : 
     344             : 
     345           0 : nsresult nsAutoConfig::readOfflineFile()
     346             : {
     347             :     nsresult rv;
     348             : 
     349             :     /* Releasing the lock to allow main thread to start
     350             :        execution. At this point we do not need to stall
     351             :        the thread since all network activities are done.
     352             :     */
     353           0 :     mLoaded = true;
     354             : 
     355             :     bool failCache;
     356           0 :     rv = mPrefBranch->GetBoolPref("autoadmin.failover_to_cached", &failCache);
     357           0 :     if (NS_SUCCEEDED(rv) && !failCache) {
     358             :         // disable network connections and return.
     359             : 
     360             :         nsCOMPtr<nsIIOService> ios =
     361           0 :             do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
     362           0 :         if (NS_FAILED(rv))
     363           0 :             return rv;
     364             : 
     365             :         bool offline;
     366           0 :         rv = ios->GetOffline(&offline);
     367           0 :         if (NS_FAILED(rv))
     368           0 :             return rv;
     369             : 
     370           0 :         if (!offline) {
     371           0 :             rv = ios->SetOffline(true);
     372           0 :             if (NS_FAILED(rv))
     373           0 :                 return rv;
     374             :         }
     375             : 
     376             :         // lock the "network.online" prference so user cannot toggle back to
     377             :         // online mode.
     378           0 :         rv = mPrefBranch->SetBoolPref("network.online", false);
     379           0 :         if (NS_FAILED(rv))
     380           0 :             return rv;
     381             : 
     382           0 :         mPrefBranch->LockPref("network.online");
     383           0 :         return NS_OK;
     384             :     }
     385             : 
     386             :     /* faiover_to_cached is set to true so
     387             :        Open the file and read the content.
     388             :        execute the javascript file
     389             :     */
     390             : 
     391           0 :     nsCOMPtr<nsIFile> failoverFile;
     392           0 :     rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
     393           0 :                                 getter_AddRefs(failoverFile));
     394           0 :     if (NS_FAILED(rv))
     395           0 :         return rv;
     396             : 
     397           0 :     failoverFile->AppendNative(NS_LITERAL_CSTRING("failover.jsc"));
     398           0 :     rv = evaluateLocalFile(failoverFile);
     399           0 :     if (NS_FAILED(rv))
     400           0 :         NS_WARNING("Couldn't open failover.jsc, going back to default prefs");
     401           0 :     return NS_OK;
     402             : }
     403             : 
     404           0 : nsresult nsAutoConfig::evaluateLocalFile(nsIFile *file)
     405             : {
     406             :     nsresult rv;
     407           0 :     nsCOMPtr<nsIInputStream> inStr;
     408             : 
     409           0 :     rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), file);
     410           0 :     if (NS_FAILED(rv))
     411           0 :         return rv;
     412             : 
     413             :     int64_t fileSize;
     414           0 :     file->GetFileSize(&fileSize);
     415           0 :     uint32_t fs = fileSize; // Converting 64 bit structure to unsigned int
     416           0 :     char* buf = (char*) malloc(fs * sizeof(char));
     417           0 :     if (!buf)
     418           0 :         return NS_ERROR_OUT_OF_MEMORY;
     419             : 
     420           0 :     uint32_t amt = 0;
     421           0 :     rv = inStr->Read(buf, fs, &amt);
     422           0 :     if (NS_SUCCEEDED(rv)) {
     423           0 :       EvaluateAdminConfigScript(buf, fs, nullptr, false,
     424           0 :                                 true, false);
     425             :     }
     426           0 :     inStr->Close();
     427           0 :     free(buf);
     428           0 :     return rv;
     429             : }
     430             : 
     431           0 : nsresult nsAutoConfig::writeFailoverFile()
     432             : {
     433             :     nsresult rv;
     434           0 :     nsCOMPtr<nsIFile> failoverFile;
     435           0 :     nsCOMPtr<nsIOutputStream> outStr;
     436             :     uint32_t amt;
     437             : 
     438           0 :     rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
     439           0 :                                 getter_AddRefs(failoverFile));
     440           0 :     if (NS_FAILED(rv))
     441           0 :         return rv;
     442             : 
     443           0 :     failoverFile->AppendNative(NS_LITERAL_CSTRING("failover.jsc"));
     444             : 
     445           0 :     rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStr), failoverFile);
     446           0 :     if (NS_FAILED(rv))
     447           0 :         return rv;
     448           0 :     rv = outStr->Write(mBuf.get(),mBuf.Length(),&amt);
     449           0 :     outStr->Close();
     450           0 :     return rv;
     451             : }
     452             : 
     453           0 : nsresult nsAutoConfig::getEmailAddr(nsACString & emailAddr)
     454             : {
     455             : 
     456             :     nsresult rv;
     457           0 :     nsXPIDLCString prefValue;
     458             : 
     459             :     /* Getting an email address through set of three preferences:
     460             :        First getting a default account with
     461             :        "mail.accountmanager.defaultaccount"
     462             :        second getting an associated id with the default account
     463             :        Third getting an email address with id
     464             :     */
     465             : 
     466           0 :     rv = mPrefBranch->GetCharPref("mail.accountmanager.defaultaccount",
     467           0 :                                   getter_Copies(prefValue));
     468           0 :     if (NS_SUCCEEDED(rv) && !prefValue.IsEmpty()) {
     469           0 :         emailAddr = NS_LITERAL_CSTRING("mail.account.") +
     470           0 :             prefValue + NS_LITERAL_CSTRING(".identities");
     471           0 :         rv = mPrefBranch->GetCharPref(PromiseFlatCString(emailAddr).get(),
     472           0 :                                       getter_Copies(prefValue));
     473           0 :         if (NS_FAILED(rv) || prefValue.IsEmpty())
     474           0 :             return PromptForEMailAddress(emailAddr);
     475           0 :         int32_t commandIndex = prefValue.FindChar(',');
     476           0 :         if (commandIndex != kNotFound)
     477           0 :           prefValue.Truncate(commandIndex);
     478           0 :         emailAddr = NS_LITERAL_CSTRING("mail.identity.") +
     479           0 :             prefValue + NS_LITERAL_CSTRING(".useremail");
     480           0 :         rv = mPrefBranch->GetCharPref(PromiseFlatCString(emailAddr).get(),
     481           0 :                                       getter_Copies(prefValue));
     482           0 :         if (NS_FAILED(rv)  || prefValue.IsEmpty())
     483           0 :             return PromptForEMailAddress(emailAddr);
     484           0 :         emailAddr = prefValue;
     485             :     }
     486             :     else {
     487             :         // look for 4.x pref in case we just migrated.
     488           0 :         rv = mPrefBranch->GetCharPref("mail.identity.useremail",
     489           0 :                                   getter_Copies(prefValue));
     490           0 :         if (NS_SUCCEEDED(rv) && !prefValue.IsEmpty())
     491           0 :             emailAddr = prefValue;
     492             :         else
     493           0 :             PromptForEMailAddress(emailAddr);
     494             :     }
     495             : 
     496           0 :     return NS_OK;
     497             : }
     498             : 
     499           0 : nsresult nsAutoConfig::PromptForEMailAddress(nsACString &emailAddress)
     500             : {
     501             :     nsresult rv;
     502           0 :     nsCOMPtr<nsIPromptService> promptService = do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv);
     503           0 :     NS_ENSURE_SUCCESS(rv, rv);
     504           0 :     nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
     505           0 :     NS_ENSURE_SUCCESS(rv, rv);
     506             : 
     507           0 :     nsCOMPtr<nsIStringBundle> bundle;
     508           0 :     rv = bundleService->CreateBundle("chrome://autoconfig/locale/autoconfig.properties",
     509           0 :                                 getter_AddRefs(bundle));
     510           0 :     NS_ENSURE_SUCCESS(rv, rv);
     511             : 
     512           0 :     nsXPIDLString title;
     513           0 :     rv = bundle->GetStringFromName(u"emailPromptTitle", getter_Copies(title));
     514           0 :     NS_ENSURE_SUCCESS(rv, rv);
     515             : 
     516           0 :     nsXPIDLString err;
     517           0 :     rv = bundle->GetStringFromName(u"emailPromptMsg", getter_Copies(err));
     518           0 :     NS_ENSURE_SUCCESS(rv, rv);
     519           0 :     bool check = false;
     520           0 :     nsXPIDLString emailResult;
     521             :     bool success;
     522           0 :     rv = promptService->Prompt(nullptr, title.get(), err.get(), getter_Copies(emailResult), nullptr, &check, &success);
     523           0 :     if (!success)
     524           0 :       return NS_ERROR_FAILURE;
     525           0 :     NS_ENSURE_SUCCESS(rv, rv);
     526           0 :     LossyCopyUTF16toASCII(emailResult, emailAddress);
     527           0 :     return NS_OK;
     528             : }

Generated by: LCOV version 1.13