Merge plugin changes from electrolysis to mozilla-central.

This commit is contained in:
Benjamin Smedberg 2009-12-16 19:06:54 -05:00
commit 0177a8612f
26 changed files with 240 additions and 265 deletions

View File

@ -3091,10 +3091,10 @@ const BrowserSearch = {
return;
}
#endif
if (window.fullScreen)
var searchBar = this.searchBar;
if (searchBar && window.fullScreen)
FullScreen.mouseoverToggle(true);
var searchBar = this.searchBar;
if (isElementVisible(searchBar)) {
searchBar.select();
searchBar.focus();

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=4 ts=4 et :
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
@ -43,6 +43,8 @@
#include "npapi.h"
#include "nscore.h"
class nsNPAPIPlugin;
namespace mozilla {
class PluginLibrary
@ -50,6 +52,12 @@ class PluginLibrary
public:
virtual ~PluginLibrary() { }
/**
* Inform this library about the nsNPAPIPlugin which owns it. This
* object will hold a weak pointer to the plugin.
*/
virtual void SetPlugin(nsNPAPIPlugin* plugin) = 0;
virtual bool HasRequiredFunctions() = 0;
#if defined(XP_UNIX) && !defined(XP_MACOSX)

View File

@ -1268,14 +1268,35 @@ _poppopupsenabledstate(NPP aNPP)
return false;
}
class AsyncCallRunnable : public nsRunnable
{
public:
AsyncCallRunnable(PluginThreadCallback aFunc, void* aUserData)
: mFunc(aFunc)
, mData(aUserData)
{ }
NS_IMETHOD Run() {
mFunc(mData);
return NS_OK;
}
private:
PluginThreadCallback mFunc;
void* mData;
};
void NP_CALLBACK
_pluginthreadasynccall(NPP aNPP,
PluginThreadCallback aFunc,
void* aUserData)
{
_MOZ_LOG(__FUNCTION__);
AssertPluginThread();
NS_NOTYETIMPLEMENTED("Implement me!");
if (!aFunc)
return;
nsCOMPtr<nsIRunnable> e(new AsyncCallRunnable(aFunc, aUserData));
NS_DispatchToMainThread(e);
}
NPError NP_CALLBACK

View File

@ -69,6 +69,7 @@ PluginModuleParent::PluginModuleParent(const char* aFilePath)
: mSubprocess(new PluginProcessParent(aFilePath))
, mShutdown(false)
, mNPNIface(NULL)
, mPlugin(NULL)
{
NS_ASSERTION(mSubprocess, "Out of memory!");
@ -97,9 +98,16 @@ PluginModuleParent::ActorDestroy(ActorDestroyReason why)
{
switch (why) {
case AbnormalShutdown:
// TODObsmedberg: notify the plugin host to forget this plugin module
// and instantiate us again.
// FALL THROUGH
mShutdown = true;
// Defer the PluginCrashed method so that we don't re-enter
// and potentially modify the actor child list while enumerating it.
if (mPlugin) {
nsCOMPtr<nsIRunnable> r =
new nsRunnableMethod<nsNPAPIPlugin>(
mPlugin, &nsNPAPIPlugin::PluginCrashed);
NS_DispatchToMainThread(r);
}
break;
case NormalShutdown:
mShutdown = true;

View File

@ -97,9 +97,13 @@ protected:
public:
PluginModuleParent(const char* aFilePath);
virtual ~PluginModuleParent();
NS_OVERRIDE virtual void SetPlugin(nsNPAPIPlugin* plugin)
{
mPlugin = plugin;
}
NS_OVERRIDE virtual void ActorDestroy(ActorDestroyReason why);
/**
@ -213,6 +217,7 @@ private:
bool mShutdown;
const NPNetscapeFuncs* mNPNIface;
nsTHashtable<nsVoidPtrHashKey> mValidIdentifiers;
nsNPAPIPlugin* mPlugin;
};
} // namespace plugins

View File

@ -83,6 +83,8 @@ public:
// unref here??
}
virtual void SetPlugin(nsNPAPIPlugin*) { }
virtual bool HasRequiredFunctions() {
mNP_Initialize = (NP_InitializeFunc)
PR_FindFunctionSymbol(mLibrary, "NP_Initialize");

View File

@ -315,7 +315,7 @@ nsAuthSSPI::GetNextToken(const void *inToken,
LOG(("entering nsAuthSSPI::GetNextToken()\n"));
if (!mCtxt.dwLower && !mCtxt.dwUpper) {
if (!mCred.dwLower && !mCred.dwUpper) {
LOG(("nsAuthSSPI::GetNextToken(), not initialized. exiting."));
return NS_ERROR_NOT_INITIALIZED;
}

View File

@ -542,10 +542,8 @@ public:
PRUint32 aPlatformCode, PRUint32 aScriptCode,
PRUint32 aLangCode, nsAString& dest);
static inline bool IsJoiner(PRUint32 ch) {
return (ch == 0x200C ||
ch == 0x200D ||
ch == 0x2060);
static inline bool IsJoinCauser(PRUint32 ch) {
return (ch == 0x200D);
}
static inline bool IsInvalid(PRUint32 ch) {

View File

@ -1564,9 +1564,9 @@ gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh, PRUint32 aNextCh,
{
nsRefPtr<gfxFont> selectedFont;
// if this character or the next one is a joiner use the
// same font as the previous range if we can
if (gfxFontUtils::IsJoiner(aCh) || gfxFontUtils::IsJoiner(aPrevCh) || gfxFontUtils::IsJoiner(aNextCh)) {
// if this character or the previous one is a join-causer,
// use the same font as the previous range if we can
if (gfxFontUtils::IsJoinCauser(aCh) || gfxFontUtils::IsJoinCauser(aPrevCh)) {
if (aPrevMatchedFont && aPrevMatchedFont->HasCharacter(aCh)) {
selectedFont = aPrevMatchedFont;
return selectedFont.forget();

View File

@ -170,7 +170,7 @@ skip-if(xulRuntime.OS=="WINNT"&&isDebugBuild) script regress-341360.js # slow
script regress-343713.js
script regress-343966.js
script regress-344711-n.js
script regress-344804.js # bug 524732
random-if(!xulRuntime.shell&&xulRuntime.OS=="WINNT") script regress-344804.js # bug 524732
script regress-344959.js
script regress-346237.js
script regress-346801.js

View File

@ -1,6 +1,6 @@
url-prefix ../../jsreftest.html?test=js1_5/Scope/
script regress-154693.js
script regress-181834.js # bug 524732
random-if(!xulRuntime.shell&&xulRuntime.OS=="WINNT") script regress-181834.js # bug 524732
script regress-184107.js
script regress-185485.js
script regress-191276.js

View File

@ -536,7 +536,7 @@ private:
PRBool SetupXShm();
void ReleaseXShm();
void NativeImageDraw(NPRect* invalidRect = nsnull);
PRBool UpdateVisibility();
PRBool UpdateVisibility(PRBool aVisible);
#endif
};
@ -5604,7 +5604,7 @@ void nsPluginInstanceOwner::SetPluginHost(nsIPluginHost* aHost)
}
#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2)
PRBool nsPluginInstanceOwner::UpdateVisibility()
PRBool nsPluginInstanceOwner::UpdateVisibility(PRBool aVisible)
{
if (!mInstance)
return PR_TRUE;
@ -5614,7 +5614,7 @@ PRBool nsPluginInstanceOwner::UpdateVisibility()
XVisibilityEvent& visibilityEvent = pluginEvent.xvisibility;
visibilityEvent.type = VisibilityNotify;
visibilityEvent.display = 0;
visibilityEvent.state = VisibilityUnobscured;
visibilityEvent.state = aVisible ? VisibilityUnobscured : VisibilityFullyObscured;
mInstance->HandleEvent(&pluginEvent, &handled);
mWidgetVisible = PR_TRUE;
@ -5789,7 +5789,7 @@ nsPluginInstanceOwner::SetAbsoluteScreenPosition(nsIDOMElement* element,
mBlitParentElement = element;
UpdateVisibility();
UpdateVisibility(!(width == 0 && height == 0));
if (!mInstance)
return NS_OK;

View File

@ -0,0 +1,17 @@
<html lang="ar">
<head>
<style type="text/css">
body {
font-family: foo, sans-serif;
font-size: 300%;
line-height: 2em;
}
</style>
<body>
<p>&#x06AF; &#x0632;</p>
<p>&#x06AF; &#x0632;</p>
<p>&#x06AF; &#x0632;</p>
<p>&#x06AF; &#x0632;</p>
<p>&#x06AF; &#x0632;</p>
</body>
</html>

View File

@ -0,0 +1,17 @@
<html lang="ar">
<head>
<style type="text/css">
body {
font-family: foo, sans-serif;
font-size: 300%;
line-height: 2em;
}
</style>
<body>
<p>&#x06AF; &#x0632;</p>
<p>&#x200c;&#x06AF; &#x0632;</p>
<p>&#x06AF;&#x200c; &#x0632;</p>
<p>&#x06AF; &#x200c;&#x0632;</p>
<p>&#x06AF; &#x0632;&#x200c;</p>
</body>
</html>

View File

@ -1353,3 +1353,4 @@ fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") == 488692-1.html 488692-1-ref.html # needs
== 530686-1.html 530686-1-ref.html
== 531098-1.html 531098-1-ref.html
== 531371-1.html 531371-1-ref.html
== 534919-1.html 534919-1-ref.html

View File

@ -280,6 +280,7 @@ nsNPAPIPlugin::nsNPAPIPlugin(NPPluginFuncs* callbacks,
#endif
fLibrary = aLibrary;
fLibrary->SetPlugin(this);
}
nsNPAPIPlugin::~nsNPAPIPlugin()
@ -299,6 +300,15 @@ nsNPAPIPlugin::SetPluginRefNum(short aRefNum)
}
#endif
#ifdef MOZ_IPC
void
nsNPAPIPlugin::PluginCrashed()
{
nsRefPtr<nsPluginHost> host = dont_AddRef(nsPluginHost::GetInst());
host->PluginCrashed(this);
}
#endif
namespace {
#ifdef MOZ_IPC

View File

@ -94,6 +94,12 @@ public:
void SetPluginRefNum(short aRefNum);
#endif
#ifdef MOZ_IPC
// The IPC mechanism notifies the nsNPAPIPlugin if the plugin crashes and is
// no longer usable.
void PluginCrashed();
#endif
protected:
// Ensures that the static CALLBACKS is properly initialized
static void CheckClassInitialized(void);

View File

@ -1754,9 +1754,10 @@ nsPluginHost::~nsPluginHost()
sInst = nsnull;
}
NS_IMPL_ISUPPORTS3(nsPluginHost,
NS_IMPL_ISUPPORTS4(nsPluginHost,
nsIPluginHost,
nsIObserver,
nsITimerCallback,
nsISupportsWeakReference)
nsPluginHost*
@ -5180,6 +5181,44 @@ NS_IMETHODIMP nsPluginHost::Notify(nsITimer* timer)
return NS_ERROR_FAILURE;
}
#ifdef MOZ_IPC
void
nsPluginHost::PluginCrashed(nsNPAPIPlugin* aPlugin)
{
// Find the nsPluginTag corresponding to this plugin
nsPluginTag* plugin;
for (plugin = mPlugins; plugin; plugin = plugin->mNext) {
if (plugin->mEntryPoint == aPlugin)
break;
}
if (!plugin) {
NS_WARNING("nsPluginTag not found in nsPluginHost::PluginCrashed");
return;
}
// Invalidate each nsPluginInstanceTag for the crashed plugin
nsPluginInstanceTag** pinstancetag = &mPluginInstanceTagList.mFirst;
while (*pinstancetag) {
nsPluginInstanceTag* instancetag = *pinstancetag;
if (instancetag->mPluginTag == plugin) {
*pinstancetag = (*pinstancetag)->mNext;
delete instancetag;
}
else {
pinstancetag = &(*pinstancetag)->mNext;
}
}
// Only after all instances have been invalidated is it safe to null
// out nsPluginTag.mEntryPoint. The next time we try to create an
// instance of this plugin we reload it (launch a new plugin process).
plugin->mEntryPoint = nsnull;
}
#endif
nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request,
nsISupports* aContext)
{

View File

@ -161,7 +161,11 @@ public:
void AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible);
void RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame);
#ifdef MOZ_IPC
void PluginCrashed(nsNPAPIPlugin* plugin);
#endif
private:
nsresult
TrySetUpPluginInstance(const char *aMimeType, nsIURI *aURL, nsIPluginInstanceOwner *aOwner);

View File

@ -69,12 +69,12 @@ _MOCHITEST_FILES = \
# test_npruntime_npnsetexception.html \ Disabled for e10s
#ifdef MOZ_IPC
#_MOCHITEST_FILES += \
# test_crashing.html \
# crashing_subpage.html \
# $(NULL)
#endif
ifdef MOZ_IPC
_MOCHITEST_FILES += \
test_crashing.html \
crashing_subpage.html \
$(NULL)
endif
ifeq ($(OS_ARCH),WINNT)
_MOCHITEST_FILES += \

View File

@ -128,23 +128,23 @@ const NetUtil = {
},
/**
* Asynchronously opens a source and fetches the response. A source can be
* an nsIURI, nsIFile, string spec, or nsIChannel. The provided callback
* will get an input stream containing the response, and the result code.
* Asynchronously opens a channel and fetches the response. The provided
* callback will get an input stream containing the response, and the result
* code.
*
* @param aSource
* The nsIURI, nsIFile, string spec, or nsIChannel to open.
* @param aChannel
* The nsIChannel to open.
* @param aCallback
* The callback function that will be notified upon completion. It
* will get two arguments:
* 1) An nsIInputStream containing the data from the channel, if any.
* 2) The status code from opening the source.
* 2) The status code from opening the channel.
*/
asyncFetch: function NetUtil_asyncOpen(aSource, aCallback)
asyncFetch: function NetUtil_asyncOpen(aChannel, aCallback)
{
if (!aSource || !aCallback) {
if (!aChannel || !aCallback) {
let exception = new Components.Exception(
"Must have a source and a callback",
"Must have a channel and a callback",
Cr.NS_ERROR_INVALID_ARG,
Components.stack.caller
);
@ -168,12 +168,7 @@ const NetUtil = {
}
});
let channel = aSource;
if (!(channel instanceof Ci.nsIChannel)) {
channel = this.newChannel(aSource);
}
channel.asyncOpen(listener, null);
aChannel.asyncOpen(listener, null);
},
/**
@ -209,41 +204,6 @@ const NetUtil = {
return this.ioService.newURI(aTarget, aOriginCharset, aBaseURI);
},
/**
* Constructs a new channel for the given spec, character set, and base URI,
* or nsIURI, or nsIFile.
*
* @param aWhatToLoad
* The string spec for the desired URI, an nsIURI, or an nsIFile.
* @param aOriginCharset [optional]
* The character set for the URI. Only used if aWhatToLoad is a
* string.
* @param aBaseURI [optional]
* The base URI for the spec. Only used if aWhatToLoad is a string.
*
* @return an nsIChannel object.
*/
newChannel: function NetUtil_newChannel(aWhatToLoad, aOriginCharset,
aBaseURI)
{
if (!aWhatToLoad) {
let exception = new Components.Exception(
"Must have a non-null string spec, nsIURI, or nsIFile object",
Cr.NS_ERROR_INVALID_ARG,
Components.stack.caller
);
throw exception;
}
let uri = aWhatToLoad;
if (!(aWhatToLoad instanceof Ci.nsIURI)) {
// We either have a string or an nsIFile that we'll need a URI for.
uri = this.newURI(aWhatToLoad, aOriginCharset, aBaseURI);
}
return this.ioService.newChannelFromURI(uri);
},
/**
* Returns a reference to nsIIOService.
*

View File

@ -224,7 +224,7 @@ function test_asyncFetch_no_callback()
run_next_test();
}
function test_asyncFetch_with_nsIChannel()
function test_asyncFetch()
{
const TEST_DATA = "this is a test string";
@ -258,110 +258,6 @@ function test_asyncFetch_with_nsIChannel()
});
}
function test_asyncFetch_with_nsIURI()
{
const TEST_DATA = "this is a test string";
// Start the http server, and register our handler.
let server = new nsHttpServer();
server.registerPathHandler("/test", function(aRequest, aResponse) {
aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
aResponse.setHeader("Content-Type", "text/plain", false);
aResponse.write(TEST_DATA);
});
server.start(4444);
// Create our URI.
let uri = NetUtil.newURI("http://localhost:4444/test");
// Open our URI asynchronously.
NetUtil.asyncFetch(uri, function(aInputStream, aResult) {
// Check that we had success.
do_check_true(Components.isSuccessCode(aResult));
// Check that we got the right data.
do_check_eq(aInputStream.available(), TEST_DATA.length);
let is = Cc["@mozilla.org/scriptableinputstream;1"].
createInstance(Ci.nsIScriptableInputStream);
is.init(aInputStream);
let result = is.read(TEST_DATA.length);
do_check_eq(TEST_DATA, result);
server.stop(run_next_test);
});
}
function test_asyncFetch_with_string()
{
const TEST_DATA = "this is a test string";
// Start the http server, and register our handler.
let server = new nsHttpServer();
server.registerPathHandler("/test", function(aRequest, aResponse) {
aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
aResponse.setHeader("Content-Type", "text/plain", false);
aResponse.write(TEST_DATA);
});
server.start(4444);
// Open our location asynchronously.
NetUtil.asyncFetch("http://localhost:4444/test", function(aInputStream,
aResult) {
// Check that we had success.
do_check_true(Components.isSuccessCode(aResult));
// Check that we got the right data.
do_check_eq(aInputStream.available(), TEST_DATA.length);
let is = Cc["@mozilla.org/scriptableinputstream;1"].
createInstance(Ci.nsIScriptableInputStream);
is.init(aInputStream);
let result = is.read(TEST_DATA.length);
do_check_eq(TEST_DATA, result);
server.stop(run_next_test);
});
}
function test_asyncFetch_with_nsIFile()
{
const TEST_DATA = "this is a test string";
// First we need a file to read from.
let file = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
get("TmpD", Ci.nsIFile);
file.append("NetUtil-asyncFetch-test-file.tmp");
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
// Write the test data to the file.
let ostream = Cc["@mozilla.org/network/file-output-stream;1"].
createInstance(Ci.nsIFileOutputStream);
ostream.init(file, -1, -1, 0);
ostream.write(TEST_DATA, TEST_DATA.length);
// Sanity check to make sure the data was written.
do_check_eq(TEST_DATA, getFileContents(file));
// Open our file asynchronously.
NetUtil.asyncFetch(file, function(aInputStream, aResult) {
// Check that we had success.
do_check_true(Components.isSuccessCode(aResult));
// Check that we got the right data.
do_check_eq(aInputStream.available(), TEST_DATA.length);
let is = Cc["@mozilla.org/scriptableinputstream;1"].
createInstance(Ci.nsIScriptableInputStream);
is.init(aInputStream);
let result = is.read(TEST_DATA.length);
do_check_eq(TEST_DATA, result);
// Remove our test file.
file.remove(false);
run_next_test();
});
}
function test_asyncFetch_does_not_block()
{
// Create our channel that has no data.
@ -390,64 +286,6 @@ function test_asyncFetch_does_not_block()
});
}
function test_newChannel_no_specifier()
{
try {
NetUtil.newChannel();
do_throw("should throw!");
}
catch (e) {
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
}
run_next_test();
}
function test_newChannel_with_string()
{
const TEST_SPEC = "http://mozilla.org";
// Check that we get the same URI back from channel the IO service creates and
// the channel the utility method creates.
let ios = NetUtil.ioService;
let iosChannel = ios.newChannel(TEST_SPEC, null, null);
let NetUtilChannel = NetUtil.newChannel(TEST_SPEC);
do_check_true(iosChannel.URI.equals(NetUtilChannel.URI));
run_next_test();
}
function test_newChannel_with_nsIURI()
{
const TEST_SPEC = "http://mozilla.org";
// Check that we get the same URI back from channel the IO service creates and
// the channel the utility method creates.
let uri = NetUtil.newURI(TEST_SPEC);
let iosChannel = NetUtil.ioService.newChannelFromURI(uri);
let NetUtilChannel = NetUtil.newChannel(uri);
do_check_true(iosChannel.URI.equals(NetUtilChannel.URI));
run_next_test();
}
function test_newChannel_with_nsIFile()
{
let file = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
get("TmpD", Ci.nsIFile);
file.append("NetUtil-test-file.tmp");
// Check that we get the same URI back from channel the IO service creates and
// the channel the utility method creates.
let uri = NetUtil.newURI(file);
let iosChannel = NetUtil.ioService.newChannelFromURI(uri);
let NetUtilChannel = NetUtil.newChannel(uri);
do_check_true(iosChannel.URI.equals(NetUtilChannel.URI));
run_next_test();
}
////////////////////////////////////////////////////////////////////////////////
//// Test Runner
@ -460,15 +298,8 @@ let tests = [
test_ioService,
test_asyncFetch_no_channel,
test_asyncFetch_no_callback,
test_asyncFetch_with_nsIChannel,
test_asyncFetch_with_nsIURI,
test_asyncFetch_with_string,
test_asyncFetch_with_nsIFile,
test_asyncFetch,
test_asyncFetch_does_not_block,
test_newChannel_no_specifier,
test_newChannel_with_string,
test_newChannel_with_nsIURI,
test_newChannel_with_nsIFile,
];
let index = 0;

View File

@ -211,5 +211,6 @@ generate-snippet-%:
--application-ini-file=$(STAGEDIST)/application.ini \
--locale=$* \
--product=$(MOZ_PKG_APPNAME) \
--platform=$(MOZ_PKG_PLATFORM) \
--download-base-URL=$(DOWNLOAD_BASE_URL) \
--verbose

View File

@ -85,7 +85,6 @@ tier_gecko_dirs += ipc
endif
tier_gecko_dirs += \
$(tier_necko_dirs) \
js/src/xpconnect \
js/ctypes \
intl/chardet \

View File

@ -66,6 +66,10 @@ def main():
action="store",
dest="product",
help="[Required] This option is used to generate the URL to download the MAR file.")
parser.add_option("--platform",
action="store",
dest="platform",
help="[Required] This option is used to indicate which target platform.")
parser.add_option("--download-base-URL",
action="store",
dest="downloadBaseURL",
@ -80,7 +84,8 @@ def main():
for req, msg in (('marPath', "the absolute path to the where the MAR file is"),
('applicationIniFile', "the absolute path to the application.ini file."),
('locale', "a locale."),
('product', "specify a product.")):
('product', "specify a product."),
('platform', "specify the platform.")):
if not hasattr(options, req):
parser.error('You must specify %s' % msg)
@ -91,7 +96,8 @@ def main():
options.applicationIniFile,
options.locale,
options.downloadBaseURL,
options.product)
options.product,
options.platform)
f = open(os.path.join(options.marPath, 'complete.update.snippet'), 'wb')
f.write(snippet)
f.close()
@ -101,7 +107,7 @@ def main():
print snippet
def generateSnippet(abstDistDir, applicationIniFile, locale,
downloadBaseURL, product):
downloadBaseURL, product, platform):
# Let's extract information from application.ini
c = ConfigParser()
try:
@ -116,7 +122,7 @@ def generateSnippet(abstDistDir, applicationIniFile, locale,
product,
appVersion,
locale,
getPlatform())
platform)
# Let's determine the hash and the size of the MAR file
# This function exits the script if the file does not exist
(completeMarHash, completeMarSize) = getFileHashAndSize(
@ -148,14 +154,6 @@ sha1
return snippet
def getPlatform():
if platform.system() == "Linux":
return "linux-i686"
elif platform.system() in ("Windows", "Microsoft"):
return "win32"
elif platform.system() == "Darwin":
return "mac"
def getFileHashAndSize(filepath):
sha1Hash = 'UNKNOWN'
size = 'UNKNOWN'

View File

@ -41,6 +41,7 @@
*/
#import <Cocoa/Cocoa.h>
#include <dlfcn.h>
#include "nsAppShell.h"
#include "nsCOMPtr.h"
@ -431,6 +432,17 @@ nsAppShell::Init()
@selector(nsAppShell_NSApplication_beginModalSessionForWindow:));
nsToolkit::SwizzleMethods([NSApplication class], @selector(endModalSession:),
@selector(nsAppShell_NSApplication_endModalSession:));
if (nsToolkit::OnLeopardOrLater() && !nsToolkit::OnSnowLeopardOrLater()) {
dlopen("/System/Library/Frameworks/Carbon.framework/Frameworks/Print.framework/Versions/Current/Plugins/PrintCocoaUI.bundle/Contents/MacOS/PrintCocoaUI",
RTLD_LAZY);
Class PDEPluginCallbackClass = ::NSClassFromString(@"PDEPluginCallback");
nsresult rv1 = nsToolkit::SwizzleMethods(PDEPluginCallbackClass, @selector(initWithPrintWindowController:),
@selector(nsAppShell_PDEPluginCallback_initWithPrintWindowController:));
if (NS_SUCCEEDED(rv1)) {
nsToolkit::SwizzleMethods(PDEPluginCallbackClass, @selector(dealloc),
@selector(nsAppShell_PDEPluginCallback_dealloc));
}
}
gAppShellMethodsSwizzled = PR_TRUE;
}
@ -1104,3 +1116,41 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
}
@end
@interface PDEPluginCallback : NSObject
{
@public
id _printWindowController;
}
- (PMPrintSettings *)printSettings;
@end
@interface PDEPluginCallback (MethodSwizzling)
- (PDEPluginCallback *)nsAppShell_PDEPluginCallback_initWithPrintWindowController:(id)controller;
- (void)nsAppShell_PDEPluginCallback_dealloc;
@end
@implementation PDEPluginCallback (MethodSwizzling)
// On Leopard, the PDEPluginCallback class in Apple's PrintCocoaUI module
// fails to retain and release its PMPrintWindowController object. This
// causes the PMPrintWindowController to sometimes be deleted prematurely,
// leading to crashes on attempts to access it. One example is bug 396680,
// caused by attempting to call a deleted PMPrintWindowController object's
// printSettings method. We work around the problem by hooking the
// appropriate methods and retaining and releasing the object ourselves.
// PrintCocoaUI.bundle is a "plugin" of the Carbon framework's Print
// framework.
- (PDEPluginCallback *)nsAppShell_PDEPluginCallback_initWithPrintWindowController:(id)controller
{
return [self nsAppShell_PDEPluginCallback_initWithPrintWindowController:[controller retain]];
}
- (void)nsAppShell_PDEPluginCallback_dealloc
{
[self->_printWindowController release];
[self nsAppShell_PDEPluginCallback_dealloc];
}
@end