LCOV - code coverage report
Current view: top level - toolkit/components/places - Helpers.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 52 132 39.4 %
Date: 2017-07-14 16:53:18 Functions: 12 26 46.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
       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 "Helpers.h"
       7             : #include "mozIStorageError.h"
       8             : #include "prio.h"
       9             : #include "nsString.h"
      10             : #include "nsNavHistory.h"
      11             : #include "mozilla/Base64.h"
      12             : #include "mozilla/Services.h"
      13             : 
      14             : // The length of guids that are used by history and bookmarks.
      15             : #define GUID_LENGTH 12
      16             : 
      17             : namespace mozilla {
      18             : namespace places {
      19             : 
      20             : ////////////////////////////////////////////////////////////////////////////////
      21             : //// AsyncStatementCallback
      22             : 
      23          10 : NS_IMPL_ISUPPORTS(
      24             :   AsyncStatementCallback
      25             : , mozIStorageStatementCallback
      26             : )
      27             : 
      28             : NS_IMETHODIMP
      29           0 : WeakAsyncStatementCallback::HandleResult(mozIStorageResultSet *aResultSet)
      30             : {
      31           0 :   MOZ_ASSERT(false, "Was not expecting a resultset, but got it.");
      32             :   return NS_OK;
      33             : }
      34             : 
      35             : NS_IMETHODIMP
      36           1 : WeakAsyncStatementCallback::HandleCompletion(uint16_t aReason)
      37             : {
      38           1 :   return NS_OK;
      39             : }
      40             : 
      41             : NS_IMETHODIMP
      42           0 : WeakAsyncStatementCallback::HandleError(mozIStorageError *aError)
      43             : {
      44             : #ifdef DEBUG
      45             :   int32_t result;
      46           0 :   nsresult rv = aError->GetResult(&result);
      47           0 :   NS_ENSURE_SUCCESS(rv, rv);
      48           0 :   nsAutoCString message;
      49           0 :   rv = aError->GetMessage(message);
      50           0 :   NS_ENSURE_SUCCESS(rv, rv);
      51             : 
      52           0 :   nsAutoCString warnMsg;
      53           0 :   warnMsg.AppendLiteral("An error occurred while executing an async statement: ");
      54           0 :   warnMsg.AppendInt(result);
      55           0 :   warnMsg.Append(' ');
      56           0 :   warnMsg.Append(message);
      57           0 :   NS_WARNING(warnMsg.get());
      58             : #endif
      59             : 
      60           0 :   return NS_OK;
      61             : }
      62             : 
      63             : #define URI_TO_URLCSTRING(uri, spec) \
      64             :   nsAutoCString spec; \
      65             :   if (NS_FAILED(aURI->GetSpec(spec))) { \
      66             :     return NS_ERROR_UNEXPECTED; \
      67             :   }
      68             : 
      69             : // Bind URI to statement by index.
      70             : nsresult // static
      71           0 : URIBinder::Bind(mozIStorageStatement* aStatement,
      72             :                 int32_t aIndex,
      73             :                 nsIURI* aURI)
      74             : {
      75           0 :   NS_ASSERTION(aStatement, "Must have non-null statement");
      76           0 :   NS_ASSERTION(aURI, "Must have non-null uri");
      77             : 
      78           0 :   URI_TO_URLCSTRING(aURI, spec);
      79           0 :   return URIBinder::Bind(aStatement, aIndex, spec);
      80             : }
      81             : 
      82             : // Statement URLCString to statement by index.
      83             : nsresult // static
      84           0 : URIBinder::Bind(mozIStorageStatement* aStatement,
      85             :                 int32_t index,
      86             :                 const nsACString& aURLString)
      87             : {
      88           0 :   NS_ASSERTION(aStatement, "Must have non-null statement");
      89           0 :   return aStatement->BindUTF8StringByIndex(
      90           0 :     index, StringHead(aURLString, URI_LENGTH_MAX)
      91           0 :   );
      92             : }
      93             : 
      94             : // Bind URI to statement by name.
      95             : nsresult // static
      96           0 : URIBinder::Bind(mozIStorageStatement* aStatement,
      97             :                 const nsACString& aName,
      98             :                 nsIURI* aURI)
      99             : {
     100           0 :   NS_ASSERTION(aStatement, "Must have non-null statement");
     101           0 :   NS_ASSERTION(aURI, "Must have non-null uri");
     102             : 
     103           0 :   URI_TO_URLCSTRING(aURI, spec);
     104           0 :   return URIBinder::Bind(aStatement, aName, spec);
     105             : }
     106             : 
     107             : // Bind URLCString to statement by name.
     108             : nsresult // static
     109           4 : URIBinder::Bind(mozIStorageStatement* aStatement,
     110             :                 const nsACString& aName,
     111             :                 const nsACString& aURLString)
     112             : {
     113           4 :   NS_ASSERTION(aStatement, "Must have non-null statement");
     114           8 :   return aStatement->BindUTF8StringByName(
     115           8 :     aName, StringHead(aURLString, URI_LENGTH_MAX)
     116          12 :   );
     117             : }
     118             : 
     119             : // Bind URI to params by index.
     120             : nsresult // static
     121           0 : URIBinder::Bind(mozIStorageBindingParams* aParams,
     122             :                 int32_t aIndex,
     123             :                 nsIURI* aURI)
     124             : {
     125           0 :   NS_ASSERTION(aParams, "Must have non-null statement");
     126           0 :   NS_ASSERTION(aURI, "Must have non-null uri");
     127             : 
     128           0 :   URI_TO_URLCSTRING(aURI, spec);
     129           0 :   return URIBinder::Bind(aParams, aIndex, spec);
     130             : }
     131             : 
     132             : // Bind URLCString to params by index.
     133             : nsresult // static
     134           0 : URIBinder::Bind(mozIStorageBindingParams* aParams,
     135             :                 int32_t index,
     136             :                 const nsACString& aURLString)
     137             : {
     138           0 :   NS_ASSERTION(aParams, "Must have non-null statement");
     139           0 :   return aParams->BindUTF8StringByIndex(
     140           0 :     index, StringHead(aURLString, URI_LENGTH_MAX)
     141           0 :   );
     142             : }
     143             : 
     144             : // Bind URI to params by name.
     145             : nsresult // static
     146           0 : URIBinder::Bind(mozIStorageBindingParams* aParams,
     147             :                 const nsACString& aName,
     148             :                 nsIURI* aURI)
     149             : {
     150           0 :   NS_ASSERTION(aParams, "Must have non-null params array");
     151           0 :   NS_ASSERTION(aURI, "Must have non-null uri");
     152             : 
     153           0 :   URI_TO_URLCSTRING(aURI, spec);
     154           0 :   return URIBinder::Bind(aParams, aName, spec);
     155             : }
     156             : 
     157             : // Bind URLCString to params by name.
     158             : nsresult // static
     159           1 : URIBinder::Bind(mozIStorageBindingParams* aParams,
     160             :                 const nsACString& aName,
     161             :                 const nsACString& aURLString)
     162             : {
     163           1 :   NS_ASSERTION(aParams, "Must have non-null params array");
     164             : 
     165             :   nsresult rv = aParams->BindUTF8StringByName(
     166           2 :     aName, StringHead(aURLString, URI_LENGTH_MAX)
     167           2 :   );
     168           1 :   NS_ENSURE_SUCCESS(rv, rv);
     169           1 :   return NS_OK;
     170             : }
     171             : 
     172             : #undef URI_TO_URLCSTRING
     173             : 
     174             : nsresult
     175           1 : GetReversedHostname(nsIURI* aURI, nsString& aRevHost)
     176             : {
     177           2 :   nsAutoCString forward8;
     178           1 :   nsresult rv = aURI->GetHost(forward8);
     179             :   // Not all URIs have a host.
     180           1 :   if (NS_FAILED(rv))
     181           0 :     return rv;
     182             : 
     183             :   // can't do reversing in UTF8, better use 16-bit chars
     184           1 :   GetReversedHostname(NS_ConvertUTF8toUTF16(forward8), aRevHost);
     185           1 :   return NS_OK;
     186             : }
     187             : 
     188             : void
     189           1 : GetReversedHostname(const nsString& aForward, nsString& aRevHost)
     190             : {
     191           1 :   ReverseString(aForward, aRevHost);
     192           1 :   aRevHost.Append(char16_t('.'));
     193           1 : }
     194             : 
     195             : void
     196          17 : ReverseString(const nsString& aInput, nsString& aReversed)
     197             : {
     198          17 :   aReversed.Truncate(0);
     199         170 :   for (int32_t i = aInput.Length() - 1; i >= 0; i--) {
     200         153 :     aReversed.Append(aInput[i]);
     201             :   }
     202          17 : }
     203             : 
     204             : #ifdef XP_WIN
     205             : } // namespace places
     206             : } // namespace mozilla
     207             : 
     208             : // Included here because windows.h conflicts with the use of mozIStorageError
     209             : // above, but make sure that these are not included inside mozilla::places.
     210             : #include <windows.h>
     211             : #include <wincrypt.h>
     212             : 
     213             : namespace mozilla {
     214             : namespace places {
     215             : #endif
     216             : 
     217             : static
     218             : nsresult
     219           1 : GenerateRandomBytes(uint32_t aSize,
     220             :                     uint8_t* _buffer)
     221             : {
     222             :   // On Windows, we'll use its built-in cryptographic API.
     223             : #if defined(XP_WIN)
     224             :   HCRYPTPROV cryptoProvider;
     225             :   BOOL rc = CryptAcquireContext(&cryptoProvider, 0, 0, PROV_RSA_FULL,
     226             :                                 CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
     227             :   if (rc) {
     228             :     rc = CryptGenRandom(cryptoProvider, aSize, _buffer);
     229             :     (void)CryptReleaseContext(cryptoProvider, 0);
     230             :   }
     231             :   return rc ? NS_OK : NS_ERROR_FAILURE;
     232             : 
     233             :   // On Unix, we'll just read in from /dev/urandom.
     234             : #elif defined(XP_UNIX)
     235           1 :   NS_ENSURE_ARG_MAX(aSize, INT32_MAX);
     236           1 :   PRFileDesc* urandom = PR_Open("/dev/urandom", PR_RDONLY, 0);
     237           1 :   nsresult rv = NS_ERROR_FAILURE;
     238           1 :   if (urandom) {
     239           1 :     int32_t bytesRead = PR_Read(urandom, _buffer, aSize);
     240           1 :     if (bytesRead == static_cast<int32_t>(aSize)) {
     241           1 :       rv = NS_OK;
     242             :     }
     243           1 :     (void)PR_Close(urandom);
     244             :   }
     245           1 :   return rv;
     246             : #endif
     247             : }
     248             : 
     249             : nsresult
     250           1 : GenerateGUID(nsACString& _guid)
     251             : {
     252           1 :   _guid.Truncate();
     253             : 
     254             :   // Request raw random bytes and base64url encode them.  For each set of three
     255             :   // bytes, we get one character.
     256             :   const uint32_t kRequiredBytesLength =
     257           1 :     static_cast<uint32_t>(GUID_LENGTH / 4 * 3);
     258             : 
     259             :   uint8_t buffer[kRequiredBytesLength];
     260           1 :   nsresult rv = GenerateRandomBytes(kRequiredBytesLength, buffer);
     261           1 :   NS_ENSURE_SUCCESS(rv, rv);
     262             : 
     263             :   rv = Base64URLEncode(kRequiredBytesLength, buffer,
     264           1 :                        Base64URLEncodePaddingPolicy::Omit, _guid);
     265           1 :   NS_ENSURE_SUCCESS(rv, rv);
     266             : 
     267           1 :   NS_ASSERTION(_guid.Length() == GUID_LENGTH, "GUID is not the right size!");
     268           1 :   return NS_OK;
     269             : }
     270             : 
     271             : bool
     272           0 : IsValidGUID(const nsACString& aGUID)
     273             : {
     274           0 :   nsCString::size_type len = aGUID.Length();
     275           0 :   if (len != GUID_LENGTH) {
     276           0 :     return false;
     277             :   }
     278             : 
     279           0 :   for (nsCString::size_type i = 0; i < len; i++ ) {
     280           0 :     char c = aGUID[i];
     281           0 :     if ((c >= 'a' && c <= 'z') || // a-z
     282           0 :         (c >= 'A' && c <= 'Z') || // A-Z
     283           0 :         (c >= '0' && c <= '9') || // 0-9
     284           0 :         c == '-' || c == '_') { // - or _
     285           0 :       continue;
     286             :     }
     287           0 :     return false;
     288             :   }
     289           0 :   return true;
     290             : }
     291             : 
     292             : void
     293           0 : TruncateTitle(const nsACString& aTitle, nsACString& aTrimmed)
     294             : {
     295           0 :   if (aTitle.IsVoid()) {
     296           0 :     return;
     297             :   }
     298           0 :   aTrimmed = aTitle;
     299           0 :   if (aTitle.Length() > TITLE_LENGTH_MAX) {
     300           0 :     aTrimmed = StringHead(aTitle, TITLE_LENGTH_MAX);
     301             :   }
     302             : }
     303             : 
     304             : PRTime
     305           0 : RoundToMilliseconds(PRTime aTime) {
     306           0 :   return aTime - (aTime % PR_USEC_PER_MSEC);
     307             : }
     308             : 
     309             : PRTime
     310           0 : RoundedPRNow() {
     311           0 :   return RoundToMilliseconds(PR_Now());
     312             : }
     313             : 
     314             : bool
     315           1 : GetHiddenState(bool aIsRedirect,
     316             :                uint32_t aTransitionType)
     317             : {
     318           1 :   return aTransitionType == nsINavHistoryService::TRANSITION_FRAMED_LINK ||
     319           2 :          aTransitionType == nsINavHistoryService::TRANSITION_EMBED ||
     320           1 :          aIsRedirect;
     321             : }
     322             : 
     323             : ////////////////////////////////////////////////////////////////////////////////
     324             : //// AsyncStatementCallbackNotifier
     325             : 
     326             : NS_IMETHODIMP
     327           0 : AsyncStatementCallbackNotifier::HandleCompletion(uint16_t aReason)
     328             : {
     329           0 :   if (aReason != mozIStorageStatementCallback::REASON_FINISHED)
     330           0 :     return NS_ERROR_UNEXPECTED;
     331             : 
     332           0 :   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
     333           0 :   if (obs) {
     334           0 :     (void)obs->NotifyObservers(nullptr, mTopic, nullptr);
     335             :   }
     336             : 
     337           0 :   return NS_OK;
     338             : }
     339             : 
     340             : ////////////////////////////////////////////////////////////////////////////////
     341             : //// AsyncStatementCallbackNotifier
     342             : 
     343             : NS_IMETHODIMP
     344           0 : AsyncStatementTelemetryTimer::HandleCompletion(uint16_t aReason)
     345             : {
     346           0 :   if (aReason == mozIStorageStatementCallback::REASON_FINISHED) {
     347           0 :     Telemetry::AccumulateTimeDelta(mHistogramId, mStart);
     348             :   }
     349           0 :   return NS_OK;
     350             : }
     351             : 
     352             : } // namespace places
     353             : } // namespace mozilla

Generated by: LCOV version 1.13