Bug 815952 - Stop clearing clipboard data originating from a private window after closing private windows. r=ehsan

This reverts bug 462106.
This commit is contained in:
Birunthan Mohanathas 2014-07-14 12:35:30 -07:00
parent 124259226c
commit 15ce305024
12 changed files with 4 additions and 335 deletions

View File

@ -137,14 +137,6 @@ nsClipboard::SetData(nsITransferable *aTransferable,
return NS_OK;
}
nsresult rv;
if (!mPrivacyHandler) {
rv = NS_NewClipboardPrivacyHandler(getter_AddRefs(mPrivacyHandler));
NS_ENSURE_SUCCESS(rv, rv);
}
rv = mPrivacyHandler->PrepareDataForClipboard(aTransferable);
NS_ENSURE_SUCCESS(rv, rv);
// Clear out the clipboard in order to set the new data
EmptyClipboard(aWhichClipboard);
@ -154,7 +146,8 @@ nsClipboard::SetData(nsITransferable *aTransferable,
// Get the types of supported flavors
nsCOMPtr<nsISupportsArray> flavors;
rv = aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavors));
nsresult rv =
aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavors));
if (!flavors || NS_FAILED(rv))
return NS_ERROR_FAILURE;

View File

@ -9,8 +9,7 @@
#define __nsClipboard_h_
#include "nsIClipboard.h"
#include "nsClipboardPrivacyHandler.h"
#include "nsAutoPtr.h"
#include "nsIObserver.h"
#include <gtk/gtk.h>
class nsClipboard : public nsIClipboard,
@ -53,7 +52,6 @@ private:
nsCOMPtr<nsIClipboardOwner> mGlobalOwner;
nsCOMPtr<nsITransferable> mSelectionTransferable;
nsCOMPtr<nsITransferable> mGlobalTransferable;
nsRefPtr<nsClipboardPrivacyHandler> mPrivacyHandler;
};

View File

@ -468,14 +468,6 @@ nsClipboard::SetData(nsITransferable *aTransferable,
return NS_OK;
}
nsresult rv;
if (!mPrivacyHandler) {
rv = NS_NewClipboardPrivacyHandler(getter_AddRefs(mPrivacyHandler));
NS_ENSURE_SUCCESS(rv, rv);
}
rv = mPrivacyHandler->PrepareDataForClipboard(aTransferable);
NS_ENSURE_SUCCESS(rv, rv);
EmptyClipboard(aWhichClipboard);
QClipboard::Mode mode;

View File

@ -8,8 +8,6 @@
#include "nsIClipboard.h"
#include "nsITransferable.h"
#include "nsIClipboardOwner.h"
#include "nsClipboardPrivacyHandler.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include <qclipboard.h>

View File

@ -8,7 +8,6 @@ support-files = window_bug429954.xul
[test_bug478536.xul]
skip-if = true # Bug 561929
support-files = window_bug478536.xul
[test_bug462106_perwindow.xul]
[test_bug517396.xul]
[test_bug538242.xul]
support-files = window_bug538242.xul

View File

@ -1,136 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=462106
-->
<window title="Mozilla Bug 462106"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="initAndRunTests()">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
</body>
<!-- test code goes here -->
<script class="testbody" type="application/javascript">
<![CDATA[
/** Test for Bug 462106 **/
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
function copy(str, doc) {
if (!doc) {
doc = document;
}
Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper).
copyString(str, doc);
}
function getLoadContext() {
return window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsILoadContext);
}
function paste() {
let trans = Cc["@mozilla.org/widget/transferable;1"].
createInstance(Ci.nsITransferable);
trans.init(getLoadContext());
trans.addDataFlavor("text/unicode");
let clip = Cc["@mozilla.org/widget/clipboard;1"].
getService(Ci.nsIClipboard);
clip.getData(trans, Ci.nsIClipboard.kGlobalClipboard);
let str = {}, length = {};
try {
trans.getTransferData("text/unicode", str, length);
} catch (e) {
str = null;
}
if (str) {
str = str.value.QueryInterface(Ci.nsISupportsString);
if (str)
str = str.data.substring(0, length.value / 2);
}
return str;
}
function whenDelayedStartupFinished(aWindow, aCallback) {
Services.obs.addObserver(function observer(aSubject, aTopic) {
if (aWindow == aSubject) {
Services.obs.removeObserver(observer, aTopic);
setTimeout(aCallback, 0);
}
}, "browser-delayed-startup-finished", false);
}
function testOnWindow(options, callback) {
var mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
let win = mainWindow.OpenBrowserWindow(options);
whenDelayedStartupFinished(win, function() {
callback(win);
});
};
function initAndRunTests() {
SimpleTest.waitForExplicitFinish();
const data = "random number: " + Math.random();
copy(data);
is(data, paste(), "Data successfully copied before entering the private browsing mode");
testOnWindow({private: true}, function (aPrivateWindow) {
aPrivateWindow.close();
// the data should still be on the clipboard because it was copied before
// entering the private browsing mode
is(data, paste(), "Copied data persisted after leaving the private browsing mode");
const data2 = "another random number: " + Math.random();
testOnWindow({private: true}, function (aPrivateWindow) {
copy(data2, aPrivateWindow.document); // copy the data inside the private browsing mode
function insidePBPaste() {
if (data2 != paste()) {
setTimeout(insidePBPaste, 100);
return;
}
// the data should be on the clipboard inside the private browsing mode
is(data2, paste(), "Data successfully copied inside the private browsing mode");
aPrivateWindow.close();
function afterClose() {
if (data2 == paste()) {
setTimeout(afterClose, 100);
return;
}
// the data should no longer be on the clipboard at this stage
isnot(data2, paste(), "Data no longer available after leaving the private browsing mode");
SimpleTest.finish();
}
afterClose();
}
insidePBPaste();
});
});
}
]]>
</script>
</window>

View File

@ -7,6 +7,7 @@
#define nsClipboard_h__
#include "nsBaseClipboard.h"
#include "nsIObserver.h"
#include "nsIURI.h"
#include <windows.h>

View File

@ -22,7 +22,6 @@ UNIFIED_SOURCES += [
'nsBaseDragService.cpp',
'nsBaseScreen.cpp',
'nsClipboardHelper.cpp',
'nsClipboardPrivacyHandler.cpp',
'nsClipboardProxy.cpp',
'nsColorPickerProxy.cpp',
'nsContentProcessWidgetFactory.cpp',

View File

@ -59,12 +59,6 @@ NS_IMETHODIMP nsBaseClipboard::SetData(nsITransferable * aTransferable, nsIClipb
if ( mTransferable ) {
NS_ADDREF(mTransferable);
if (!mPrivacyHandler) {
rv = NS_NewClipboardPrivacyHandler(getter_AddRefs(mPrivacyHandler));
NS_ENSURE_SUCCESS(rv, rv);
}
rv = mPrivacyHandler->PrepareDataForClipboard(mTransferable);
NS_ENSURE_SUCCESS(rv, rv);
rv = SetNativeClipboardData(aWhichClipboard);
}

View File

@ -8,8 +8,6 @@
#include "nsIClipboard.h"
#include "nsITransferable.h"
#include "nsClipboardPrivacyHandler.h"
#include "nsAutoPtr.h"
class nsITransferable;
class nsDataObj;
@ -42,7 +40,6 @@ protected:
bool mIgnoreEmptyNotification;
nsIClipboardOwner * mClipboardOwner;
nsITransferable * mTransferable;
nsRefPtr<nsClipboardPrivacyHandler> mPrivacyHandler;
};

View File

@ -1,124 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ArrayUtils.h"
#include "nsClipboardPrivacyHandler.h"
#include "nsITransferable.h"
#include "nsISupportsPrimitives.h"
#include "nsIObserverService.h"
#include "nsIClipboard.h"
#include "nsComponentManagerUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsLiteralString.h"
#include "nsNetCID.h"
#include "nsXPCOM.h"
#include "mozilla/Services.h"
#if defined(XP_WIN)
#include <ole2.h>
#endif
using namespace mozilla;
#define NS_MOZ_DATA_FROM_PRIVATEBROWSING "application/x-moz-private-browsing"
NS_IMPL_ISUPPORTS(nsClipboardPrivacyHandler, nsIObserver, nsISupportsWeakReference)
nsresult
nsClipboardPrivacyHandler::Init()
{
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (!observerService)
return NS_ERROR_FAILURE;
return observerService->AddObserver(this, "last-pb-context-exited", true);
}
/**
* Prepare the transferable object to be inserted into the clipboard
*
*/
nsresult
nsClipboardPrivacyHandler::PrepareDataForClipboard(nsITransferable * aTransferable)
{
NS_ASSERTION(aTransferable, "clipboard given a null transferable");
bool isPrivateData = false;
aTransferable->GetIsPrivateData(&isPrivateData);
nsresult rv = NS_OK;
if (isPrivateData) {
nsCOMPtr<nsISupportsPRBool> data = do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
if (data) {
rv = data->SetData(true);
NS_ENSURE_SUCCESS(rv, rv);
// Ignore the error code of AddDataFlavor, since we might have added
// this flavor before. If this call really fails, so will the next
// one (SetTransferData).
aTransferable->AddDataFlavor(NS_MOZ_DATA_FROM_PRIVATEBROWSING);
rv = aTransferable->SetTransferData(NS_MOZ_DATA_FROM_PRIVATEBROWSING, data, sizeof(bool));
NS_ENSURE_SUCCESS(rv, rv);
}
}
return rv;
}
NS_IMETHODIMP
nsClipboardPrivacyHandler::Observe(nsISupports *aSubject, char const *aTopic, char16_t const *aData)
{
nsresult rv;
nsCOMPtr<nsIClipboard> clipboard =
do_GetService("@mozilla.org/widget/clipboard;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
const char * flavors[] = { NS_MOZ_DATA_FROM_PRIVATEBROWSING };
bool haveFlavors;
rv = clipboard->HasDataMatchingFlavors(flavors,
ArrayLength(flavors),
nsIClipboard::kGlobalClipboard,
&haveFlavors);
if (NS_SUCCEEDED(rv) && haveFlavors) {
#if defined(XP_WIN)
// Workaround for bug 518412. On Windows 7 x64, there is a bug
// in handling clipboard data without any formats between
// 32-bit/64-bit boundaries, which could lead Explorer to crash.
// We work around the problem by clearing the clipboard using
// the usual Win32 API.
NS_ENSURE_TRUE(SUCCEEDED(::OleSetClipboard(nullptr)), NS_ERROR_FAILURE);
#else
// Empty the native clipboard by copying an empty transferable
nsCOMPtr<nsITransferable> nullData =
do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nullData->Init(nullptr);
rv = clipboard->SetData(nullData, nullptr,
nsIClipboard::kGlobalClipboard);
NS_ENSURE_SUCCESS(rv, rv);
#endif
}
return NS_OK;
}
nsresult
NS_NewClipboardPrivacyHandler(nsClipboardPrivacyHandler ** aHandler)
{
NS_PRECONDITION(aHandler != nullptr, "null ptr");
if (!aHandler)
return NS_ERROR_NULL_POINTER;
*aHandler = new nsClipboardPrivacyHandler();
NS_ADDREF(*aHandler);
nsresult rv = (*aHandler)->Init();
if (NS_FAILED(rv))
NS_RELEASE(*aHandler);
return rv;
}

View File

@ -1,42 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsClipboardPrivacyHandler_h__
#define nsClipboardPrivacyHandler_h__
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsCOMPtr.h"
#include "mozilla/Attributes.h"
class nsITransferable;
// nsClipboardPrivacyHandler makes sure that clipboard data copied during
// the private browsing mode does not leak after exiting this mode.
// In order to ensure this, callers should store an object of this class
// for their lifetime, and call PrepareDataForClipboard in their
// nsIClipboard::SetData implementation before starting to use the
// nsITransferable object in any way.
class nsClipboardPrivacyHandler MOZ_FINAL : public nsIObserver,
public nsSupportsWeakReference
{
~nsClipboardPrivacyHandler() {}
public:
// nsISupports
NS_DECL_ISUPPORTS
// nsIObserver
NS_DECL_NSIOBSERVER
nsresult Init();
nsresult PrepareDataForClipboard(nsITransferable * aTransferable);
};
nsresult NS_NewClipboardPrivacyHandler(nsClipboardPrivacyHandler ** aHandler);
#endif // nsClipboardPrivacyHandler_h__