LCOV - app.info - toolkit/components/places/Helpers.cpp

LCOV - code coverage report
| Current view: | directory - toolkit/components/places - Helpers.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 180 | 157 | 87.2 %
| Date: | 2012-04-21 | Functions: | 33 | 30 | 90.9 %

           1                 : /* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
           2                 :  * ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is Places code.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is
          18                 :  * the Mozilla Foundation.
          19                 :  * Portions created by the Initial Developer are Copyright (C) 2009
          20                 :  * the Initial Developer. All Rights Reserved.
          21                 :  *
          22                 :  * Contributor(s):
          23                 :  *   Shawn Wilsher <me@shawnwilsher.com> (Original Author)
          24                 :  *
          25                 :  * Alternatively, the contents of this file may be used under the terms of
          26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          29                 :  * of those above. If you wish to allow use of your version of this file only
          30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          31                 :  * use your version of this file under the terms of the MPL, indicate your
          32                 :  * decision by deleting the provisions above and replace them with the notice
          33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          34                 :  * the provisions above, a recipient may use your version of this file under
          35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          36                 :  *
          37                 :  * ***** END LICENSE BLOCK ***** */
          38                 :
          39                 : #include "Helpers.h"
          40                 : #include "mozIStorageError.h"
          41                 : #include "plbase64.h"
          42                 : #include "prio.h"
          43                 : #include "nsString.h"
          44                 : #include "nsNavHistory.h"
          45                 : #include "mozilla/Services.h"
          46                 : #if defined(XP_OS2)
          47                 : #include "nsIRandomGenerator.h"
          48                 : #endif
          49                 : #include "nsContentUtils.h"
          50                 :
          51                 : // The length of guids that are used by history and bookmarks.
          52                 : #define GUID_LENGTH 12
          53                 :
          54                 : namespace mozilla {
          55                 : namespace places {
          56                 :
          57                 : ////////////////////////////////////////////////////////////////////////////////
          58                 : //// AsyncStatementCallback
          59                 :
          60           25645 : NS_IMPL_ISUPPORTS1(
          61                 :   AsyncStatementCallback
          62                 : , mozIStorageStatementCallback
          63                 : )
          64                 :
          65                 : NS_IMETHODIMP
          66               0 : AsyncStatementCallback::HandleResult(mozIStorageResultSet *aResultSet)
          67                 : {
          68               0 :   NS_ABORT_IF_FALSE(false, "Was not expecting a resultset, but got it.");
          69               0 :   return NS_OK;
          70                 : }
          71                 :
          72                 : NS_IMETHODIMP
          73            1252 : AsyncStatementCallback::HandleCompletion(PRUint16 aReason)
          74                 : {
          75            1252 :   return NS_OK;
          76                 : }
          77                 :
          78                 : NS_IMETHODIMP
          79               0 : AsyncStatementCallback::HandleError(mozIStorageError *aError)
          80                 : {
          81                 : #ifdef DEBUG
          82                 :   PRInt32 result;
          83               0 :   nsresult rv = aError->GetResult(&result);
          84               0 :   NS_ENSURE_SUCCESS(rv, rv);
          85               0 :   nsCAutoString message;
          86               0 :   rv = aError->GetMessage(message);
          87               0 :   NS_ENSURE_SUCCESS(rv, rv);
          88                 :
          89               0 :   nsCAutoString warnMsg;
          90               0 :   warnMsg.Append("An error occurred while executing an async statement: ");
          91               0 :   warnMsg.AppendInt(result);
          92               0 :   warnMsg.Append(" ");
          93               0 :   warnMsg.Append(message);
          94               0 :   NS_WARNING(warnMsg.get());
          95                 : #endif
          96                 :
          97               0 :   return NS_OK;
          98                 : }
          99                 :
         100                 : #define URI_TO_URLCSTRING(uri, spec) \
         101                 :   nsCAutoString spec; \
         102                 :   if (NS_FAILED(aURI->GetSpec(spec))) { \
         103                 :     return NS_ERROR_UNEXPECTED; \
         104                 :   }
         105                 :
         106                 : // Bind URI to statement by index.
         107                 : nsresult // static
         108               0 : URIBinder::Bind(mozIStorageStatement* aStatement,
         109                 :                 PRInt32 aIndex,
         110                 :                 nsIURI* aURI)
         111                 : {
         112               0 :   NS_ASSERTION(aStatement, "Must have non-null statement");
         113               0 :   NS_ASSERTION(aURI, "Must have non-null uri");
         114                 :
         115               0 :   URI_TO_URLCSTRING(aURI, spec);
         116               0 :   return URIBinder::Bind(aStatement, aIndex, spec);
         117                 : }
         118                 :
         119                 : // Statement URLCString to statement by index.
         120                 : nsresult // static
         121             149 : URIBinder::Bind(mozIStorageStatement* aStatement,
         122                 :                 PRInt32 index,
         123                 :                 const nsACString& aURLString)
         124                 : {
         125             149 :   NS_ASSERTION(aStatement, "Must have non-null statement");
         126                 :   return aStatement->BindUTF8StringByIndex(
         127             149 :     index, StringHead(aURLString, URI_LENGTH_MAX)
         128             149 :   );
         129                 : }
         130                 :
         131                 : // Bind URI to statement by name.
         132                 : nsresult // static
         133            7926 : URIBinder::Bind(mozIStorageStatement* aStatement,
         134                 :                 const nsACString& aName,
         135                 :                 nsIURI* aURI)
         136                 : {
         137            7926 :   NS_ASSERTION(aStatement, "Must have non-null statement");
         138            7926 :   NS_ASSERTION(aURI, "Must have non-null uri");
         139                 :
         140           15852 :   URI_TO_URLCSTRING(aURI, spec);
         141            7926 :   return URIBinder::Bind(aStatement, aName, spec);
         142                 : }
         143                 :
         144                 : // Bind URLCString to statement by name.
         145                 : nsresult // static
         146            9968 : URIBinder::Bind(mozIStorageStatement* aStatement,
         147                 :                 const nsACString& aName,
         148                 :                 const nsACString& aURLString)
         149                 : {
         150            9968 :   NS_ASSERTION(aStatement, "Must have non-null statement");
         151                 :   return aStatement->BindUTF8StringByName(
         152            9968 :     aName, StringHead(aURLString, URI_LENGTH_MAX)
         153            9968 :   );
         154                 : }
         155                 :
         156                 : // Bind URI to params by index.
         157                 : nsresult // static
         158             332 : URIBinder::Bind(mozIStorageBindingParams* aParams,
         159                 :                 PRInt32 aIndex,
         160                 :                 nsIURI* aURI)
         161                 : {
         162             332 :   NS_ASSERTION(aParams, "Must have non-null statement");
         163             332 :   NS_ASSERTION(aURI, "Must have non-null uri");
         164                 :
         165             664 :   URI_TO_URLCSTRING(aURI, spec);
         166             332 :   return URIBinder::Bind(aParams, aIndex, spec);
         167                 : }
         168                 :
         169                 : // Bind URLCString to params by index.
         170                 : nsresult // static
         171             332 : URIBinder::Bind(mozIStorageBindingParams* aParams,
         172                 :                 PRInt32 index,
         173                 :                 const nsACString& aURLString)
         174                 : {
         175             332 :   NS_ASSERTION(aParams, "Must have non-null statement");
         176                 :   return aParams->BindUTF8StringByIndex(
         177             332 :     index, StringHead(aURLString, URI_LENGTH_MAX)
         178             332 :   );
         179                 : }
         180                 :
         181                 : // Bind URI to params by name.
         182                 : nsresult // static
         183              81 : URIBinder::Bind(mozIStorageBindingParams* aParams,
         184                 :                 const nsACString& aName,
         185                 :                 nsIURI* aURI)
         186                 : {
         187              81 :   NS_ASSERTION(aParams, "Must have non-null params array");
         188              81 :   NS_ASSERTION(aURI, "Must have non-null uri");
         189                 :
         190             162 :   URI_TO_URLCSTRING(aURI, spec);
         191              81 :   return URIBinder::Bind(aParams, aName, spec);
         192                 : }
         193                 :
         194                 : // Bind URLCString to params by name.
         195                 : nsresult // static
         196            1546 : URIBinder::Bind(mozIStorageBindingParams* aParams,
         197                 :                 const nsACString& aName,
         198                 :                 const nsACString& aURLString)
         199                 : {
         200            1546 :   NS_ASSERTION(aParams, "Must have non-null params array");
         201                 :
         202                 :   nsresult rv = aParams->BindUTF8StringByName(
         203            1546 :     aName, StringHead(aURLString, URI_LENGTH_MAX)
         204            1546 :   );
         205            1546 :   NS_ENSURE_SUCCESS(rv, rv);
         206            1546 :   return NS_OK;
         207                 : }
         208                 :
         209                 : #undef URI_TO_URLCSTRING
         210                 :
         211                 : nsresult
         212            1741 : GetReversedHostname(nsIURI* aURI, nsString& aRevHost)
         213                 : {
         214            3482 :   nsCAutoString forward8;
         215            1741 :   nsresult rv = aURI->GetHost(forward8);
         216                 :   // Not all URIs have a host.
         217            1741 :   if (NS_FAILED(rv))
         218             148 :     return rv;
         219                 :
         220                 :   // can't do reversing in UTF8, better use 16-bit chars
         221            1593 :   GetReversedHostname(NS_ConvertUTF8toUTF16(forward8), aRevHost);
         222            1593 :   return NS_OK;
         223                 : }
         224                 :
         225                 : void
         226            1739 : GetReversedHostname(const nsString& aForward, nsString& aRevHost)
         227                 : {
         228            1739 :   ReverseString(aForward, aRevHost);
         229            1739 :   aRevHost.Append(PRUnichar('.'));
         230            1739 : }
         231                 :
         232                 : void
         233           22591 : ReverseString(const nsString& aInput, nsString& aReversed)
         234                 : {
         235           22591 :   aReversed.Truncate(0);
         236          282860 :   for (PRInt32 i = aInput.Length() - 1; i >= 0; i--) {
         237          260269 :     aReversed.Append(aInput[i]);
         238                 :   }
         239           22591 : }
         240                 :
         241                 : static
         242                 : nsresult
         243            5203 : Base64urlEncode(const PRUint8* aBytes,
         244                 :                 PRUint32 aNumBytes,
         245                 :                 nsCString& _result)
         246                 : {
         247                 :   // SetLength does not set aside space for NULL termination.  PL_Base64Encode
         248                 :   // will not NULL terminate, however, nsCStrings must be NULL terminated.  As a
         249                 :   // result, we set the capacity to be one greater than what we need, and the
         250                 :   // length to our desired length.
         251            5203 :   PRUint32 length = (aNumBytes + 2) / 3 * 4; // +2 due to integer math.
         252            5203 :   NS_ENSURE_TRUE(_result.SetCapacity(length + 1), NS_ERROR_OUT_OF_MEMORY);
         253            5203 :   _result.SetLength(length);
         254                 :   (void)PL_Base64Encode(reinterpret_cast<const char*>(aBytes), aNumBytes,
         255            5203 :                         _result.BeginWriting());
         256                 :
         257                 :   // base64url encoding is defined in RFC 4648.  It replaces the last two
         258                 :   // alphabet characters of base64 encoding with '-' and '_' respectively.
         259            5203 :   _result.ReplaceChar('+', '-');
         260            5203 :   _result.ReplaceChar('/', '_');
         261            5203 :   return NS_OK;
         262                 : }
         263                 :
         264                 : #ifdef XP_WIN
         265                 : // Included here because windows.h conflicts with the use of mozIStorageError
         266                 : // above.
         267                 : #include <windows.h>
         268                 : #include <wincrypt.h>
         269                 : #endif
         270                 :
         271                 : static
         272                 : nsresult
         273            5203 : GenerateRandomBytes(PRUint32 aSize,
         274                 :                     PRUint8* _buffer)
         275                 : {
         276                 :   // On Windows, we'll use its built-in cryptographic API.
         277                 : #if defined(XP_WIN)
         278                 :   HCRYPTPROV cryptoProvider;
         279                 :   BOOL rc = CryptAcquireContext(&cryptoProvider, 0, 0, PROV_RSA_FULL,
         280                 :                                 CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
         281                 :   if (rc) {
         282                 :     rc = CryptGenRandom(cryptoProvider, aSize, _buffer);
         283                 :     (void)CryptReleaseContext(cryptoProvider, 0);
         284                 :   }
         285                 :   return rc ? NS_OK : NS_ERROR_FAILURE;
         286                 :
         287                 :   // On Unix, we'll just read in from /dev/urandom.
         288                 : #elif defined(XP_UNIX)
         289            5203 :   NS_ENSURE_ARG_MAX(aSize, PR_INT32_MAX);
         290            5203 :   PRFileDesc* urandom = PR_Open("/dev/urandom", PR_RDONLY, 0);
         291            5203 :   nsresult rv = NS_ERROR_FAILURE;
         292            5203 :   if (urandom) {
         293            5203 :     PRInt32 bytesRead = PR_Read(urandom, _buffer, aSize);
         294            5203 :     if (bytesRead == static_cast<PRInt32>(aSize)) {
         295            5203 :       rv = NS_OK;
         296                 :     }
         297            5203 :     (void)PR_Close(urandom);
         298                 :   }
         299            5203 :   return rv;
         300                 : #elif defined(XP_OS2)
         301                 :   nsCOMPtr<nsIRandomGenerator> rg =
         302                 :     do_GetService("@mozilla.org/security/random-generator;1");
         303                 :   NS_ENSURE_STATE(rg);
         304                 :
         305                 :   PRUint8* temp;
         306                 :   nsresult rv = rg->GenerateRandomBytes(aSize, &temp);
         307                 :   NS_ENSURE_SUCCESS(rv, rv);
         308                 :   memcpy(_buffer, temp, aSize);
         309                 :   NS_Free(temp);
         310                 :   return NS_OK;
         311                 : #endif
         312                 : }
         313                 :
         314                 : nsresult
         315            5203 : GenerateGUID(nsCString& _guid)
         316                 : {
         317            5203 :   _guid.Truncate();
         318                 :
         319                 :   // Request raw random bytes and base64url encode them.  For each set of three
         320                 :   // bytes, we get one character.
         321                 :   const PRUint32 kRequiredBytesLength =
         322            5203 :     static_cast<PRUint32>(GUID_LENGTH / 4 * 3);
         323                 :
         324                 :   PRUint8 buffer[kRequiredBytesLength];
         325            5203 :   nsresult rv = GenerateRandomBytes(kRequiredBytesLength, buffer);
         326            5203 :   NS_ENSURE_SUCCESS(rv, rv);
         327                 :
         328            5203 :   rv = Base64urlEncode(buffer, kRequiredBytesLength, _guid);
         329            5203 :   NS_ENSURE_SUCCESS(rv, rv);
         330                 :
         331            5203 :   NS_ASSERTION(_guid.Length() == GUID_LENGTH, "GUID is not the right size!");
         332            5203 :   return NS_OK;
         333                 : }
         334                 :
         335                 : bool
         336             471 : IsValidGUID(const nsCString& aGUID)
         337                 : {
         338             471 :   nsCString::size_type len = aGUID.Length();
         339             471 :   if (len != GUID_LENGTH) {
         340             211 :     return false;
         341                 :   }
         342                 :
         343            6750 :   for (nsCString::size_type i = 0; i < len; i++ ) {
         344            3118 :     char c = aGUID[i];
         345            3118 :     if ((c >= 'a' && c <= 'z') || // a-z
         346                 :         (c >= 'A' && c <= 'Z') || // A-Z
         347                 :         (c >= '0' && c <= '9') || // 0-9
         348                 :         c == '-' || c == '_') { // - or _
         349            3115 :       continue;
         350                 :     }
         351               3 :     return false;
         352                 :   }
         353             257 :   return true;
         354                 : }
         355                 :
         356                 : void
         357            1782 : TruncateTitle(const nsACString& aTitle, nsACString& aTrimmed)
         358                 : {
         359            1782 :   aTrimmed = aTitle;
         360            1782 :   if (aTitle.Length() > TITLE_LENGTH_MAX) {
         361               4 :     aTrimmed = StringHead(aTitle, TITLE_LENGTH_MAX);
         362                 :   }
         363            1782 : }
         364                 :
         365                 : void
         366             264 : ForceWALCheckpoint()
         367                 : {
         368             528 :   nsRefPtr<Database> DB = Database::GetDatabase();
         369             264 :   if (DB) {
         370                 :     nsCOMPtr<mozIStorageAsyncStatement> stmt = DB->GetAsyncStatement(
         371                 :       "pragma wal_checkpoint "
         372             528 :     );
         373             264 :     if (stmt) {
         374             528 :       nsCOMPtr<mozIStoragePendingStatement> handle;
         375             264 :       (void)stmt->ExecuteAsync(nsnull, getter_AddRefs(handle));
         376                 :     }
         377                 :   }
         378             264 : }
         379                 :
         380                 : bool
         381             686 : GetHiddenState(bool aIsRedirect,
         382                 :                PRUint32 aTransitionType)
         383                 : {
         384                 :   return aTransitionType == nsINavHistoryService::TRANSITION_FRAMED_LINK ||
         385                 :          aTransitionType == nsINavHistoryService::TRANSITION_EMBED ||
         386             686 :          aIsRedirect;
         387                 : }
         388                 :
         389                 : ////////////////////////////////////////////////////////////////////////////////
         390                 : //// PlacesEvent
         391                 :
         392             265 : PlacesEvent::PlacesEvent(const char* aTopic)
         393             265 : : mTopic(aTopic)
         394                 : {
         395             265 : }
         396                 :
         397                 : NS_IMETHODIMP
         398             265 : PlacesEvent::Run()
         399                 : {
         400             265 :   Notify();
         401             265 :   return NS_OK;
         402                 : }
         403                 :
         404                 : void
         405             265 : PlacesEvent::Notify()
         406                 : {
         407             265 :   NS_ASSERTION(NS_IsMainThread(), "Must only be used on the main thread!");
         408             530 :   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
         409             265 :   if (obs) {
         410             265 :     (void)obs->NotifyObservers(nsnull, mTopic, nsnull);
         411                 :   }
         412             265 : }
         413                 :
         414            1855 : NS_IMPL_THREADSAFE_ISUPPORTS1(
         415                 :   PlacesEvent
         416                 : , nsIRunnable
         417                 : )
         418                 :
         419                 : ////////////////////////////////////////////////////////////////////////////////
         420                 : //// AsyncStatementCallbackNotifier
         421                 :
         422                 : NS_IMETHODIMP
         423            4668 : AsyncStatementCallbackNotifier::HandleCompletion(PRUint16 aReason)
         424                 : {
         425            4668 :   if (aReason != mozIStorageStatementCallback::REASON_FINISHED)
         426               0 :     return NS_ERROR_UNEXPECTED;
         427                 :
         428            9336 :   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
         429            4668 :   if (obs) {
         430            4668 :     (void)obs->NotifyObservers(nsnull, mTopic, nsnull);
         431                 :   }
         432                 :
         433            4668 :   return NS_OK;
         434                 : }
         435                 :
         436                 : ////////////////////////////////////////////////////////////////////////////////
         437                 : //// AsyncStatementCallbackNotifier
         438                 :
         439                 : NS_IMETHODIMP
         440              21 : AsyncStatementTelemetryTimer::HandleCompletion(PRUint16 aReason)
         441                 : {
         442              21 :   if (aReason == mozIStorageStatementCallback::REASON_FINISHED) {
         443              21 :     Telemetry::AccumulateTimeDelta(mHistogramId, mStart);
         444                 :   }
         445              21 :   return NS_OK;
         446                 : }
         447                 :
         448                 : // This is a temporary converter used by nsPlacesImportExportService until
         449                 : // bug 482911 completes its js rewrite.
         450                 : jsval
         451              11 : livemarkInfoToJSVal(PRInt64 aId,
         452                 :                     const nsACString& aGUID,
         453                 :                     const nsAString& aTitle,
         454                 :                     PRInt64 aParentId,
         455                 :                     PRInt32 aIndex,
         456                 :                     nsCOMPtr<nsIURI>& aFeedURI,
         457                 :                     nsCOMPtr<nsIURI>& aSiteURI)
         458                 : {
         459              22 :   nsCOMPtr<nsIXPConnect> xpc = mozilla::services::GetXPConnect();
         460              11 :   NS_ENSURE_TRUE(xpc, JSVAL_NULL);
         461                 :
         462                 :   nsAXPCNativeCallContext *ncc;
         463              11 :   nsresult rv = xpc->GetCurrentNativeCallContext(&ncc);
         464              11 :   NS_ENSURE_SUCCESS(rv, JSVAL_NULL);
         465              11 :   JSContext *cx = nsnull;
         466              11 :   rv = ncc->GetJSContext(&cx);
         467              11 :   NS_ENSURE_SUCCESS(rv, JSVAL_NULL);
         468              11 :   JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL);
         469              11 :   NS_ENSURE_TRUE(obj, JSVAL_NULL);
         470                 :
         471                 :   jsval id;
         472              11 :   NS_ENSURE_TRUE(JS_NewNumberValue(cx, double(aId), &id), JSVAL_NULL);
         473                 :
         474              11 :   JSString* guid = JS_NewStringCopyN(cx, PromiseFlatCString(aGUID).get(),
         475              11 :                                      aGUID.Length());
         476              11 :   NS_ENSURE_TRUE(guid, JSVAL_NULL);
         477                 :
         478              11 :   JSString* title = JS_NewUCStringCopyN(cx, PromiseFlatString(aTitle).get(),
         479              11 :                                         aTitle.Length());
         480              11 :   NS_ENSURE_TRUE(title, JSVAL_NULL);
         481                 :
         482                 :   jsval parentId;
         483              11 :   NS_ENSURE_TRUE(JS_NewNumberValue(cx, double(aParentId), &parentId), JSVAL_NULL);
         484                 :
         485                 :   jsval feedURI;
         486                 :   rv = nsContentUtils::WrapNative(cx, JS_GetGlobalForScopeChain(cx),
         487              11 :                                   NS_ISUPPORTS_CAST(nsIURI*, aFeedURI), &feedURI);
         488              11 :   NS_ENSURE_SUCCESS(rv, JSVAL_NULL);
         489                 :
         490                 :   jsval siteURI;
         491                 :   rv = nsContentUtils::WrapNative(cx, JS_GetGlobalForScopeChain(cx),
         492              11 :                                   NS_ISUPPORTS_CAST(nsIURI*, aSiteURI), &siteURI);
         493              11 :   NS_ENSURE_SUCCESS(rv, JSVAL_NULL);
         494                 :
         495              77 :   if (!JS_DefineProperty(cx, obj, "id", id, NULL, NULL, JSPROP_ENUMERATE) ||
         496              11 :       !JS_DefineProperty(cx, obj, "guid", STRING_TO_JSVAL(guid), NULL, NULL, JSPROP_ENUMERATE) ||
         497              11 :       !JS_DefineProperty(cx, obj, "title", STRING_TO_JSVAL(title), NULL, NULL, JSPROP_ENUMERATE) ||
         498              11 :       !JS_DefineProperty(cx, obj, "parentId", parentId, NULL, NULL, JSPROP_ENUMERATE) ||
         499              11 :       !JS_DefineProperty(cx, obj, "index", INT_TO_JSVAL(aIndex), NULL, NULL, JSPROP_ENUMERATE) ||
         500              11 :       !JS_DefineProperty(cx, obj, "feedURI", feedURI, NULL, NULL, JSPROP_ENUMERATE) ||
         501              11 :       !JS_DefineProperty(cx, obj, "siteURI", siteURI, NULL, NULL, JSPROP_ENUMERATE)) {
         502               0 :     return JSVAL_NULL;
         503                 :   }
         504              11 :   return OBJECT_TO_JSVAL(obj);
         505                 : }
         506                 :
         507                 : } // namespace places
         508                 : } // namespace mozilla

Generated by: LCOV version 1.7