Merging mozilla-inbound into mozilla-central.
authorMounir Lamouri <mounir.lamouri@gmail.com>
Mon, 22 Aug 2011 19:46:18 +0200
changeset 75655 c8f2a44d604b3ff4dce90c60fa03439c58ca9a66
parent 75647 7a9079ac5718060ff0d496910d9d2107124ccc1c (current diff)
parent 75654 ac57320746e8e9ec9dd3091740f84899d1d688b2 (diff)
child 75656 33e4aa663bba7fd563ab0bc2023b6219cf812c44
child 75666 14ebdc83383736e491333f88e5a3e468cefa7f6c
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
milestone9.0a1
Merging mozilla-inbound into mozilla-central.
--- a/config/nsinstall_win.c
+++ b/config/nsinstall_win.c
@@ -36,16 +36,48 @@ static const char *sh_GetLastErrorMessag
 static BOOL sh_DoCopy(wchar_t *srcFileName, DWORD srcFileAttributes,
         wchar_t *dstFileName, DWORD dstFileAttributes,
         int force, int recursive);
 
 #define LONGPATH_PREFIX L"\\\\?\\"
 #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
 #define STR_LEN(a) (ARRAY_LEN(a) - 1)
 
+#ifdef __MINGW32__
+
+/* MingW currently does not implement a wide version of the
+   startup routines.  Workaround is to implement something like
+   it ourselves. */
+
+#include <shellapi.h>
+
+int wmain(int argc, WCHAR **argv);
+
+int main(int argc, char **argv)
+{
+    int result;
+    wchar_t *commandLine = GetCommandLineW();
+    int argcw = 0;
+    wchar_t **_argvw = CommandLineToArgvW( commandLine, &argcw );
+    wchar_t *argvw[argcw + 1];
+    int i;
+    if (!_argvw)
+        return 127;
+    /* CommandLineToArgvW doesn't output the ending NULL so
+       we have to manually add it on */
+    for ( i = 0; i < argcw; i++ )
+        argvw[i] = _argvw[i];
+    argvw[argcw] = NULL;
+
+    result = wmain(argcw, argvw);
+    LocalFree(_argvw);
+    return result;
+}
+#endif /* __MINGW32__ */
+
 /* changes all forward slashes in token to backslashes */
 void changeForwardSlashesToBackSlashes ( wchar_t *arg )
 {
     if ( arg == NULL )
         return;
 
     while ( *arg ) {
         if ( *arg == '/' )
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -2505,22 +2505,22 @@ nsHTMLInputElement::SanitizeValue(nsAStr
   NS_ASSERTION(!GET_BOOLBIT(mBitField, BF_PARSER_CREATING),
                "The element parsing should be finished!");
 
   switch (mType) {
     case NS_FORM_INPUT_TEXT:
     case NS_FORM_INPUT_SEARCH:
     case NS_FORM_INPUT_TEL:
     case NS_FORM_INPUT_PASSWORD:
-    case NS_FORM_INPUT_EMAIL:
       {
         PRUnichar crlf[] = { PRUnichar('\r'), PRUnichar('\n'), 0 };
         aValue.StripChars(crlf);
       }
       break;
+    case NS_FORM_INPUT_EMAIL:
     case NS_FORM_INPUT_URL:
       {
         PRUnichar crlf[] = { PRUnichar('\r'), PRUnichar('\n'), 0 };
         aValue.StripChars(crlf);
 
         aValue = nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aValue);
       }
       break;
--- a/content/html/content/test/forms/test_input_email.html
+++ b/content/html/content/test/forms/test_input_email.html
@@ -70,18 +70,22 @@ function testEmailAddress(aElement, aVal
 }
 
 var email = document.forms[0].elements[0];
 
 // Simple values, checking the e-mail syntax validity.
 var values = [
   [ '', true ], // The empty string shouldn't be considered as invalid.
   [ 'foo@bar.com', true ],
-  [ ' foo@bar.com', false ],
-  [ 'foo@bar.com ', false ],
+  [ ' foo@bar.com', true ],
+  [ 'foo@bar.com ', true ],
+  [ '\r\n foo@bar.com', true ],
+  [ 'foo@bar.com \n\r', true ],
+  [ '\n\n \r\rfoo@bar.com\n\n   \r\r', true ],
+  [ '\n\r \n\rfoo@bar.com\n\r   \n\r', true ],
   [ 'tulip', false ],
   // Some checks on the user part of the address.
   [ '@bar.com', false ],
   [ 'f\noo@bar.com', true ],
   [ 'f\roo@bar.com', true ],
   [ 'f\r\noo@bar.com', true ],
   // Some checks for the domain part.
   [ 'foo@bar', true ],
@@ -158,17 +162,17 @@ for each (c in legalCharacters) {
   values.push(["foo@foo.bar" + c, true]);
 }
 // Add the concatenation of all legal characters too.
 values.push(["foo@bar.com" + legalCharacters, true]);
 
 // Add domain illegal characters.
 illegalCharacters = "()<>[]:;@\\,!#$%&'*+/=?^_`{|}~ \t";
 for each (c in illegalCharacters) {
-  values.push(['foo@foo.bar' + c, false]);
+  values.push(['foo@foo.ba' + c + 'r', false]);
 }
 
 values.forEach(function([value, valid]) {
   testEmailAddress(email, value, false, valid);
 });
 
 multipleValues.forEach(function([value, valid]) {
   testEmailAddress(email, value, true, valid);
--- a/content/html/content/test/test_bug549475.html
+++ b/content/html/content/test/test_bug549475.html
@@ -42,19 +42,19 @@ var valueModeValue =
 
 function sanitizeValue(aType, aValue)
 {
   switch (aType) {
     case "text":
     case "password":
     case "search":
     case "tel":
-    case "email":
       return aValue.replace(/[\n\r]/g, "");
     case "url":
+    case "email":
       return aValue.replace(/[\n\r]/g, "").replace(/^\s+|\s+$/g, "");
     case "date":
     case "month":
     case "week":
     case "time":
     case "datetime":
     case "datetime-local":
       // TODO: write the sanitize algorithm.
--- a/js/src/config/nsinstall_win.c
+++ b/js/src/config/nsinstall_win.c
@@ -36,16 +36,48 @@ static const char *sh_GetLastErrorMessag
 static BOOL sh_DoCopy(wchar_t *srcFileName, DWORD srcFileAttributes,
         wchar_t *dstFileName, DWORD dstFileAttributes,
         int force, int recursive);
 
 #define LONGPATH_PREFIX L"\\\\?\\"
 #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
 #define STR_LEN(a) (ARRAY_LEN(a) - 1)
 
+#ifdef __MINGW32__
+
+/* MingW currently does not implement a wide version of the
+   startup routines.  Workaround is to implement something like
+   it ourselves. */
+
+#include <shellapi.h>
+
+int wmain(int argc, WCHAR **argv);
+
+int main(int argc, char **argv)
+{
+    int result;
+    wchar_t *commandLine = GetCommandLineW();
+    int argcw = 0;
+    wchar_t **_argvw = CommandLineToArgvW( commandLine, &argcw );
+    wchar_t *argvw[argcw + 1];
+    int i;
+    if (!_argvw)
+        return 127;
+    /* CommandLineToArgvW doesn't output the ending NULL so
+       we have to manually add it on */
+    for ( i = 0; i < argcw; i++ )
+        argvw[i] = _argvw[i];
+    argvw[argcw] = NULL;
+
+    result = wmain(argcw, argvw);
+    LocalFree(_argvw);
+    return result;
+}
+#endif /* __MINGW32__ */
+
 /* changes all forward slashes in token to backslashes */
 void changeForwardSlashesToBackSlashes ( wchar_t *arg )
 {
     if ( arg == NULL )
         return;
 
     while ( *arg ) {
         if ( *arg == '/' )
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -244,16 +244,17 @@ nsProgressFrame::AttributeChanged(PRInt3
   NS_ASSERTION(mBarDiv, "Progress bar div must exist!");
 
   if (aNameSpaceID == kNameSpaceID_None &&
       (aAttribute == nsGkAtoms::value || aAttribute == nsGkAtoms::max)) {
     nsIFrame* barFrame = mBarDiv->GetPrimaryFrame();
     NS_ASSERTION(barFrame, "The progress frame should have a child with a frame!");
     PresContext()->PresShell()->FrameNeedsReflow(barFrame, nsIPresShell::eResize,
                                                  NS_FRAME_IS_DIRTY);
+    Invalidate(GetVisualOverflowRectRelativeToSelf());
   }
 
   return nsHTMLContainerFrame::AttributeChanged(aNameSpaceID, aAttribute,
                                                 aModType);
 }
 
 nsSize
 nsProgressFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/progress/block-invalidate-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <style>
+    progress { display: block; }
+  </style>
+  <body>
+    <progress value='0.5'></progress>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/progress/block-invalidate.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html class='reftest-wait'>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <style>
+    progress { display: block; }
+  </style>
+  <script>
+    function loadHandler() {
+      setTimeout(function() {
+        var p = document.getElementsByTagName('progress')[0];
+        p.value = '0.5';
+        document.documentElement.className = '';
+      }, 0);
+    }
+  </script>
+  <body onload="loadHandler();">
+    <progress value='0'></progress>
+  </body>
+</html>
--- a/layout/reftests/forms/progress/reftest.list
+++ b/layout/reftests/forms/progress/reftest.list
@@ -14,8 +14,11 @@
 == bar-pseudo-element-vertical.html bar-pseudo-element-vertical-ref.html
 == bar-pseudo-element-vertical-rtl.html bar-pseudo-element-vertical-rtl-ref.html
 == indeterminate-style-height.html indeterminate-style-height-ref.html
 
 # The following test is disabled but kept in the repository because the
 # transformations will not behave exactly the same for <progress> and two divs.
 # However, it would be possible to manually check those.
 # == transformations.html transformations-ref.html
+
+# Tests for bugs:
+== block-invalidate.html block-invalidate-ref.html
--- a/testing/xpcshell/xpcshell.ini
+++ b/testing/xpcshell/xpcshell.ini
@@ -1,16 +1,15 @@
 [include:chrome/test/unit/xpcshell.ini]
 [include:intl/locale/tests/unit/xpcshell.ini]
 [include:netwerk/cookie/test/unit/xpcshell.ini]
 [include:modules/libjar/zipwriter/test/unit/xpcshell.ini]
 [include:uriloader/exthandler/tests/unit/xpcshell.ini]
 [include:parser/xml/test/unit/xpcshell.ini]
 [include:modules/libpr0n/test/unit/xpcshell.ini]
-[include:modules/plugin/test/unit/xpcshell.ini]
 [include:dom/plugins/test/unit/xpcshell.ini]
 [include:dom/src/json/test/unit/xpcshell.ini]
 [include:dom/tests/unit/xpcshell.ini]
 [include:content/xtf/test/unit/xpcshell.ini]
 [include:docshell/test/unit/xpcshell.ini]
 [include:embedding/tests/unit/xpcshell.ini]
 [include:toolkit/components/commandlines/test/unit/xpcshell.ini]
 [include:toolkit/components/contentprefs/tests/unit/xpcshell.ini]
--- a/toolkit/components/places/nsNavBookmarks.cpp
+++ b/toolkit/components/places/nsNavBookmarks.cpp
@@ -62,16 +62,22 @@
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/Util.h"
 
 #define BOOKMARKS_TO_KEYWORDS_INITIAL_CACHE_SIZE 64
 #define RECENT_BOOKMARKS_INITIAL_CACHE_SIZE 10
 // Threashold to expire old bookmarks if the initial cache size is exceeded.
 #define RECENT_BOOKMARKS_THRESHOLD PRTime((PRInt64)1 * 60 * PR_USEC_PER_SEC)
 
+#define BEGIN_CRITICAL_BOOKMARK_CACHE_SECTION(_itemId_) \
+  mRecentBookmarksCache.RemoveEntry(_itemId_)
+
+#define END_CRITICAL_BOOKMARK_CACHE_SECTION(_itemId_) \
+  MOZ_ASSERT(!mRecentBookmarksCache.GetEntry(_itemId_))
+
 #define TOPIC_PLACES_MAINTENANCE "places-maintenance-finished"
 
 const PRInt32 nsNavBookmarks::kFindURIBookmarksIndex_Id = 0;
 const PRInt32 nsNavBookmarks::kFindURIBookmarksIndex_Guid = 1;
 const PRInt32 nsNavBookmarks::kFindURIBookmarksIndex_ParentId = 2;
 const PRInt32 nsNavBookmarks::kFindURIBookmarksIndex_LastModified = 3;
 const PRInt32 nsNavBookmarks::kFindURIBookmarksIndex_ParentGuid = 4;
 const PRInt32 nsNavBookmarks::kFindURIBookmarksIndex_GrandParentId = 5;
@@ -1047,17 +1053,17 @@ nsNavBookmarks::InsertBookmark(PRInt64 a
 
 
 NS_IMETHODIMP
 nsNavBookmarks::RemoveItem(PRInt64 aItemId)
 {
   NS_ENSURE_ARG(aItemId != mRoot);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, true);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
                    nsINavBookmarkObserver,
                    OnBeforeItemRemoved(bookmark.id,
                                        bookmark.type,
                                        bookmark.parentId,
                                        bookmark.guid,
@@ -1081,16 +1087,18 @@ nsNavBookmarks::RemoveItem(PRInt64 aItem
       }
     }
 
     // Remove all of the folder's children.
     rv = RemoveFolderChildren(bookmark.id);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
+  BEGIN_CRITICAL_BOOKMARK_CACHE_SECTION(bookmark.id);
+
   DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBRemoveItem);
   rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), bookmark.id);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = stmt->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Fix indices in the parent.
   if (bookmark.position != DEFAULT_INDEX) {
@@ -1102,16 +1110,18 @@ nsNavBookmarks::RemoveItem(PRInt64 aItem
   bookmark.lastModified = PR_Now();
   rv = SetItemDateInternal(GetStatement(mDBSetItemLastModified),
                            bookmark.parentId, bookmark.lastModified);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = transaction.Commit();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  END_CRITICAL_BOOKMARK_CACHE_SECTION(bookmark.id);
+
   if (!mBatching) {
     ForceWALCheckpoint(mDBConn);
   }
 
   nsCOMPtr<nsIURI> uri;
   if (bookmark.type == TYPE_BOOKMARK) {
     nsNavHistory* history = nsNavHistory::GetHistoryService();
     NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
@@ -1496,34 +1506,31 @@ nsNavBookmarks::GetDescendantChildren(PR
 
 
 NS_IMETHODIMP
 nsNavBookmarks::RemoveFolderChildren(PRInt64 aFolderId)
 {
   NS_ENSURE_ARG_MIN(aFolderId, 1);
 
   BookmarkData folder;
-  nsresult rv = FetchItemInfo(aFolderId, folder, true);
+  nsresult rv = FetchItemInfo(aFolderId, folder);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_ARG(folder.type == TYPE_FOLDER);
 
   // Fill folder children array recursively.
   nsTArray<BookmarkData> folderChildrenArray;
   rv = GetDescendantChildren(folder.id, folder.guid, folder.parentId,
                              folderChildrenArray);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Build a string of folders whose children will be removed.
   nsCString foldersToRemove;
   for (PRUint32 i = 0; i < folderChildrenArray.Length(); ++i) {
     BookmarkData& child = folderChildrenArray[i];
 
-    // Invalidate the bookmark cache.
-    mRecentBookmarksCache.RemoveEntry(child.id);
-
     // Notify observers that we are about to remove this child.
     NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
                      nsINavBookmarkObserver,
                      OnBeforeItemRemoved(child.id,
                                          child.type,
                                          child.parentId,
                                          child.guid,
                                          child.parentGuid));
@@ -1538,16 +1545,18 @@ nsNavBookmarks::RemoveFolderChildren(PRI
       if (!child.serviceCID.IsEmpty()) {
         nsCOMPtr<nsIDynamicContainer> svc =
           do_GetService(child.serviceCID.get());
         if (svc) {
           (void)svc->OnContainerRemoving(child.id);
         }
       }
     }
+
+    BEGIN_CRITICAL_BOOKMARK_CACHE_SECTION(child.id);
   }
 
   // Delete items from the database now.
   mozStorageTransaction transaction(mDBConn, PR_FALSE);
 
   nsCOMPtr<mozIStorageStatement> deleteStatement;
   rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
       "DELETE FROM moz_bookmarks "
@@ -1582,16 +1591,17 @@ nsNavBookmarks::RemoveFolderChildren(PRI
       nsNavHistory* history = nsNavHistory::GetHistoryService();
       NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
       rv = history->UpdateFrecency(child.placeId);
       NS_ENSURE_SUCCESS(rv, rv);
 
       rv = UpdateKeywordsHashForRemovedBookmark(child.id);
       NS_ENSURE_SUCCESS(rv, rv);
     }
+    END_CRITICAL_BOOKMARK_CACHE_SECTION(child.id);
   }
 
   rv = transaction.Commit();
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!mBatching) {
     ForceWALCheckpoint(mDBConn);
   }
@@ -1653,17 +1663,17 @@ nsNavBookmarks::MoveItem(PRInt64 aItemId
   // -1 is append, but no other negative number is allowed.
   NS_ENSURE_ARG_MIN(aIndex, -1);
   // Disallow making an item its own parent.
   NS_ENSURE_TRUE(aItemId != aNewParent, NS_ERROR_INVALID_ARG);
 
   mozStorageTransaction transaction(mDBConn, PR_FALSE);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, true);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // if parent and index are the same, nothing to do
   if (bookmark.parentId == aNewParent && bookmark.position == aIndex)
     return NS_OK;
 
   // Make sure aNewParent is not aFolder or a subfolder of aFolder.
   // TODO: make this performant, maybe with a nested tree (bug 408991).
@@ -1734,16 +1744,18 @@ nsNavBookmarks::MoveItem(PRInt64 aItemId
     // First, fill the hole from the removal from the old parent.
     rv = AdjustIndices(bookmark.parentId, bookmark.position + 1, PR_INT32_MAX, -1);
     NS_ENSURE_SUCCESS(rv, rv);
     // Now, make room in the new parent for the insertion.
     rv = AdjustIndices(aNewParent, newIndex, PR_INT32_MAX, 1);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
+  BEGIN_CRITICAL_BOOKMARK_CACHE_SECTION(bookmark.id);
+
   {
     // Update parent and position.
     DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBMoveItem);
     rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("parent"), aNewParent);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("item_index"), newIndex);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), bookmark.id);
@@ -1758,16 +1770,18 @@ nsNavBookmarks::MoveItem(PRInt64 aItemId
   NS_ENSURE_SUCCESS(rv, rv);
   rv = SetItemDateInternal(GetStatement(mDBSetItemLastModified),
                            aNewParent, now);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = transaction.Commit();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  END_CRITICAL_BOOKMARK_CACHE_SECTION(bookmark.id);
+
   NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
                    nsINavBookmarkObserver,
                    OnItemMoved(bookmark.id,
                                bookmark.parentId,
                                bookmark.position,
                                aNewParent,
                                newIndex,
                                bookmark.type,
@@ -1783,27 +1797,23 @@ nsNavBookmarks::MoveItem(PRInt64 aItemId
       (void)svc->OnContainerMoved(bookmark.id, aNewParent, newIndex);
     }
   }
   return NS_OK;
 }
 
 nsresult
 nsNavBookmarks::FetchItemInfo(PRInt64 aItemId,
-                              BookmarkData& _bookmark,
-                              bool aInvalidateCache)
+                              BookmarkData& _bookmark)
 {
   // Check if the requested id is in the recent cache and avoid the database
   // lookup if so.  Invalidate the cache after getting data if requested.
   BookmarkKeyClass* key = mRecentBookmarksCache.GetEntry(aItemId);
   if (key) {
     _bookmark = key->bookmark;
-    if (aInvalidateCache) {
-      mRecentBookmarksCache.RemoveEntry(aItemId);
-    }
     return NS_OK;
   }
 
   DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBGetItemProperties);
   nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool hasResult;
@@ -1859,58 +1869,61 @@ nsNavBookmarks::FetchItemInfo(PRInt64 aI
     rv = stmt->GetInt64(kGetItemPropertiesIndex_GrandParentId,
                         &_bookmark.grandParentId);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   else {
     _bookmark.grandParentId = -1;
   }
 
-  if (!aInvalidateCache) {
-    // Make space for the new entry.
-    ExpireNonrecentBookmarks(&mRecentBookmarksCache);
-    // Update the recent bookmarks cache.
-    BookmarkKeyClass* key = mRecentBookmarksCache.PutEntry(aItemId);
-    if (key) {
-      key->bookmark = _bookmark;
-    }
+  // Make space for the new entry.
+  ExpireNonrecentBookmarks(&mRecentBookmarksCache);
+  // Update the recent bookmarks cache.
+  key = mRecentBookmarksCache.PutEntry(aItemId);
+  if (key) {
+    key->bookmark = _bookmark;
   }
+
   return NS_OK;
 }
 
 nsresult
 nsNavBookmarks::SetItemDateInternal(mozIStorageStatement* aStatement,
                                     PRInt64 aItemId,
                                     PRTime aValue)
 {
+  BEGIN_CRITICAL_BOOKMARK_CACHE_SECTION(aItemId);
+
   NS_ENSURE_STATE(aStatement);
   mozStorageStatementScoper scoper(aStatement);
 
   nsresult rv = aStatement->BindInt64ByName(NS_LITERAL_CSTRING("date"), aValue);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = aStatement->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = aStatement->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  END_CRITICAL_BOOKMARK_CACHE_SECTION(aItemId);
+
   // note, we are not notifying the observers
   // that the item has changed.
 
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsNavBookmarks::SetItemDateAdded(PRInt64 aItemId, PRTime aDateAdded)
 {
   NS_ENSURE_ARG_MIN(aItemId, 1);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, true);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
   bookmark.dateAdded = aDateAdded;
 
   rv = SetItemDateInternal(GetStatement(mDBSetItemDateAdded),
                            bookmark.id, bookmark.dateAdded);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Note: mDBSetItemDateAdded also sets lastModified to aDateAdded.
@@ -1931,31 +1944,31 @@ nsNavBookmarks::SetItemDateAdded(PRInt64
 
 NS_IMETHODIMP
 nsNavBookmarks::GetItemDateAdded(PRInt64 aItemId, PRTime* _dateAdded)
 {
   NS_ENSURE_ARG_MIN(aItemId, 1);
   NS_ENSURE_ARG_POINTER(_dateAdded);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, false);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *_dateAdded = bookmark.dateAdded;
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsNavBookmarks::SetItemLastModified(PRInt64 aItemId, PRTime aLastModified)
 {
   NS_ENSURE_ARG_MIN(aItemId, 1);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, true);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
   bookmark.lastModified = aLastModified;
 
   rv = SetItemDateInternal(GetStatement(mDBSetItemLastModified),
                            bookmark.id, bookmark.lastModified);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Note: mDBSetItemDateAdded also sets lastModified to aDateAdded.
@@ -1976,17 +1989,17 @@ nsNavBookmarks::SetItemLastModified(PRIn
 
 NS_IMETHODIMP
 nsNavBookmarks::GetItemLastModified(PRInt64 aItemId, PRTime* _lastModified)
 {
   NS_ENSURE_ARG_MIN(aItemId, 1);
   NS_ENSURE_ARG_POINTER(_lastModified);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, false);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *_lastModified = bookmark.lastModified;
   return NS_OK;
 }
 
 
 nsresult
@@ -2081,19 +2094,21 @@ nsNavBookmarks::GetItemIdForGUID(const n
 
 
 NS_IMETHODIMP
 nsNavBookmarks::SetItemTitle(PRInt64 aItemId, const nsACString& aTitle)
 {
   NS_ENSURE_ARG_MIN(aItemId, 1);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, true);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  BEGIN_CRITICAL_BOOKMARK_CACHE_SECTION(bookmark.id);
+
   DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(statement, mDBSetItemTitle);
   // Support setting a null title, we support this in insertBookmark.
   if (aTitle.IsVoid()) {
     rv = statement->BindNullByName(NS_LITERAL_CSTRING("item_title"));
   }
   else {
     rv = statement->BindUTF8StringByName(NS_LITERAL_CSTRING("item_title"),
                                          aTitle);
@@ -2104,16 +2119,18 @@ nsNavBookmarks::SetItemTitle(PRInt64 aIt
                                   bookmark.lastModified);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = statement->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), bookmark.id);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = statement->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  END_CRITICAL_BOOKMARK_CACHE_SECTION(bookmark.id);
+
   NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
                    nsINavBookmarkObserver,
                    OnItemChanged(bookmark.id,
                                  NS_LITERAL_CSTRING("title"),
                                  PR_FALSE,
                                  aTitle,
                                  bookmark.lastModified,
                                  bookmark.type,
@@ -2126,79 +2143,79 @@ nsNavBookmarks::SetItemTitle(PRInt64 aIt
 
 NS_IMETHODIMP
 nsNavBookmarks::GetItemTitle(PRInt64 aItemId,
                              nsACString& _title)
 {
   NS_ENSURE_ARG_MIN(aItemId, 1);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, false);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   _title = bookmark.title;
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsNavBookmarks::GetBookmarkURI(PRInt64 aItemId,
                                nsIURI** _URI)
 {
   NS_ENSURE_ARG_MIN(aItemId, 1);
   NS_ENSURE_ARG_POINTER(_URI);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, false);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = NS_NewURI(_URI, bookmark.url);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsNavBookmarks::GetItemType(PRInt64 aItemId, PRUint16* _type)
 {
   NS_ENSURE_ARG_MIN(aItemId, 1);
   NS_ENSURE_ARG_POINTER(_type);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, false);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *_type = static_cast<PRUint16>(bookmark.type);
   return NS_OK;
 }
 
 
 nsresult
 nsNavBookmarks::GetFolderType(PRInt64 aItemId,
                               nsACString& _type)
 {
   NS_ENSURE_ARG_MIN(aItemId, 1);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, false);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   _type = bookmark.serviceCID;
   return NS_OK;
 }
 
 
 nsresult
 nsNavBookmarks::ResultNodeForContainer(PRInt64 aItemId,
                                        nsNavHistoryQueryOptions* aOptions,
                                        nsNavHistoryResultNode** aNode)
 {
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, false);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (bookmark.type == TYPE_DYNAMIC_CONTAINER) {
     *aNode = new nsNavHistoryContainerResultNode(EmptyCString(),
                                                  bookmark.title,
                                                  EmptyCString(),
                                                  nsINavHistoryResultNode::RESULT_TYPE_DYNAMIC_CONTAINER,
                                                  PR_TRUE,
@@ -2456,46 +2473,50 @@ nsNavBookmarks::GetBookmarkedURIFor(nsIU
 
 NS_IMETHODIMP
 nsNavBookmarks::ChangeBookmarkURI(PRInt64 aBookmarkId, nsIURI* aNewURI)
 {
   NS_ENSURE_ARG_MIN(aBookmarkId, 1);
   NS_ENSURE_ARG(aNewURI);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aBookmarkId, bookmark, true);
+  nsresult rv = FetchItemInfo(aBookmarkId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_ARG(bookmark.type == TYPE_BOOKMARK);
 
   mozStorageTransaction transaction(mDBConn, PR_FALSE);
 
   nsNavHistory* history = nsNavHistory::GetHistoryService();
   NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
   PRInt64 newPlaceId;
   nsCAutoString newPlaceGuid;
   rv = history->GetOrCreateIdForPage(aNewURI, &newPlaceId, newPlaceGuid);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!newPlaceId)
     return NS_ERROR_INVALID_ARG;
 
+  BEGIN_CRITICAL_BOOKMARK_CACHE_SECTION(bookmark.id);
+
   DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(statement, mDBChangeBookmarkURI);
   rv = statement->BindInt64ByName(NS_LITERAL_CSTRING("page_id"), newPlaceId);
   NS_ENSURE_SUCCESS(rv, rv);
   bookmark.lastModified = PR_Now();
   rv = statement->BindInt64ByName(NS_LITERAL_CSTRING("date"),
                                   bookmark.lastModified);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = statement->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), bookmark.id);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = statement->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = transaction.Commit();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  END_CRITICAL_BOOKMARK_CACHE_SECTION(bookmark.id);
+
   rv = history->UpdateFrecency(newPlaceId);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Upon changing the URI for a bookmark, update the frecency for the old
   // place as well.
   rv = history->UpdateFrecency(bookmark.placeId);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -2520,17 +2541,17 @@ nsNavBookmarks::ChangeBookmarkURI(PRInt6
 
 NS_IMETHODIMP
 nsNavBookmarks::GetFolderIdForItem(PRInt64 aItemId, PRInt64* _parentId)
 {
   NS_ENSURE_ARG_MIN(aItemId, 1);
   NS_ENSURE_ARG_POINTER(_parentId);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, false);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // this should not happen, but see bug #400448 for details
   NS_ENSURE_TRUE(bookmark.id != bookmark.parentId, NS_ERROR_UNEXPECTED);
 
   *_parentId = bookmark.parentId;
   return NS_OK;
 }
@@ -2646,17 +2667,17 @@ nsNavBookmarks::GetBookmarkIdsForURI(nsI
 
 NS_IMETHODIMP
 nsNavBookmarks::GetItemIndex(PRInt64 aItemId, PRInt32* _index)
 {
   NS_ENSURE_ARG_MIN(aItemId, 1);
   NS_ENSURE_ARG_POINTER(_index);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, false);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   // With respect to the API.
   if (NS_FAILED(rv)) {
     *_index = -1;
     return NS_OK;
   }
 
   *_index = bookmark.position;
   return NS_OK;
@@ -2665,38 +2686,42 @@ nsNavBookmarks::GetItemIndex(PRInt64 aIt
 
 NS_IMETHODIMP
 nsNavBookmarks::SetItemIndex(PRInt64 aItemId, PRInt32 aNewIndex)
 {
   NS_ENSURE_ARG_MIN(aItemId, 1);
   NS_ENSURE_ARG_MIN(aNewIndex, 0);
 
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, true);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Ensure we are not going out of range.
   PRInt32 folderCount;
   PRInt64 grandParentId;
   nsCAutoString folderGuid;
   rv = FetchFolderInfo(bookmark.parentId, &folderCount, folderGuid, &grandParentId);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(aNewIndex < folderCount, NS_ERROR_INVALID_ARG);
   // Check the parent's guid is the expected one.
   MOZ_ASSERT(bookmark.parentGuid == folderGuid);
 
+  BEGIN_CRITICAL_BOOKMARK_CACHE_SECTION(bookmark.id);
+
   DECLARE_AND_ASSIGN_SCOPED_LAZY_STMT(stmt, mDBSetItemIndex);
   rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), aItemId);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("item_index"), aNewIndex);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = stmt->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  END_CRITICAL_BOOKMARK_CACHE_SECTION(bookmark.id);
+
   NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
                    nsINavBookmarkObserver,
                    OnItemMoved(bookmark.id,
                                bookmark.parentId,
                                bookmark.position,
                                bookmark.parentId,
                                aNewIndex,
                                bookmark.type,
@@ -2724,17 +2749,17 @@ nsNavBookmarks::UpdateKeywordsHashForRem
 NS_IMETHODIMP
 nsNavBookmarks::SetKeywordForBookmark(PRInt64 aBookmarkId,
                                       const nsAString& aUserCasedKeyword)
 {
   NS_ENSURE_ARG_MIN(aBookmarkId, 1);
 
   // This also ensures the bookmark is valid.
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aBookmarkId, bookmark, true);
+  nsresult rv = FetchItemInfo(aBookmarkId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = EnsureKeywordsHash();
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Shortcuts are always lowercased internally.
   nsAutoString keyword(aUserCasedKeyword);
   ToLowerCase(keyword);
@@ -2743,16 +2768,18 @@ nsNavBookmarks::SetKeywordForBookmark(PR
   nsAutoString oldKeyword;
   rv = GetKeywordForBookmark(bookmark.id, oldKeyword);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Trying to set the same value or to remove a nonexistent keyword is a no-op.
   if (keyword.Equals(oldKeyword) || (keyword.IsEmpty() && oldKeyword.IsEmpty()))
     return NS_OK;
 
+  BEGIN_CRITICAL_BOOKMARK_CACHE_SECTION(bookmark.id);
+
   mozStorageTransaction transaction(mDBConn, PR_FALSE);
 
   nsCOMPtr<mozIStorageStatement> updateBookmarkStmt;
   rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
     "UPDATE moz_bookmarks "
     "SET keyword_id = (SELECT id FROM moz_keywords WHERE keyword = :keyword), "
         "lastModified = :date "
     "WHERE id = :item_id "
@@ -2793,16 +2820,18 @@ nsNavBookmarks::SetKeywordForBookmark(PR
                                            bookmark.id);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = updateBookmarkStmt->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = transaction.Commit();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  END_CRITICAL_BOOKMARK_CACHE_SECTION(bookmark.id);
+
   NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
                    nsINavBookmarkObserver,
                    OnItemChanged(bookmark.id,
                                  NS_LITERAL_CSTRING("keyword"),
                                  PR_FALSE,
                                  NS_ConvertUTF16toUTF8(keyword),
                                  bookmark.lastModified,
                                  bookmark.type,
@@ -3138,17 +3167,17 @@ nsNavBookmarks::OnPageChanged(nsIURI* aU
       nsCOMArray<nsNavHistoryQuery> queries;
       nsCOMPtr<nsNavHistoryQueryOptions> options;
       rv = history->QueryStringToQueryArray(changeData.bookmark.url,
                                             &queries, getter_AddRefs(options));
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (queries.Count() == 1 && queries[0]->Folders().Length() == 1) {
         // Fetch missing data.
-        rv = FetchItemInfo(queries[0]->Folders()[0], changeData.bookmark, false);
+        rv = FetchItemInfo(queries[0]->Folders()[0], changeData.bookmark);
         NS_ENSURE_SUCCESS(rv, rv);        
         NotifyItemChanged(changeData);
       }
     }
     else {
       nsRefPtr< AsyncGetBookmarksForURI<ItemChangeMethod, ItemChangeData> > notifier =
         new AsyncGetBookmarksForURI<ItemChangeMethod, ItemChangeData>(this, &nsNavBookmarks::NotifyItemChanged, changeData);
       notifier->Init();
@@ -3190,17 +3219,17 @@ nsNavBookmarks::OnPageAnnotationSet(nsIU
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsNavBookmarks::OnItemAnnotationSet(PRInt64 aItemId, const nsACString& aName)
 {
   BookmarkData bookmark;
-  nsresult rv = FetchItemInfo(aItemId, bookmark, true);
+  nsresult rv = FetchItemInfo(aItemId, bookmark);
   NS_ENSURE_SUCCESS(rv, rv);
 
   bookmark.lastModified = PR_Now();
   rv = SetItemDateInternal(GetStatement(mDBSetItemLastModified),
                            bookmark.id, bookmark.lastModified);
   NS_ENSURE_SUCCESS(rv, rv);
 
   NOTIFY_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
--- a/toolkit/components/places/nsNavBookmarks.h
+++ b/toolkit/components/places/nsNavBookmarks.h
@@ -223,22 +223,19 @@ public:
 
   /**
    * Fetches information about the specified id from the database.
    *
    * @param aItemId
    *        Id of the item to fetch information for.
    * @param aBookmark
    *        BookmarkData to store the information.
-   * @param aInvalidateCache
-   *        True if the cache should discard its entry after the fetching.
    */
   nsresult FetchItemInfo(PRInt64 aItemId,
-                         BookmarkData& _bookmark,
-                         bool aInvalidateCache);
+                         BookmarkData& _bookmark);
 
   /**
    * Finalize all internal statements.
    */
   nsresult FinalizeStatements();
 
   mozIStorageStatement* GetStatementById(BookmarkStatementId aStatementId)
   {
@@ -516,17 +513,17 @@ private:
     RemoveFolderTransaction(PRInt64 aID) : mID(aID) {}
 
     NS_DECL_ISUPPORTS
 
     NS_IMETHOD DoTransaction() {
       nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
       NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
       BookmarkData folder;
-      nsresult rv = bookmarks->FetchItemInfo(mID, folder, true);
+      nsresult rv = bookmarks->FetchItemInfo(mID, folder);
       // TODO (Bug 656935): store the BookmarkData struct instead.
       mParent = folder.parentId;
       mIndex = folder.position;
 
       rv = bookmarks->GetItemTitle(mID, mTitle);
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsCAutoString type;
new file mode 100644
--- /dev/null
+++ b/toolkit/components/places/tests/bookmarks/test_675416.js
@@ -0,0 +1,57 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function run_test() {
+  /**
+   * Requests information to the service, so that bookmark's data is cached.
+   * @param aItemId
+   *        Id of the bookmark to be cached.
+   */
+  function forceBookmarkCaching(aItemId) {
+    PlacesUtils.bookmarks.getFolderIdForItem(aItemId);
+  }
+
+  let observer = {
+    onBeginUpdateBatch: function() forceBookmarkCaching(itemId1),
+    onEndUpdateBatch: function() forceBookmarkCaching(itemId1),
+    onItemAdded: forceBookmarkCaching,
+    onItemChanged: forceBookmarkCaching,
+    onItemMoved: forceBookmarkCaching,
+    onBeforeItemRemoved: forceBookmarkCaching,
+    onItemRemoved: function(id) {
+      try {
+        forceBookmarkCaching(id);
+        do_throw("trying to fetch a removed bookmark should throw");
+      } catch (ex) {}
+    },
+    onItemVisited: forceBookmarkCaching,
+    QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver])
+  };
+  PlacesUtils.bookmarks.addObserver(observer, false);
+
+  let folderId1 = PlacesUtils.bookmarks
+                             .createFolder(PlacesUtils.bookmarksMenuFolderId,
+                                           "Bookmarks",
+                                           PlacesUtils.bookmarks.DEFAULT_INDEX);
+  let itemId1 = PlacesUtils.bookmarks
+                           .insertBookmark(folderId1,
+                                           NetUtil.newURI("http:/www.wired.com/wiredscience"),
+                                           PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                           "Wired Science");
+
+  PlacesUtils.bookmarks.removeItem(folderId1);
+
+  let folderId2 = PlacesUtils.bookmarks
+                             .createFolder(PlacesUtils.bookmarksMenuFolderId,
+                                           "Science",
+                                           PlacesUtils.bookmarks.DEFAULT_INDEX);
+  let folderId3 = PlacesUtils.bookmarks
+                             .createFolder(folderId2,
+                                           "Blogs",
+                                           PlacesUtils.bookmarks.DEFAULT_INDEX);
+  // Check title is correctly reported.
+  do_check_eq(PlacesUtils.bookmarks.getItemTitle(folderId3), "Blogs");
+  do_check_eq(PlacesUtils.bookmarks.getItemTitle(folderId2), "Science");
+
+  PlacesUtils.bookmarks.removeObserver(observer, false);
+}
--- a/toolkit/components/places/tests/bookmarks/xpcshell.ini
+++ b/toolkit/components/places/tests/bookmarks/xpcshell.ini
@@ -26,9 +26,10 @@ tail =
 [test_getBookmarkedURIFor.js]
 [test_keywords.js]
 [test_livemarks.js]
 [test_nsINavBookmarkObserver.js]
 [test_onBeforeItemRemoved_observer.js]
 [test_removeItem.js]
 [test_restore_guids.js]
 [test_savedsearches.js]
+[test_675416.js]
 
--- a/toolkit/xre/test/win/TestDllInterceptor.cpp
+++ b/toolkit/xre/test/win/TestDllInterceptor.cpp
@@ -35,35 +35,35 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include <stdio.h>
 #include "nsWindowsDllInterceptor.h"
 
 static bool patched_func_called = false;
 
-static BOOL (WINAPI *orig_GetVersionExA)(__inout LPOSVERSIONINFO);
+static BOOL (WINAPI *orig_GetVersionExA)(LPOSVERSIONINFO);
 
 static BOOL WINAPI
-patched_GetVersionExA(__inout LPOSVERSIONINFO lpVersionInfo)
+patched_GetVersionExA(LPOSVERSIONINFO lpVersionInfo)
 {
   patched_func_called = true;
   return orig_GetVersionExA(lpVersionInfo);
 }
 
 bool osvi_equal(OSVERSIONINFO &info0, OSVERSIONINFO &info1)
 {
   return (info0.dwMajorVersion == info1.dwMajorVersion &&
           info0.dwMinorVersion == info1.dwMinorVersion &&
           info0.dwBuildNumber == info1.dwBuildNumber &&
           info0.dwPlatformId == info1.dwPlatformId &&
           !strncmp(info0.szCSDVersion, info1.szCSDVersion, sizeof(info0.szCSDVersion)));
 }
 
-int wmain()
+int main()
 {
   OSVERSIONINFO info0, info1;
   ZeroMemory(&info0, sizeof(OSVERSIONINFO));
   ZeroMemory(&info1, sizeof(OSVERSIONINFO));
   info0.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
   info1.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
 
   GetVersionExA(&info0);
--- a/widget/src/windows/nsFilePicker.h
+++ b/widget/src/windows/nsFilePicker.h
@@ -101,17 +101,17 @@ protected:
 
 // The constructor will obtain the working path, the destructor
 // will set the working path back to what it used to be.
 class AutoRestoreWorkingPath
 {
 public:
   AutoRestoreWorkingPath();
   ~AutoRestoreWorkingPath();
-  inline bool AutoRestoreWorkingPath::HasWorkingPath() const
+  inline bool HasWorkingPath() const
   {
     return mWorkingPath != NULL;
   }
 
 private:
   nsAutoArrayPtr<PRUnichar> mWorkingPath;
 };