import changes from thunderbird-2.0.0.24

This commit is contained in:
roytam1 2018-05-01 14:29:08 +08:00
parent 550ebdaee7
commit 455fb87a48
80 changed files with 2958 additions and 826 deletions

View File

@ -666,13 +666,33 @@ nsChromeRegistry::Canonify(nsIURL* aChromeURL)
aChromeURL->SetPath(path);
}
else {
nsCAutoString filePath;
rv = aChromeURL->GetFilePath(filePath);
NS_ENSURE_SUCCESS(rv, rv);
if (filePath.Find(NS_LITERAL_CSTRING("..")) != -1 ||
filePath.FindChar(':') != -1) {
return NS_ERROR_DOM_BAD_URI;
// prevent directory traversals ("..")
// path is already unescaped once, but uris can get unescaped twice
const char* pos = path.BeginReading();
const char* end = path.EndReading();
while (pos < end) {
switch (*pos) {
case ':':
return NS_ERROR_DOM_BAD_URI;
case '.':
if (pos[1] == '.')
return NS_ERROR_DOM_BAD_URI;
break;
case '%':
// chrome: URIs with double-escapes are trying to trick us.
// watch for %2e, and %25 in case someone triple unescapes
if (pos[1] == '2' &&
( pos[2] == 'e' || pos[2] == 'E' ||
pos[2] == '5' ))
return NS_ERROR_DOM_BAD_URI;
break;
case '?':
case '#':
// ignore query or ref part, we're done
pos = end;
continue;
}
++pos;
}
}
@ -1965,7 +1985,7 @@ CheckVersionFlag(const nsSubstring& aFlag, const nsSubstring& aData,
const nsSubstring& aValue, nsIVersionComparator* aChecker,
TriState& aResult)
{
if (! (aData.Length() > aFlag.Length() + 2))
if (aData.Length() < aFlag.Length() + 2)
return PR_FALSE;
if (!StringBeginsWith(aData, aFlag))
@ -2006,6 +2026,9 @@ CheckVersionFlag(const nsSubstring& aFlag, const nsSubstring& aData,
return PR_FALSE;
}
if (testdata.Length() == 0)
return PR_FALSE;
if (aResult != eOK) {
if (!aChecker) {
aResult = eBad;
@ -2388,7 +2411,7 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
nsCOMPtr<nsIURI> chromeuri, resolveduri;
rv = io->NewURI(nsDependentCString(chrome), nsnull, nsnull,
getter_AddRefs(chromeuri));
rv |= io->NewURI(nsDependentCString(resolved), nsnull, nsnull,
rv |= io->NewURI(nsDependentCString(resolved), nsnull, manifestURI,
getter_AddRefs(resolveduri));
if (NS_FAILED(rv))
continue;

View File

@ -80,6 +80,9 @@
#define NS_URLCLASSIFIERSTREAMUPDATER_CONTRACTID \
"@mozilla.org/url-classifier/streamupdater;1"
#define NS_URLCLASSIFIERUTILS_CONTRACTID \
"@mozilla.org/url-classifier/utils;1"
#define NS_SCRIPTABLEUNESCAPEHTML_CONTRACTID "@mozilla.org/feed-unescapehtml;1"
/////////////////////////////////////////////////////////////////////////////
@ -131,6 +134,10 @@
#define NS_URLCLASSIFIERSTREAMUPDATER_CID \
{ 0xc2be6dc0, 0xef1e, 0x4abd, { 0x86, 0xa2, 0x4f, 0x86, 0x4d, 0xdc, 0x57, 0xf6} }
// {b7b2ccec-7912-4ea6-a548-b038447004bd}
#define NS_URLCLASSIFIERUTILS_CID \
{ 0xb7b2ccec, 0x7912, 0x4ea6, { 0xa5, 0x48, 0xb0, 0x38, 0x44, 0x70, 0x04, 0xbd} }
// {10f2f5f0-f103-4901-980f-ba11bd70d60d}
#define NS_SCRIPTABLEUNESCAPEHTML_CID \
{ 0x10f2f5f0, 0xf103, 0x4901, { 0x98, 0x0f, 0xba, 0x11, 0xbd, 0x70, 0xd6, 0x0d} }

View File

@ -76,6 +76,7 @@
#ifdef MOZ_URL_CLASSIFIER
#include "nsUrlClassifierDBService.h"
#include "nsUrlClassifierStreamUpdater.h"
#include "nsUrlClassifierUtils.h"
#endif
#ifdef MOZ_FEEDS
#include "nsScriptableUnescapeHTML.h"
@ -117,6 +118,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsSingleSignonPrompt)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsUrlClassifierDBService,
nsUrlClassifierDBService::GetInstance)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUrlClassifierStreamUpdater)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUrlClassifierUtils)
#endif
#ifdef MOZ_FEEDS
NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptableUnescapeHTML)
@ -242,6 +244,10 @@ static const nsModuleComponentInfo components[] =
NS_URLCLASSIFIERSTREAMUPDATER_CID,
NS_URLCLASSIFIERSTREAMUPDATER_CONTRACTID,
nsUrlClassifierStreamUpdaterConstructor },
{ "Url Classifier Utils",
NS_URLCLASSIFIERUTILS_CID,
NS_URLCLASSIFIERUTILS_CONTRACTID,
nsUrlClassifierUtilsConstructor },
#endif
#ifdef MOZ_FEEDS
{ "Unescape HTML",

View File

@ -49,6 +49,7 @@ XPIDLSRCS = \
nsICommandLine.idl \
nsICommandLineRunner.idl \
nsICommandLineHandler.idl \
nsICommandLineValidator.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,70 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla toolkit.
*
* The Initial Developer of the Original Code is
* Robert Strong <robert.bugzilla@gmail.com>
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsICommandLine;
/**
* Validates arguments on the command line of an XUL application.
*
* Each validator is registered in the category "command-line-validator".
* The entries in this category are read in alphabetical order, and each
* category value is treated as a service contractid implementing this
* interface.
*
* By convention, validator with ordinary priority should begin with "m".
*
* Example:
* Category Entry Value
* command-line-validator b-browser @mozilla.org/browser/clh;1
* command-line-validator m-edit @mozilla.org/composer/clh;1
* command-line-validator m-irc @mozilla.org/chatzilla/clh;1
*
*/
[scriptable, uuid(5ecaa593-7660-4a3a-957a-92d5770671c7)]
interface nsICommandLineValidator : nsISupports
{
/**
* Process the command-line validators in the proper order, calling
* "validate()" on each.
*
* @throws NS_ERROR_ABORT if any validator throws NS_ERROR_ABORT. All other
* errors thrown by validators will be silently ignored.
*/
void validate(in nsICommandLine aCommandLine);
};

View File

@ -39,6 +39,7 @@
#include "nsICategoryManager.h"
#include "nsICommandLineHandler.h"
#include "nsICommandLineValidator.h"
#include "nsIDOMWindow.h"
#include "nsIFile.h"
#include "nsISimpleEnumerator.h"
@ -85,12 +86,17 @@ public:
protected:
~nsCommandLine() { }
typedef nsresult (*EnumerateCallback)(nsICommandLineHandler* aHandler,
typedef nsresult (*EnumerateHandlersCallback)(nsICommandLineHandler* aHandler,
nsICommandLine* aThis,
void *aClosure);
typedef nsresult (*EnumerateValidatorsCallback)(nsICommandLineValidator* aValidator,
nsICommandLine* aThis,
void *aClosure);
void appendArg(const char* arg);
nsresult EnumerateHandlers(EnumerateCallback aCallback, void *aClosure);
void resolveShortcutURL(nsILocalFile* aFile, nsACString& outURL);
nsresult EnumerateHandlers(EnumerateHandlersCallback aCallback, void *aClosure);
nsresult EnumerateValidators(EnumerateValidatorsCallback aCallback, void *aClosure);
nsStringArray mArgs;
PRUint32 mState;
@ -439,18 +445,27 @@ nsCommandLine::ResolveURI(const nsAString& aArgument, nsIURI* *aResult)
nsCOMPtr<nsIIOService> io = do_GetIOService();
NS_ENSURE_TRUE(io, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIURI> workingDirURI;
if (mWorkingDir) {
io->NewFileURI(mWorkingDir, getter_AddRefs(workingDirURI));
}
nsCOMPtr<nsILocalFile> lf (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
rv = lf->InitWithPath(aArgument);
if (NS_SUCCEEDED(rv)) {
lf->Normalize();
nsCAutoString url;
// Try to resolve the url for .url files.
resolveShortcutURL(lf, url);
if (!url.IsEmpty()) {
return io->NewURI(url,
nsnull,
workingDirURI,
aResult);
}
return io->NewFileURI(lf, aResult);
}
nsCOMPtr<nsIURI> workingDirURI;
if (mWorkingDir) {
io->NewFileURI(mWorkingDir, getter_AddRefs(workingDirURI));
}
return io->NewURI(NS_ConvertUTF16toUTF8(aArgument),
nsnull,
workingDirURI,
@ -470,6 +485,22 @@ nsCommandLine::appendArg(const char* arg)
mArgs.AppendString(warg);
}
void
nsCommandLine::resolveShortcutURL(nsILocalFile* aFile, nsACString& outURL)
{
nsCOMPtr<nsIFileProtocolHandler> fph;
nsresult rv = NS_GetFileProtocolHandler(getter_AddRefs(fph));
if (NS_FAILED(rv))
return;
nsCOMPtr<nsIURI> uri;
rv = fph->ReadURLFile(aFile, getter_AddRefs(uri));
if (NS_FAILED(rv))
return;
uri->GetSpec(outURL);
}
NS_IMETHODIMP
nsCommandLine::Init(PRInt32 argc, char** argv, nsIFile* aWorkingDir,
PRUint32 aState)
@ -536,7 +567,7 @@ nsCommandLine::Init(PRInt32 argc, char** argv, nsIFile* aWorkingDir,
}
nsresult
nsCommandLine::EnumerateHandlers(EnumerateCallback aCallback, void *aClosure)
nsCommandLine::EnumerateHandlers(EnumerateHandlersCallback aCallback, void *aClosure)
{
nsresult rv;
@ -578,6 +609,55 @@ nsCommandLine::EnumerateHandlers(EnumerateCallback aCallback, void *aClosure)
return rv;
}
nsresult
nsCommandLine::EnumerateValidators(EnumerateValidatorsCallback aCallback, void *aClosure)
{
nsresult rv;
nsCOMPtr<nsICategoryManager> catman
(do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
NS_ENSURE_TRUE(catman, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsISimpleEnumerator> entenum;
rv = catman->EnumerateCategory("command-line-validator",
getter_AddRefs(entenum));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIUTF8StringEnumerator> strenum (do_QueryInterface(entenum));
NS_ENSURE_TRUE(strenum, NS_ERROR_UNEXPECTED);
nsCAutoString entry;
PRBool hasMore;
while (NS_SUCCEEDED(strenum->HasMore(&hasMore)) && hasMore) {
strenum->GetNext(entry);
nsXPIDLCString contractID;
rv = catman->GetCategoryEntry("command-line-validator",
entry.get(),
getter_Copies(contractID));
if (!contractID)
continue;
nsCOMPtr<nsICommandLineValidator> clv(do_GetService(contractID.get()));
if (!clv)
continue;
rv = (aCallback)(clv, this, aClosure);
if (rv == NS_ERROR_ABORT)
break;
rv = NS_OK;
}
return rv;
}
static nsresult
EnumValidate(nsICommandLineValidator* aValidator, nsICommandLine* aThis, void*)
{
return aValidator->Validate(aThis);
}
static nsresult
EnumRun(nsICommandLineHandler* aHandler, nsICommandLine* aThis, void*)
{
@ -589,6 +669,10 @@ nsCommandLine::Run()
{
nsresult rv;
rv = EnumerateValidators(EnumValidate, nsnull);
if (rv == NS_ERROR_ABORT)
return rv;
rv = EnumerateHandlers(EnumRun, nsnull);
if (rv == NS_ERROR_ABORT)
return rv;

View File

@ -74,6 +74,12 @@
#include <shlobj.h>
#endif
#if defined(_MSC_VER) && _MSC_VER < 1300
#define BYTES_TO_KBYTES(bytes) ((PRFloat64)((PRInt64)(bytes >> 8) / 4 + .5))
#else
#define BYTES_TO_KBYTES(bytes) ((PRFloat64)bytes / 1024.0 + .5)
#endif
/* Outstanding issues/todo:
* 1. Implement pause/resume.
*/
@ -480,8 +486,8 @@ nsDownloadManager::AssertProgressInfoFor(const PRUnichar* aPath)
internalDownload->GetTransferInformation();
// convert from bytes to kbytes for progress display
PRInt64 current = (PRFloat64)transferInfo.mCurrBytes / 1024 + .5;
PRInt64 max = (PRFloat64)transferInfo.mMaxBytes / 1024 + .5;
PRInt64 current = BYTES_TO_KBYTES(transferInfo.mCurrBytes);
PRInt64 max = BYTES_TO_KBYTES(transferInfo.mMaxBytes);
nsAutoString currBytes; currBytes.AppendInt(current);
nsAutoString maxBytes; maxBytes.AppendInt(max);
@ -2330,14 +2336,14 @@ nsDownload::GetPercentComplete(PRInt32* aPercentComplete)
NS_IMETHODIMP
nsDownload::GetAmountTransferred(PRUint64* aAmountTransferred)
{
*aAmountTransferred = ((PRFloat64)mCurrBytes / 1024.0 + .5);
*aAmountTransferred = BYTES_TO_KBYTES(mCurrBytes);
return NS_OK;
}
NS_IMETHODIMP
nsDownload::GetSize(PRUint64* aSize)
{
*aSize = ((PRFloat64)mMaxBytes / 1024 + .5);
*aSize = BYTES_TO_KBYTES(mMaxBytes);
return NS_OK;
}

View File

@ -333,7 +333,7 @@ Feed.prototype = {
categories: ["categories", "dc:subject"],
rights: ["atom03:rights","atom:rights"],
cloud: ["cloud"],
image: ["image", "rss1:image"],
image: ["image", "rss1:image", "atom:logo"],
textInput: ["textInput", "rss1:textinput"],
skipDays: ["skipDays"],
skipHours: ["skipHours"],
@ -355,6 +355,11 @@ Feed.prototype = {
if (bagHasKey(this.fields, "links"))
this._atomLinksToURI();
// Resolve relative image links
if (this.image && bagHasKey(this.image, "url")) {
this._resolveImageLink();
}
this._resetBagMembersToRawText([this.searchLists.subtitle,
this.searchLists.title]);
},
@ -363,22 +368,36 @@ Feed.prototype = {
var links = this.fields.getPropertyAsInterface("links", Ci.nsIArray);
var alternates = findAtomLinks("alternate", links);
if (alternates.length > 0) {
try {
var href = alternates[0].getPropertyAsAString("href");
var base;
if (bagHasKey(alternates[0], "xml:base"))
base = strToURI(alternates[0].getPropertyAsAString("xml:base"),
this.baseURI);
else
base = this.baseURI;
this.link = strToURI(alternates[0].getPropertyAsAString("href"), base);
}
catch(e) {
LOG(e);
}
var href = alternates[0].getPropertyAsAString("href");
var base;
if (bagHasKey(alternates[0], "xml:base"))
base = alternates[0].getPropertyAsAString("xml:base");
this.link = this._resolveURI(href, base);
}
},
_resolveImageLink: function Feed_resolveImageLink() {
var base;
if (bagHasKey(this.image, "xml:base"))
base = this.image.getPropertyAsAString("xml:base");
var url = this._resolveURI(this.image.getPropertyAsAString("url"), base);
if (url)
this.image.setPropertyAsAString("url", url.spec);
},
_resolveURI: function Feed_resolveURI(linkSpec, baseSpec) {
var uri = null;
try {
var base = baseSpec ? strToURI(baseSpec, this.baseURI) : this.baseURI;
uri = strToURI(linkSpec, base);
}
catch(e) {
LOG(e);
}
return uri;
},
// reset the bag to raw contents, not text constructs
_resetBagMembersToRawText: function Feed_resetBagMembers(fieldLists) {
for (var i=0; i<fieldLists.length; i++) {
@ -450,7 +469,7 @@ Entry.prototype = {
var isPermaLink = true;
if (bagHasKey(guid, "isPermaLink"))
isPermaLink = new Boolean(guid.getProperty("isPermaLink"));
isPermaLink = guid.getProperty("isPermaLink").toLowerCase() != "false";
if (guid && isPermaLink)
this.link = strToURI(guid.getProperty("guid"));
@ -477,6 +496,7 @@ Entry.prototype = {
}
Entry.prototype._atomLinksToURI = Feed.prototype._atomLinksToURI;
Entry.prototype._resolveURI = Feed.prototype._resolveURI;
Entry.prototype._resetBagMembersToRawText =
Feed.prototype._resetBagMembersToRawText;
@ -633,7 +653,12 @@ function atomGenerator(s, generator) {
generator.QueryInterface(Ci.nsIFeedGenerator);
generator.agent = trimString(s);
return generator;
}
}
// post-process atom:logo to create an RSS2-like structure
function atomLogo(s, logo) {
logo.setPropertyAsAString("url", trimString(s));
}
// post-process an RSS category, map it to the Atom fields.
function rssCatTerm(s, cat) {
@ -1060,6 +1085,7 @@ function FeedProcessor() {
"atom:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
null, true),
"atom:link": new ElementInfo("links", null, null, true),
"atom:logo": new ElementInfo("atom:logo", null, atomLogo, false),
"atom:entry": new ElementInfo("entries", Cc[ENTRY_CONTRACTID],
null, true)
},

View File

@ -2,10 +2,10 @@
<!--
Description: atom logo works
Expect: feed.fields.getProperty('atom:logo') == 'http://example.org/logo.jpg'
Expect: feed.image.getProperty('url') == 'http://example.org/logo.jpg'
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<title>test title</title>
<logo>http://example.org/logo.jpg</logo>
<logo xml:base="http://example.org/">logo.jpg</logo>
</feed>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: item guid should not map to link when isPermaLink=false
Expect: var link = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link; link == null;
-->
<rss version="2.0" >
<channel>
<item>
<enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" />
<author>jbb@dallas.example.com (Joe Bob Briggs)</author>
<title>test</title>
<guid isPermaLink="false">http://www.example.org/</guid>
<category domain="foo">bar</category>
<description>I'm headed for France. I wasn't gonna go this year, but then last week &lt;a href="http://www.imdb.com/title/tt0086525/"&gt;Valley Girl&lt;/a&gt; came out and I said to myself, Joe Bob, you gotta get out of the country for a while.</description></item>
</channel>
</rss>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: item guid should not map to link when isPermaLink=FaLsE
Expect: var link = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link; link == null;
-->
<rss version="2.0" >
<channel>
<item>
<enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" />
<author>jbb@dallas.example.com (Joe Bob Briggs)</author>
<title>test</title>
<guid isPermaLink="FaLsE">http://www.example.org/</guid>
<category domain="foo">bar</category>
<description>I'm headed for France. I wasn't gonna go this year, but then last week &lt;a href="http://www.imdb.com/title/tt0086525/"&gt;Valley Girl&lt;/a&gt; came out and I said to myself, Joe Bob, you gotta get out of the country for a while.</description></item>
</channel>
</rss>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: item guid should map to link when isPermaLink=TrUe
Expect: var link = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link; link.spec == "http://www.example.org/";
-->
<rss version="2.0" >
<channel>
<item>
<enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" />
<author>jbb@dallas.example.com (Joe Bob Briggs)</author>
<title>test</title>
<guid isPermaLink="TrUe">http://www.example.org/</guid>
<category domain="foo">bar</category>
<description>I'm headed for France. I wasn't gonna go this year, but then last week &lt;a href="http://www.imdb.com/title/tt0086525/"&gt;Valley Girl&lt;/a&gt; came out and I said to myself, Joe Bob, you gotta get out of the country for a while.</description></item>
</channel>
</rss>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Description: item guid should map to link when isPermaLink=meatcake or other unknown values
Expect: var link = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link; link.spec == "http://www.example.org/";
-->
<rss version="2.0" >
<channel>
<item>
<enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" />
<author>jbb@dallas.example.com (Joe Bob Briggs)</author>
<title>test</title>
<guid isPermaLink="meatcake">http://www.example.org/</guid>
<category domain="foo">bar</category>
<description>I'm headed for France. I wasn't gonna go this year, but then last week &lt;a href="http://www.imdb.com/title/tt0086525/"&gt;Valley Girl&lt;/a&gt; came out and I said to myself, Joe Bob, you gotta get out of the country for a while.</description></item>
</channel>
</rss>

View File

@ -137,6 +137,12 @@ function init() {
helpGlossaryPanel = document.getElementById("help-glossary-panel");
helpBrowser = document.getElementById("help-content");
// Turn off unnecessary features for security
helpBrowser.docShell.allowJavascript = false;
helpBrowser.docShell.allowPlugins = false;
helpBrowser.docShell.allowSubframes = false;
helpBrowser.docShell.allowMetaRedirects = false;
strBundle = document.getElementById("bundle_help");
emptySearchText = strBundle.getString("emptySearchText");

View File

@ -1524,7 +1524,7 @@ nsGlobalHistory::GetSource(nsIRDFResource* aProperty,
// XXX We could be more forgiving here, and check for literal
// values as well.
nsCOMPtr<nsIRDFResource> target = do_QueryInterface(aTarget);
if (IsURLInHistory(target))
if (target && IsURLInHistory(target))
return CallQueryInterface(aTarget, aSource);
}

View File

@ -47,6 +47,9 @@ const nsIModule = Components.interfaces.nsIModule;
const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
const nsISupportsString = Components.interfaces.nsISupportsString;
const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
const nsIProperties = Components.interfaces.nsIProperties;
const nsIFile = Components.interfaces.nsIFile;
const nsISimpleEnumerator = Components.interfaces.nsISimpleEnumerator;
/**
* This file provides a generic default command-line handler.
@ -59,6 +62,12 @@ const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
* It doesn't do anything if the pref "toolkit.defaultChromeURI" is unset.
*/
function getDirectoryService()
{
return Components.classes["@mozilla.org/file/directory_service;1"]
.getService(nsIProperties);
}
var nsDefaultCLH = {
/* nsISupports */
@ -74,8 +83,41 @@ var nsDefaultCLH = {
/* nsICommandLineHandler */
handle : function clh_handle(cmdLine) {
var printDir;
while (printDir = cmdLine.handleFlagWithParam("print-xpcom-dir", false)) {
var out = "print-xpcom-dir(\"" + printDir + "\"): ";
try {
out += getDirectoryService().get(printDir, nsIFile).path;
}
catch (e) {
out += "<Not Provided>";
}
dump(out + "\n");
Components.utils.reportError(out);
}
var printDirList;
while (printDirList = cmdLine.handleFlagWithParam("print-xpcom-dirlist",
false)) {
out = "print-xpcom-dirlist(\"" + printDirList + "\"): ";
try {
var list = getDirectoryService().get(printDirList,
nsISimpleEnumerator);
while (list.hasMoreElements())
out += list.getNext().QueryInterface(nsIFile).path + ";";
}
catch (e) {
out += "<Not Provided>";
}
dump(out + "\n");
Components.utils.reportError(out);
}
if (cmdLine.preventDefault)
return;
return;
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(nsIPrefBranch);
@ -86,9 +128,9 @@ var nsDefaultCLH = {
.getService(Components.interfaces.nsIWindowMediator);
var win = windowMediator.getMostRecentWindow(singletonWindowType);
if (win) {
win.focus();
cmdLine.preventDefault = true;
return;
win.focus();
cmdLine.preventDefault = true;
return;
}
}
catch (e) { }

View File

@ -373,6 +373,11 @@ nsPasswordManager::AddUser(const nsACString& aHost,
if (aUser.IsEmpty() && aPassword.IsEmpty())
return NS_OK;
// Reject values that would cause problems when parsing the storage file
nsresult rv = CheckLoginValues(aHost,
EmptyString(), EmptyString(), EmptyCString());
NS_ENSURE_SUCCESS(rv, rv);
// Check for an existing entry for this host + user
if (!aHost.IsEmpty()) {
SignonHashEntry *hashEnt;
@ -440,6 +445,11 @@ nsPasswordManager::RemoveUser(const nsACString& aHost, const nsAString& aUser)
NS_IMETHODIMP
nsPasswordManager::AddReject(const nsACString& aHost)
{
// Reject values that would cause problems when parsing the storage file
nsresult rv = CheckLoginValues(aHost,
EmptyString(), EmptyString(), EmptyCString());
NS_ENSURE_SUCCESS(rv, rv);
mRejectTable.Put(aHost, 1);
WritePasswords(mSignonFile);
return NS_OK;
@ -611,6 +621,11 @@ nsPasswordManager::AddUserFull(const nsACString& aKey,
if (aUser.IsEmpty() && aPassword.IsEmpty())
return NS_OK;
// Reject values that would cause problems when parsing the storage file
nsresult rv = CheckLoginValues(aKey, aUserFieldName,
aPassFieldName, EmptyCString());
NS_ENSURE_SUCCESS(rv, rv);
// Check for an existing entry for this host + user
if (!aKey.IsEmpty()) {
SignonHashEntry *hashEnt;
@ -795,7 +810,7 @@ nsPasswordManager::Observe(nsISupports* aSubject,
obsService->AddObserver(this, "profile-after-change", PR_TRUE);
} else if (!strcmp(aTopic, "profile-after-change"))
nsCOMPtr<nsIPasswordManager> pm = do_GetService(NS_PASSWORDMANAGER_CONTRACTID);
LoadPasswords();
return NS_OK;
}
@ -1023,10 +1038,14 @@ nsPasswordManager::Notify(nsIContent* aFormNode,
if (NS_SUCCEEDED(GetActionRealm(formElement, formActionOrigin)) &&
!entry->actionOrigin.Equals(formActionOrigin)) {
// update the action URL
entry->actionOrigin.Assign(formActionOrigin);
writePasswords = PR_TRUE;
// Reject values that would cause problems when parsing the storage file
if (NS_SUCCEEDED(CheckLoginValues(EmptyCString(), EmptyString(),
EmptyString(), formActionOrigin))) {
// update the action URL
entry->actionOrigin.Assign(formActionOrigin);
writePasswords = PR_TRUE;
}
}
if (writePasswords)
@ -1101,9 +1120,23 @@ nsPasswordManager::Notify(nsIContent* aFormNode,
return NS_OK;
}
// Reject values that would cause problems when parsing the storage file
// We do this after prompting, lest any code somehow change the values
// during the prompting.
nsresult rv = CheckLoginValues(realm,
entry->userField, entry->passField,
entry->actionOrigin);
NS_ENSURE_SUCCESS(rv, NS_OK);
AddSignonData(realm, entry);
WritePasswords(mSignonFile);
} else if (selection == 2) {
// Reject values that would cause problems when parsing the storage file
// We do this after prompting, lest any code run from prompt context.
nsresult rv = CheckLoginValues(realm, EmptyString(),
EmptyString(), EmptyCString());
NS_ENSURE_SUCCESS(rv, NS_OK);
AddReject(realm);
}
}
@ -1914,6 +1947,7 @@ nsPasswordManager::FillDocument(nsIDOMDocument* aDomDoc)
inputField->GetValue(oldUserValue);
userField = inputField;
foundNode = inputField;
// Only the case differs, so CheckLoginValues() unneeded.
e->userField.Assign(name);
break;
}
@ -1973,8 +2007,15 @@ nsPasswordManager::FillDocument(nsIDOMDocument* aDomDoc)
temp->GetValue(oldPassValue);
passField = temp;
if ((e->passField).IsEmpty())
passField->GetName(e->passField);
if ((e->passField).IsEmpty()) {
nsAutoString passName;
passField->GetName(passName);
// Reject values that would cause problems when parsing the storage file
if (NS_SUCCEEDED(CheckLoginValues(EmptyCString(), EmptyString(),
passName, EmptyCString())))
e->passField.Assign(passName);
}
} else {
continue;
}
@ -2098,8 +2139,9 @@ nsPasswordManager::FillPassword(nsIDOMEvent* aEvent)
nsCOMPtr<nsIForm> form = do_QueryInterface(formEl);
nsCAutoString formActionOrigin;
GetActionRealm(form, formActionOrigin);
if (NS_FAILED(GetActionRealm(form, formActionOrigin)) ||
!foundEntry->actionOrigin.Equals(formActionOrigin))
if (NS_FAILED(GetActionRealm(form, formActionOrigin)))
return NS_OK;
if (!foundEntry->actionOrigin.IsEmpty() && !foundEntry->actionOrigin.Equals(formActionOrigin))
return NS_OK;
nsCOMPtr<nsISupports> foundNode;
@ -2197,3 +2239,68 @@ nsPasswordManager::GetActionRealm(nsIForm* aForm, nsCString& aURL)
aURL.Assign(formActionOrigin);
return NS_OK;
}
/* static */ PRBool
nsPasswordManager::BadCharacterPresent(const nsAString &aString)
{
if (aString.FindChar('\r') >= 0)
return PR_TRUE;
if (aString.FindChar('\n') >= 0)
return PR_TRUE;
if (aString.FindChar('\0') >= 0)
return PR_TRUE;
return PR_FALSE;
}
/* static */ nsresult
nsPasswordManager::CheckLoginValues(const nsACString &aHost,
const nsAString &aUserField,
const nsAString &aPassField,
const nsACString &aActionOrigin)
{
// aHost
if (BadCharacterPresent(NS_ConvertUTF8toUTF16(aHost))) {
NS_WARNING("Login rejected, bad character in aHost");
return NS_ERROR_FAILURE;
}
// The aHost arg is used for both login entry hostnames and reject entry
// hostnames ("never for this site"). A value of "." is not allowed for
// reject entries. It's technically ok for login entries, but to keep the
// code simple we'll disallow it anyway.
if (aHost.EqualsLiteral(".")) {
NS_WARNING("Login rejected, aHost can not be just a period");
return NS_ERROR_FAILURE;
}
// aUserField
if (BadCharacterPresent(aUserField)) {
NS_WARNING("Login rejected, bad character in aUserField");
return NS_ERROR_FAILURE;
}
if (aUserField.EqualsLiteral(".")) {
NS_WARNING("Login rejected, aUserField can not be just a period");
return NS_ERROR_FAILURE;
}
// aPassField
if (BadCharacterPresent(aPassField)) {
NS_WARNING("Login rejected, bad character in aPassField");
return NS_ERROR_FAILURE;
}
// aActionOrigin
if (BadCharacterPresent(NS_ConvertUTF8toUTF16(aActionOrigin))) {
NS_WARNING("Login rejected, bad character in aActionOrigin");
return NS_ERROR_FAILURE;
}
if (aActionOrigin.EqualsLiteral(".")) {
NS_WARNING("Login rejected, aActionOrigin can not be just a period");
return NS_ERROR_FAILURE;
}
return NS_OK;
}

View File

@ -153,6 +153,12 @@ protected:
static nsresult GetActionRealm(nsIForm* aForm, nsCString& aURL);
static PRBool BadCharacterPresent(const nsAString &aString);
static nsresult CheckLoginValues(const nsACString &aHost,
const nsAString &aUserField,
const nsAString &aPassField,
const nsACString &aActionOrigin);
static PLDHashOperator PR_CALLBACK FindEntryEnumerator(const nsACString& aKey,
SignonHashEntry* aEntry,
void* aUserData);

View File

@ -71,7 +71,7 @@ CPPSRCS += nsGTKRemoteService.cpp
endif
ifeq (photon,$(MOZ_WIDGET_TOOLKIT))
CPPSRCS += nsPhMozRemoteHelper.cpp
CPPSRCS += nsPhRemoteService.cpp
endif
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,193 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Christopher Blizzard.
* Portions created by Christopher Blizzard are Copyright (C)
* Christopher Blizzard. All Rights Reserved.
*
* Contributor(s):
* Adrian Mardare <amardare@qnx.com>
* Max Feil <mfeil@qnx.com>
*/
#include <stdlib.h>
#include <nsIWidget.h>
#include <nsCOMPtr.h>
#include "nsIGenericFactory.h"
#include "nsPhRemoteService.h"
#include "nsIServiceManager.h"
#include "nsCRT.h"
#ifdef MOZ_XUL_APP
#include "nsICommandLineRunner.h"
#include "nsXULAppAPI.h"
#else
#include "nsISuiteRemoteService.h"
#endif
#include <Pt.h>
NS_IMPL_QUERY_INTERFACE2(nsPhRemoteService,
nsIRemoteService,
nsIObserver)
NS_IMETHODIMP_(nsrefcnt)
nsPhRemoteService::AddRef()
{
return 1;
}
NS_IMETHODIMP_(nsrefcnt)
nsPhRemoteService::Release()
{
return 1;
}
NS_IMETHODIMP
nsPhRemoteService::Startup(const char* aAppName, const char* aProfileName)
{
NS_ASSERTION(aAppName, "Don't pass a null appname!");
if (mIsInitialized)
return NS_ERROR_ALREADY_INITIALIZED;
mIsInitialized = PR_TRUE;
mAppName = aAppName;
ToLowerCase(mAppName);
HandleCommandsFor(nsnull, nsnull);
return NS_OK;
}
NS_IMETHODIMP
nsPhRemoteService::RegisterWindow(nsIDOMWindow* aWindow)
{
return NS_OK;
}
NS_IMETHODIMP
nsPhRemoteService::Shutdown()
{
if (!mIsInitialized)
return NS_ERROR_NOT_INITIALIZED;
mIsInitialized = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsPhRemoteService::Observe(nsISupports* aSubject,
const char *aTopic,
const PRUnichar *aData)
{
// This can be xpcom-shutdown or quit-application, but it's the same either
// way.
Shutdown();
return NS_OK;
}
#define MOZ_REMOTE_MSG_TYPE 100
static void const * RemoteMsgHandler( PtConnectionServer_t *connection, void *user_data,
unsigned long type, void const *msg, unsigned len, unsigned *reply_len )
{
nsresult rv;
if( type != MOZ_REMOTE_MSG_TYPE ) return NULL;
/* we are given strings and we reply with strings */
char *response = NULL;
// parse the command
nsCOMPtr<nsICommandLineRunner> cmdline
(do_CreateInstance("@mozilla.org/toolkit/command-line;1", &rv));
if (!NS_FAILED(rv)) {
// 1) Make sure that it looks remotely valid with parens
// 2) Treat ping() immediately and specially
nsCAutoString command((char *)msg);
PRInt32 p1, p2;
p1 = command.FindChar('(');
p2 = command.FindChar(')');
if (p1 != kNotFound && p2 != kNotFound && p1 != 0 && p2 >= p1) {
command.Truncate(p1);
command.Trim(" ", PR_TRUE, PR_TRUE);
ToLowerCase(command);
//printf("Processing xremote command: %s\n", command.get());
if (!command.EqualsLiteral("ping")) {
char* argv[3] = {"dummyappname", "-remote", (char *)msg};
rv = cmdline->Init(3, argv, nsnull, nsICommandLine::STATE_REMOTE_EXPLICIT);
if (!NS_FAILED(rv)) {
rv = cmdline->Run();
if (NS_ERROR_ABORT == rv)
response = "500 command not parseable";
if (NS_FAILED(rv))
response = "509 internal error";
} else
response = "509 internal error";
}
} else
response = "500 command not parseable";
} else
response = "509 internal error";
PtConnectionReply( connection, response ? strlen(response) : 0, response );
return ( void * ) 1; /* return any non NULL value to indicate we handled the message */
}
static void client_connect( PtConnector_t *cntr, PtConnectionServer_t *csrvr, void *data )
{
static PtConnectionMsgHandler_t handlers[] = { { 0, RemoteMsgHandler } };
PtConnectionAddMsgHandlers( csrvr, handlers, sizeof(handlers)/sizeof(handlers[0]) );
}
void
nsPhRemoteService::HandleCommandsFor( nsIWidget *aWidget, nsIWeakReference* aWindow )
{
static PRBool ConnectorCreated = PR_FALSE;
///* ATENTIE */ printf( "aProgram=%s aProfile=%s aWidget=%p\n", aProgram?aProgram:"NULL", aProfile?aProfile:"NULL", aWidget );
if( !ConnectorCreated ) {
char RemoteServerName[128];
sprintf( RemoteServerName, "%s_RemoteServer", (char *) mAppName.get() );
/* create a connector for the remote control */
PtConnectorCreate( RemoteServerName, client_connect, NULL );
ConnectorCreated = PR_TRUE;
}
return;
}
// {C0773E90-5799-4eff-AD03-3EBCD85624AC}
#define NS_REMOTESERVICE_CID \
{ 0xc0773e90, 0x5799, 0x4eff, { 0xad, 0x3, 0x3e, 0xbc, 0xd8, 0x56, 0x24, 0xac } }
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPhRemoteService)
static const nsModuleComponentInfo components[] =
{
{ "Remote Service",
NS_REMOTESERVICE_CID,
"@mozilla.org/toolkit/remote-service;1",
nsPhRemoteServiceConstructor
}
};
NS_IMPL_NSGETMODULE(RemoteServiceModule, components)

View File

@ -0,0 +1,69 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Christopher Blizzard. Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard. All Rights Reserved.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Adrian Mardare <amardare@qnx.com>
* Max Feil <mfeil@qnx.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __nsPhRemoteService_h__
#define __nsPhRemoteService_h__
#include "nsIRemoteService.h"
#include "nsIObserver.h"
#include "nsString.h"
class nsIWeakReference;
class nsPhRemoteService : public nsIRemoteService,
public nsIObserver
{
public:
// We will be a static singleton, so don't use the ordinary methods.
NS_DECL_ISUPPORTS
NS_DECL_NSIREMOTESERVICE
NS_DECL_NSIOBSERVER
nsPhRemoteService() { mIsInitialized = PR_FALSE; }
private:
~nsPhRemoteService() { }
void HandleCommandsFor(nsIWidget *aWidget,
nsIWeakReference* aWindow);
PRBool mIsInitialized;
nsCString mAppName;
};
#endif /* __nsPhRemoteService_h__ */

View File

@ -468,36 +468,34 @@ nsFormFillController::OnSearchComplete()
}
NS_IMETHODIMP
nsFormFillController::OnTextEntered(PRBool *_retval)
nsFormFillController::OnTextEntered(PRBool* aPrevent)
{
NS_ENSURE_ARG(aPrevent);
NS_ENSURE_TRUE(mFocusedInput, NS_OK);
// Fire off a DOMAutoComplete event
nsCOMPtr<nsIDOMDocument> domDoc;
mFocusedInput->GetOwnerDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDOMDocumentEvent> doc = do_QueryInterface(domDoc);
NS_ENSURE_STATE(doc);
nsCOMPtr<nsIDOMEvent> event;
doc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
if (!event) {
NS_ERROR("Could not create DOM Event");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
NS_ENSURE_STATE(privateEvent);
event->InitEvent(NS_LITERAL_STRING("DOMAutoComplete"), PR_TRUE, PR_TRUE);
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
if (privateEvent) {
// XXXjst: We mark this event as a trusted event, it's up to the
// callers of this to ensure that it's only called from trusted
// code.
privateEvent->SetTrusted(PR_TRUE);
}
// XXXjst: We mark this event as a trusted event, it's up to the
// callers of this to ensure that it's only called from trusted
// code.
privateEvent->SetTrusted(PR_TRUE);
nsCOMPtr<nsIDOMEventTarget> targ = do_QueryInterface(mFocusedInput);
PRBool defaultActionEnabled;
targ->DispatchEvent(event, &defaultActionEnabled);
*aPrevent = !defaultActionEnabled;
return NS_OK;
}
@ -994,10 +992,6 @@ nsFormFillController::AddWindowListeners(nsIDOMWindow *aWindow)
target->AddEventListener(NS_LITERAL_STRING("contextmenu"),
NS_STATIC_CAST(nsIDOMContextMenuListener *, this),
PR_TRUE);
target->AddEventListener(NS_LITERAL_STRING("keypress"),
NS_STATIC_CAST(nsIDOMKeyListener *, this),
PR_TRUE);
}
void
@ -1053,10 +1047,32 @@ nsFormFillController::RemoveWindowListeners(nsIDOMWindow *aWindow)
target->RemoveEventListener(NS_LITERAL_STRING("contextmenu"),
NS_STATIC_CAST(nsIDOMContextMenuListener *, this),
PR_TRUE);
}
target->RemoveEventListener(NS_LITERAL_STRING("keypress"),
NS_STATIC_CAST(nsIDOMKeyListener *, this),
PR_TRUE);
void
nsFormFillController::AddKeyListener(nsIDOMHTMLInputElement *aInput)
{
if (!aInput)
return;
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(aInput);
target->AddEventListener(NS_LITERAL_STRING("keypress"),
NS_STATIC_CAST(nsIDOMKeyListener *, this),
PR_TRUE);
}
void
nsFormFillController::RemoveKeyListener()
{
if (!mFocusedInput)
return;
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mFocusedInput);
target->RemoveEventListener(NS_LITERAL_STRING("keypress"),
NS_STATIC_CAST(nsIDOMKeyListener *, this),
PR_TRUE);
}
void
@ -1074,6 +1090,7 @@ nsFormFillController::StartControllingInput(nsIDOMHTMLInputElement *aInput)
// Cache the popup for the focused docShell
mPopups->GetElementAt(index, getter_AddRefs(mFocusedPopup));
AddKeyListener(aInput);
mFocusedInput = aInput;
// Now we are the autocomplete controller's bitch
@ -1083,6 +1100,8 @@ nsFormFillController::StartControllingInput(nsIDOMHTMLInputElement *aInput)
void
nsFormFillController::StopControllingInput()
{
RemoveKeyListener();
// Reset the controller's input, but not if it has been switched
// to another input already, which might happen if the user switches
// focus by clicking another autocomplete textbox

View File

@ -127,6 +127,9 @@ protected:
void AddWindowListeners(nsIDOMWindow *aWindow);
void RemoveWindowListeners(nsIDOMWindow *aWindow);
void AddKeyListener(nsIDOMHTMLInputElement *aInput);
void RemoveKeyListener();
void StartControllingInput(nsIDOMHTMLInputElement *aInput);
void StopControllingInput();

View File

@ -73,6 +73,10 @@ static void SwapBytes(PRUnichar* aDest, const PRUnichar* aSrc, PRUint32 aLen)
#define PREF_FORMFILL_BRANCH "browser.formfill."
#define PREF_FORMFILL_ENABLE "enable"
// upper bounds on saved form data, more isn't useful.
#define FORMFILL_NAME_MAX_LEN 1000
#define FORMFILL_VALUE_MAX_LEN 4000
static const char *kFormHistoryFileName = "formhistory.dat";
NS_INTERFACE_MAP_BEGIN(nsFormHistory)
@ -626,7 +630,11 @@ nsFormHistory::AppendRow(const nsAString &aName, const nsAString &aValue, nsIMdb
if (!mTable)
return NS_ERROR_NOT_INITIALIZED;
PRBool exists;
if (aName.Length() > FORMFILL_NAME_MAX_LEN ||
aValue.Length() > FORMFILL_VALUE_MAX_LEN)
return NS_ERROR_INVALID_ARG;
PRBool exists = PR_TRUE;
EntryExists(aName, aValue, &exists);
if (exists)
return NS_OK;

View File

@ -228,7 +228,7 @@ nsFormHistory::AddEntry(const nsAString &aName, const nsAString &aValue)
mozStorageTransaction transaction(mDBConn, PR_FALSE);
PRBool exists;
PRBool exists = PR_TRUE;
EntryExists(aName, aValue, &exists);
if (!exists) {
mozStorageStatementScoper scope(mDBInsertNameValue);

View File

@ -74,18 +74,15 @@ PROT_EnchashDecrypter.SALT_LENGTH = PROT_EnchashDecrypter.DATABASE_SALT.length;
PROT_EnchashDecrypter.MAX_DOTS = 5;
PROT_EnchashDecrypter.REs = {};
PROT_EnchashDecrypter.REs.FIND_DODGY_CHARS =
new RegExp("[\x01-\x1f\x7f-\xff]+");
PROT_EnchashDecrypter.REs.FIND_DODGY_CHARS_GLOBAL =
PROT_EnchashDecrypter.REs.FIND_DODGY_CHARS_GLOBAL =
new RegExp("[\x01-\x1f\x7f-\xff]+", "g");
PROT_EnchashDecrypter.REs.FIND_END_DOTS = new RegExp("^\\.+|\\.+$");
PROT_EnchashDecrypter.REs.FIND_END_DOTS_GLOBAL =
PROT_EnchashDecrypter.REs.FIND_END_DOTS_GLOBAL =
new RegExp("^\\.+|\\.+$", "g");
PROT_EnchashDecrypter.REs.FIND_MULTIPLE_DOTS = new RegExp("\\.{2,}");
PROT_EnchashDecrypter.REs.FIND_MULTIPLE_DOTS_GLOBAL =
PROT_EnchashDecrypter.REs.FIND_MULTIPLE_DOTS_GLOBAL =
new RegExp("\\.{2,}", "g");
PROT_EnchashDecrypter.REs.FIND_TRAILING_DOTS = new RegExp("\\.+$");
PROT_EnchashDecrypter.REs.POSSIBLE_IP =
PROT_EnchashDecrypter.REs.FIND_TRAILING_SPACE =
new RegExp("^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}) ");
PROT_EnchashDecrypter.REs.POSSIBLE_IP =
new RegExp("^((?:0x[0-9a-f]+|[0-9\\.])+)$", "i");
PROT_EnchashDecrypter.REs.FIND_BAD_OCTAL = new RegExp("(^|\\.)0\\d*[89]");
PROT_EnchashDecrypter.REs.IS_OCTAL = new RegExp("^0[0-7]*$");
@ -171,12 +168,17 @@ PROT_EnchashDecrypter.prototype.parseRegExps = function(data) {
* type -url.
*
* @param url String to canonicalize
* @param opt_collapseSlashes Boolean true if we want to collapse slashes in
* the path
*
* @returns String containing the canonicalized url (maximally url-decoded
* with hostname normalized, then specially url-encoded)
*/
PROT_EnchashDecrypter.prototype.getCanonicalUrl = function(url) {
var escapedUrl = PROT_URLCanonicalizer.canonicalizeURL_(url);
PROT_EnchashDecrypter.prototype.getCanonicalUrl = function(url,
opt_collapseSlashes) {
var urlUtils = Cc["@mozilla.org/url-classifier/utils;1"]
.getService(Ci.nsIUrlClassifierUtils);
var escapedUrl = urlUtils.canonicalizeURL(url);
// Normalize the host
var host = this.getCanonicalHost(escapedUrl);
if (!host) {
@ -189,6 +191,13 @@ PROT_EnchashDecrypter.prototype.getCanonicalUrl = function(url) {
.getService(Ci.nsIIOService);
var urlObj = ioService.newURI(escapedUrl, null, null);
urlObj.host = host;
if (opt_collapseSlashes) {
// Collapse multiple slashes in the path into a single slash.
// We end up collapsing slashes in the query string, but it's unlikely
// that this would lead to a false positive and it's much simpler to do
// this.
urlObj.path = urlObj.path.replace(/\/+/g, "/");
}
return urlObj.asciiSpec;
}
@ -243,8 +252,19 @@ PROT_EnchashDecrypter.prototype.getCanonicalHost = function(str, opt_maxDots) {
}
PROT_EnchashDecrypter.prototype.parseIPAddress_ = function(host) {
host = host.replace(this.REs_.FIND_TRAILING_DOTS_GLOBAL, "");
if (host.length <= 15) {
// The Windows resolver allows a 4-part dotted decimal IP address to
// have a space followed by any old rubbish, so long as the total length
// of the string doesn't get above 15 characters. So, "10.192.95.89 xy"
// is resolved to 10.192.95.89.
// If the string length is greater than 15 characters, e.g.
// "10.192.95.89 xy.wildcard.example.com", it will be resolved through
// DNS.
var match = this.REs_.FIND_TRAILING_SPACE.exec(host);
if (match) {
host = match[1];
}
}
if (!this.REs_.POSSIBLE_IP.test(host))
return "";
@ -264,13 +284,14 @@ PROT_EnchashDecrypter.prototype.parseIPAddress_ = function(host) {
}
if (canon != "")
parts[k] = canon;
else
return "";
}
return parts.join(".");
}
PROT_EnchashDecrypter.prototype.canonicalNum_ = function(num, bytes, octal) {
if (bytes < 0)
return "";
var temp_num;
@ -292,8 +313,10 @@ PROT_EnchashDecrypter.prototype.canonicalNum_ = function(num, bytes, octal) {
temp_num = -1;
} else if (this.REs_.IS_HEX.test(num)) {
num = this.lastNChars_(num, 8);
var matches = this.REs_.IS_HEX.exec(num);
if (matches) {
num = matches[1];
}
temp_num = parseInt(num, 16);
if (isNaN(temp_num))

View File

@ -552,11 +552,14 @@ PROT_ListManager.prototype.downloadError_ = function(status) {
status = 500;
}
status = parseInt(status, 10);
this.requestBackoff_.noteServerResponse(status);
// Try again in a minute
this.currentUpdateChecker_ =
new G_Alarm(BindToObject(this.checkForUpdates, this), 60000);
var isError = this.requestBackoff_.noteServerResponse(status);
if (isError) {
// Try again in a minute. We'll hit backoff if this is an error. If
// it's not an error, we just ignore the response and try again during
// our regular check interval.
this.currentUpdateChecker_ =
new G_Alarm(BindToObject(this.checkForUpdates, this), 60000);
}
}
PROT_ListManager.prototype.QueryInterface = function(iid) {

View File

@ -87,10 +87,13 @@ RequestBackoff.prototype.canMakeRequest = function() {
}
/**
* Notify this object of the last server response. If it's an error,
* Notify this object of the last server response. If it's an error, we
* check to see if we should trigger a backoff.
* @return Boolean true if this counts as an error.
*/
RequestBackoff.prototype.noteServerResponse = function(status) {
if (this.isErrorStatus_(status)) {
var isError = this.isErrorStatus_(status);
if (isError) {
var now = Date.now();
this.errorTimes_.push(now);
@ -117,6 +120,7 @@ RequestBackoff.prototype.noteServerResponse = function(status) {
this.nextRequestTime_ = 0;
this.backoffTriggered_ = false;
}
return isError;
}
/**

View File

@ -75,17 +75,18 @@ UrlClassifierTableUrl.inherits(UrlClassifierTable);
* Look up a URL in a URL table
*/
UrlClassifierTableUrl.prototype.exists = function(url, callback) {
// PROT_URLCanonicalizer.canonicalizeURL_ is the old way of canonicalizing a
// URL. Unfortunately, it doesn't normalize numeric domains so alternate IP
// formats (hex, octal, etc) won't trigger a match.
// this.enchashDecrypter_.getCanonicalUrl does the right thing and
// normalizes a URL to 4 decimal numbers, but the update server may still be
// giving us encoded IP addresses. So to be safe, we check both cases.
var oldCanonicalized = PROT_URLCanonicalizer.canonicalizeURL_(url);
var canonicalized = this.enchashDecrypter_.getCanonicalUrl(url);
G_Debug(this, "Looking up: " + url + " (" + oldCanonicalized + " and " +
canonicalized + ")");
(new ExistsMultiQuerier([oldCanonicalized, canonicalized],
var urlUtils = Cc["@mozilla.org/url-classifier/utils;1"]
.getService(Ci.nsIUrlClassifierUtils);
// We plan on having the server collapse multiple slashes in the path.
// Until this happens, we check both the raw url and the url with multiple
// slashes removed.
var urls = [
this.enchashDecrypter_.getCanonicalUrl(url),
this.enchashDecrypter_.getCanonicalUrl(url, true) /* collapse slashes */
];
G_Debug(this, "Looking up: " + url + " (" + urls + ")");
(new ExistsMultiQuerier(urls,
this.name,
callback)).run();
}

View File

@ -1,354 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Google Safe Browsing.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Fritz Schneider <fritz@google.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// This is the class we use to canonicalize URLs for TRTables of type
// url. We maximally URL-decode the URL, treating +'s as if they're
// not special. We then specially URL-encode it (we encode ASCII
// values [0, 32] (whitespace or unprintable), 37 (%), [127, 255]
// (unprintable)).
//
// This mapping is not a function. That is, multiple URLs can map to
// the same canonical representation. However this is OK because
// collisions happen only when there are weird characters (e.g.,
// nonprintables), and the canonical representation makes us robust
// to some weird kinds of encoding we could see.
//
// All members are static at this point -- this is basically a namespace.
/**
* Create a new URLCanonicalizer. Useless because members are static.
*
* @constructor
*/
function PROT_URLCanonicalizer() {
throw new Error("No need to instantiate a canonicalizer at this point.");
}
PROT_URLCanonicalizer.debugZone = "urlcanonicalizer";
PROT_URLCanonicalizer.hexChars_ = "0123456789ABCDEF";
/**
* Helper funciton to (maybe) convert a two-character hex string into its
* decimal numerical equivalent
*
* @param hh String of length two that might be a valid hex sequence
*
* @returns Number: NaN if hh wasn't valid hex, else the appropriate decimal
* value
*/
PROT_URLCanonicalizer.hexPairToInt_ = function(hh) {
return Number("0x" + hh);
}
/**
* Helper function to hex-encode a number
*
* @param val Number in range [0, 255]
*
* @returns String containing the hex representation of that number (sans 0x)
*/
PROT_URLCanonicalizer.toHex_ = function(val) {
var retVal = PROT_URLCanonicalizer.hexChars_.charAt((val >> 4) & 15) +
PROT_URLCanonicalizer.hexChars_.charAt(val & 15);
return retVal;
}
/**
* Canonicalize a URL. DON'T USE THIS DIRECTLY. Use
* PROT_EnchashDecrypter.prototype.getCanonicalUrl instead. This method
* url-decodes a string, but it doesn't normalize the hostname. The method
* in EnchashDecrypter first calls this method, then normalizes the hostname.
*
* @param url String to canonicalize
*
* @returns String containing the canonicalized url (maximally url-decoded,
* then specially url-encoded)
*/
PROT_URLCanonicalizer.canonicalizeURL_ = function(url) {
var arrayOfASCIIVals = PROT_URLCanonicalizer.fullyDecodeURL_(url);
return PROT_URLCanonicalizer.specialEncodeURL_(arrayOfASCIIVals);
}
/**
* Maximally URL-decode a URL. This breaks the semantics of the URL, but
* we don't care because we're using it for lookup, not for navigation.
* We break multi-byte UTF-8 escape sequences as well, but we don't care
* so long as they canonicalize the same way consistently (they do).
*
* @param url String containing the URL to maximally decode. Should ONLY
* contain characters with UCS codepoints U+0001 to U+00FF
* (the ASCII set minus null).
*
* @returns Array of ASCII values corresponding to the decoded sequence of
* characters in the url
*/
PROT_URLCanonicalizer.fullyDecodeURL_ = function(url) {
// The goals here are: simplicity, correctness, and most of all
// portability; we want the same implementation of canonicalization
// wherever we use it so as to to minimize the chances of
// inconsistency. For example, we have to do this canonicalization
// on URLs we get from third parties, and at the lookup server when
// we get a request.
//
// The following implementation should translate easily to any
// language that supports arrays and pointers or references. Note
// that arrays are pointer types in JavaScript, so foo = [some,
// array] points foo at the array; it doesn't copy it. The
// implementation is efficient (linear) so long as most %'s in the
// url belong to valid escape sequences and there aren't too many
// doubly-escaped values.
// The basic idea is to copy current input to output, decoding escape
// sequences as we see them, until we decode a %. At that point we start
// copying into the "next iteration buffer" instead of the output buffer;
// we do this so we can accomodate multiply-escaped strings. When we hit
// the end of the input, we take the "next iteration buffer" as our input,
// and start over.
var nextIteration = url.split("");
var output = [];
while (nextIteration.length) {
var decodedAPercent = false;
var thisIteration = nextIteration;
var nextIteration = [];
var i = 0;
while (i < thisIteration.length) {
var c = thisIteration[i];
if (c == "%" && i + 2 < thisIteration.length) {
// Peek ahead to see if we have a valid HH sequence
var asciiVal =
PROT_URLCanonicalizer.hexPairToInt_(thisIteration[i + 1] +
thisIteration[i + 2]);
if (!isNaN(asciiVal)) {
i += 2; // Valid HH sequence; consume it
if (asciiVal == 0) // We special case nulls
asciiVal = 1;
c = String.fromCharCode(asciiVal);
if (c == "%")
decodedAPercent = true;
}
}
if (decodedAPercent)
nextIteration[nextIteration.length] = c;
else
output[output.length] = c.charCodeAt(0);
++i;
}
}
return output;
}
/**
* Maximally URL-decode a URL (same as fullyDecodeURL_ except that it
* returns a string). Useful for making unittests more readable.
*
* @param url String containing the URL to maximally decode. Should ONLY
* contain characters with UCS codepoints U+0001 to U+00FF
* (the ASCII set minus null).
*
* @returns String containing the decoded URL
*/
PROT_URLCanonicalizer.fullyDecodeURLAsString_ = function(url) {
var arrayOfASCIIVals = PROT_URLCanonicalizer.fullyDecodeURL_(url);
var s = "";
for (var i = 0; i < arrayOfASCIIVals.length; i++)
s += String.fromCharCode(arrayOfASCIIVals[i]);
return s;
}
/**
* Specially URL-encode the given array of ASCII values. We want to encode
* the charcters: [0, 32], 37, [127, 255].
*
* @param arrayOfASCIIValues Array of ascii values (numbers) to encode
*
* @returns String corresonding to the escaped URL
*/
PROT_URLCanonicalizer.specialEncodeURL_ = function(arrayOfASCIIValues) {
var output = [];
for (var i = 0; i < arrayOfASCIIValues.length; i++) {
var n = arrayOfASCIIValues[i];
if (n <= 32 || n == 37 || n >= 127)
output.push("%" + ((!n) ? "01" : PROT_URLCanonicalizer.toHex_(n)));
else
output.push(String.fromCharCode(n));
}
return output.join("");
}
#ifdef DEBUG
/**
* Lame unittesting function
*/
function TEST_PROT_URLCanonicalizer() {
if (G_GDEBUG) {
var z = "urlcanonicalizer UNITTEST";
G_debugService.enableZone(z);
G_Debug(z, "Starting");
// ------ TEST HEX GOTCHA ------
var hexify = PROT_URLCanonicalizer.toHex_;
var shouldHaveLeadingZeros = hexify(0) + hexify(1);
G_Assert(z, shouldHaveLeadingZeros == "0001",
"Need to append leading zeros to hex rep value <= 15 !")
// ------ TEST DECODING ------
// For convenience, shorten the function name
var dec = PROT_URLCanonicalizer.fullyDecodeURLAsString_;
// Test empty string
G_Assert(z, dec("") == "", "decoding empty string");
// Test decoding of all characters
var allCharsEncoded = "";
var allCharsEncodedLowercase = "";
var allCharsAsString = "";
// Special case null
allCharsEncoded += "%01";
allCharsEncodedLowercase += "%01";
allCharsAsString += String.fromCharCode(1);
for (var i = 1; i < 256; i++) {
allCharsEncoded += "%" + PROT_URLCanonicalizer.toHex_(i);
allCharsEncodedLowercase += "%" +
PROT_URLCanonicalizer.toHex_(i).toLowerCase();
allCharsAsString += String.fromCharCode(i);
}
G_Assert(z, dec(allCharsEncoded) == allCharsAsString, "decoding escaped");
G_Assert(z, dec(allCharsEncodedLowercase) == allCharsAsString,
"decoding lowercase");
// Test %-related edge cases
G_Assert(z, dec("%") == "%", "1 percent");
G_Assert(z, dec("%xx") == "%xx", "1 percent, two non-hex");
G_Assert(z, dec("%%") == "%%", "2 percent");
G_Assert(z, dec("%%%") == "%%%", "3 percent");
G_Assert(z, dec("%%%%") == "%%%%", "4 percent");
G_Assert(z, dec("%1") == "%1", "1 percent, one nonhex");
G_Assert(z, dec("%1z") == "%1z", "1 percent, two nonhex");
G_Assert(z, dec("a%1z") == "a%1z", "nonhex, 1 percent, two nonhex");
G_Assert(z, dec("abc%d%e%fg%hij%klmno%") == "abc%d%e%fg%hij%klmno%",
"lots of percents, no hex");
// Test repeated %-decoding. Note: %25 --> %, %32 --> 2, %35 --> 5
G_Assert(z, dec("%25") == "%", "single-encoded %");
G_Assert(z, dec("%25%32%35") == "%", "double-encoded %");
G_Assert(z, dec("asdf%25%32%35asd") == "asdf%asd", "double-encoded % 2");
G_Assert(z, dec("%%%25%32%35asd%%") == "%%%asd%%", "double-encoded % 3");
G_Assert(z, dec("%25%32%35%25%32%35%25%32%35") == "%%%",
"sequenctial double-encoded %");
G_Assert(z, dec("%2525252525252525") == "%", "many-encoded %");
G_Assert(z, dec("%257Ea%2521b%2540c%2523d%2524e%25f%255E00%252611%252A22%252833%252944_55%252B") == "~a!b@c#d$e%f^00&11*22(33)44_55+",
"4x-encoded string");
// ------ TEST ENCODING ------
// For convenience, shorten the function name
var enc = PROT_URLCanonicalizer.specialEncodeURL_;
// Test empty string
G_Assert(z, enc([]) == "", "encoding empty array");
// Test that all characters we shouldn't encode ([33-36],[38,126]) are not.
var no = [];
var noAsString = "";
for (var i = 33; i < 127; i++)
if (i != 37) { // skip %
no.push(i);
noAsString += String.fromCharCode(i);
}
G_Assert(z, enc(no) == noAsString, "chars to not encode");
// Test that all the chars that we should encode [0,32],37,[127,255] are
var yes = [];
var yesAsString = "";
var yesExpectedString = "";
// Special case 0
yes.push(0);
yesAsString += String.fromCharCode(1);
yesExpectedString += "%01";
for (var i = 1; i < 256; i++)
if (i < 33 || i == 37 || i > 126) {
yes.push(i);
yesAsString += String.fromCharCode(i);
var hex = i.toString(16).toUpperCase();
yesExpectedString += "%" + ((i < 16) ? "0" : "") + hex;
}
G_Assert(z, enc(yes) == yesExpectedString, "chars to encode");
// Can't use decodeURIComponent or encodeURIComponent to test b/c UTF-8
// ------ TEST COMPOSITION ------
// For convenience, shorten function name:
var c = PROT_URLCanonicalizer.canonicalizeURL_;
G_Assert(z, c("http://www.google.com") == "http://www.google.com",
"http://www.google.com");
G_Assert(z, c("http://%31%36%38%2e%31%38%38%2e%39%39%2e%32%36/%2E%73%65%63%75%72%65/%77%77%77%2E%65%62%61%79%2E%63%6F%6D/") == "http://168.188.99.26/.secure/www.ebay.com/",
"fully encoded ebay");
G_Assert(z, c("http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/") == "http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/",
"long url with spaces that stays same");
// TODO: MORE!
G_Debug(z, "PASSED");
}
}
#endif

View File

@ -11,6 +11,7 @@ XPIDL_MODULE = url-classifier
XPIDLSRCS = nsIUrlClassifierDBService.idl \
nsIUrlClassifierStreamUpdater.idl \
nsIUrlClassifierTable.idl \
nsIUrlClassifierUtils.idl \
nsIUrlListManager.idl \
$(NULL)

View File

@ -0,0 +1,57 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Google, Inc.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
/**
* Some utility methods used by the url classifier.
*/
[scriptable, uuid(9afd3add-eadc-409f-a187-e3bf60e47290)]
interface nsIUrlClassifierUtils : nsISupports
{
/**
* Canonicalize a URL. DON'T USE THIS DIRECTLY. Use
* PROT_EnchashDecrypter.prototype.getCanonicalUrl instead. This method
* url-decodes a string, but it doesn't normalize the hostname. The method
* in EnchashDecrypter first calls this method, then normalizes the hostname.
*
* @param url String to canonicalize
*
* @returns String containing the canonicalized url (maximally url-decoded,
* then specially url-encoded)
*/
ACString canonicalizeURL(in ACString url);
};

View File

@ -21,6 +21,7 @@ REQUIRES = necko \
CPPSRCS = \
nsUrlClassifierDBService.cpp \
nsUrlClassifierStreamUpdater.cpp \
nsUrlClassifierUtils.cpp \
$(NULL)
LOCAL_INCLUDES = \

View File

@ -86,6 +86,10 @@ static PRMonitor *gMonitor = nsnull;
// Thread that we do the updates on.
static PRThread* gDbBackgroundThread = nsnull;
// Once we've committed to shutting down, don't do work in the background
// thread.
static PRBool gShuttingDownThread = PR_FALSE;
static const char* kNEW_TABLE_SUFFIX = "_new";
@ -264,6 +268,9 @@ nsUrlClassifierDBServiceWorker::Exists(const nsACString& tableName,
const nsACString& key,
nsIUrlClassifierCallback *c)
{
if (gShuttingDownThread)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = OpenDb();
if (NS_FAILED(rv)) {
NS_ERROR("Unable to open database");
@ -309,6 +316,9 @@ NS_IMETHODIMP
nsUrlClassifierDBServiceWorker::CheckTables(const nsACString & tableNames,
nsIUrlClassifierCallback *c)
{
if (gShuttingDownThread)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = OpenDb();
if (NS_FAILED(rv)) {
NS_ERROR("Unable to open database");
@ -351,6 +361,9 @@ NS_IMETHODIMP
nsUrlClassifierDBServiceWorker::UpdateTables(const nsACString& updateString,
nsIUrlClassifierCallback *c)
{
if (gShuttingDownThread)
return NS_ERROR_NOT_INITIALIZED;
LOG(("Updating tables\n"));
nsresult rv = OpenDb();
@ -498,6 +511,11 @@ nsUrlClassifierDBServiceWorker::Finish(nsIUrlClassifierCallback *c)
if (!mHasPendingUpdate)
return NS_OK;
if (gShuttingDownThread) {
mConnection->RollbackTransaction();
return NS_ERROR_NOT_INITIALIZED;
}
nsresult rv = NS_OK;
for (PRUint32 i = 0; i < mTableUpdateLines.Length(); ++i) {
rv = MaybeSwapTables(mTableUpdateLines[i]);
@ -843,8 +861,10 @@ PR_STATIC_CALLBACK(void) DestroyHandler(PLEvent *ev);
nsUrlClassifierDBService::~nsUrlClassifierDBService()
{
sUrlClassifierDBService = nsnull;
PR_DestroyMonitor(gMonitor);
gMonitor = nsnull;
if (gMonitor) {
PR_DestroyMonitor(gMonitor);
gMonitor = nsnull;
}
}
nsresult
@ -883,7 +903,8 @@ nsUrlClassifierDBService::Init()
if (!observerService)
return NS_ERROR_FAILURE;
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
observerService->AddObserver(this, "profile-before-change", PR_FALSE);
observerService->AddObserver(this, "xpcom-shutdown", PR_FALSE);
return NS_OK;
}
@ -1056,9 +1077,12 @@ NS_IMETHODIMP
nsUrlClassifierDBService::Observe(nsISupports *aSubject, const char *aTopic,
const PRUnichar *aData)
{
if (nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
Shutdown();
}
NS_ASSERTION(strcmp(aTopic, "profile-before-change") == 0 ||
strcmp(aTopic, "xpcom-shutdown") == 0,
"Unexpected observer topic");
Shutdown();
return NS_OK;
}
@ -1082,6 +1106,11 @@ nsUrlClassifierDBService::EnsureThreadStarted()
nsresult
nsUrlClassifierDBService::Shutdown()
{
LOG(("shutting down db service\n"));
if (!gDbBackgroundThread)
return NS_OK;
nsresult rv;
EnsureThreadStarted();
@ -1095,8 +1124,10 @@ nsUrlClassifierDBService::Shutdown()
mWorker,
PROXY_ASYNC,
getter_AddRefs(proxy));
proxy->CloseDb();
NS_ENSURE_SUCCESS(rv, rv);
if (NS_SUCCEEDED(rv)) {
rv = proxy->CloseDb();
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to post close db event");
}
}
PLEvent* ev = new PLEvent;
@ -1107,8 +1138,9 @@ nsUrlClassifierDBService::Shutdown()
}
LOG(("joining background thread"));
rv = PR_JoinThread(gDbBackgroundThread);
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to join background thread");
gShuttingDownThread = PR_TRUE;
PRStatus ok = PR_JoinThread(gDbBackgroundThread);
NS_ASSERTION(ok == PR_SUCCESS, "failed to join background thread");
gDbBackgroundThread = nsnull;
return NS_OK;

View File

@ -42,7 +42,6 @@ const Ci = Components.interfaces;
#include ../content/js/lang.js
#include ../content/enchash-decrypter.js
#include ../content/multi-querier.js
#include ../content/url-canonicalizer.js
#include ../content/trtable.js
var modScope = this;

View File

@ -0,0 +1,103 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Url Classifier code
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsEscape.h"
#include "nsString.h"
#include "nsUrlClassifierUtils.h"
static char int_to_hex_digit(PRInt32 i)
{
NS_ASSERTION((i >= 0) && (i <= 15), "int too big in int_to_hex_digit");
return NS_STATIC_CAST(char, ((i < 10) ? (i + '0') : ((i - 10) + 'A')));
}
nsUrlClassifierUtils::nsUrlClassifierUtils()
{
}
NS_IMPL_ISUPPORTS1(nsUrlClassifierUtils, nsIUrlClassifierUtils)
/* ACString canonicalizeURL (in ACString url); */
NS_IMETHODIMP
nsUrlClassifierUtils::CanonicalizeURL(const nsACString & url, nsACString & _retval)
{
nsCAutoString decodedUrl(url);
nsCAutoString temp;
while (NS_UnescapeURL(decodedUrl.get(), decodedUrl.Length(), 0, temp)) {
decodedUrl.Assign(temp);
temp.Truncate();
}
SpecialEncode(decodedUrl, _retval);
return NS_OK;
}
// This function will encode all "special" characters in typical url
// encoding, that is %hh where h is a valid hex digit. See the comment in
// the header file for details.
PRBool
nsUrlClassifierUtils::SpecialEncode(const nsACString & url, nsACString & _retval)
{
PRBool changed = PR_FALSE;
const char* curChar = url.BeginReading();
const char* end = url.EndReading();
while (curChar != end) {
unsigned char c = NS_STATIC_CAST(unsigned char, *curChar);
if (ShouldURLEscape(c)) {
// We don't want to deal with 0, as it can break certain strings, just
// encode as one.
if (c == 0)
c = 1;
_retval.Append('%');
_retval.Append(int_to_hex_digit(c / 16));
_retval.Append(int_to_hex_digit(c % 16));
changed = PR_TRUE;
} else {
_retval.Append(*curChar);
}
curChar++;
}
return changed;
}
PRBool
nsUrlClassifierUtils::ShouldURLEscape(const unsigned char c) const
{
return c <= 32 || c == '%' || c >=127;
}

View File

@ -0,0 +1,67 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Url Classifier code
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsUrlClassifierUtils_h_
#define nsUrlClassifierUtils_h_
#include "nsIUrlClassifierUtils.h"
class nsUrlClassifierUtils : public nsIUrlClassifierUtils
{
public:
nsUrlClassifierUtils();
~nsUrlClassifierUtils() {};
NS_DECL_ISUPPORTS
NS_DECL_NSIURLCLASSIFIERUTILS
// This function will encode all "special" characters in typical url encoding,
// that is %hh where h is a valid hex digit. The characters which are encoded
// by this function are any ascii characters under 32(control characters and
// space), 37(%), and anything 127 or above (special characters). Url is the
// string to encode, ret is the encoded string. Function returns true if
// ret != url.
PRBool SpecialEncode(const nsACString & url, nsACString & _retval);
private:
// Disallow copy constructor
nsUrlClassifierUtils(const nsUrlClassifierUtils&);
// Function to tell if we should encode a character.
PRBool ShouldURLEscape(const unsigned char c) const;
};
#endif // nsUrlClassifierUtils_h_

View File

@ -43,5 +43,39 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = test_url-classifier
MOZILLA_INTERNAL_API = 1
REQUIRES = \
string \
url-classifier \
xpcom \
$(NULL)
# simple c++ tests (no xpcom)
CPPSRCS = \
TestUrlClassifierUtils.cpp \
$(NULL)
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
LOCAL_INCLUDES = \
-I$(srcdir)/../src \
-I$(srcdir)/../public \
$(NULL)
LIBS = \
../src/$(LIB_PREFIX)urlclassifier_s.$(LIB_SUFFIX) \
$(XPCOM_LIBS) \
$(NSPR_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk
check::
@echo Running tests...
@$(EXIT_ON_ERROR) \
for f in $(SIMPLE_PROGRAMS); do \
$(RUN_TEST_PROGRAM) $(DIST)/bin/$$f; \
done

View File

@ -0,0 +1,195 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Url Classifier code
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdio.h>
#include <ctype.h>
#include "nsEscape.h"
#include "nsString.h"
#include "nsUrlClassifierUtils.h"
static int gTotalTests = 0;
static int gPassedTests = 0;
static char int_to_hex_digit(PRInt32 i) {
NS_ASSERTION((i >= 0) && (i <= 15), "int too big in int_to_hex_digit");
return NS_STATIC_CAST(char, ((i < 10) ? (i + '0') : ((i - 10) + 'A')));
}
static void CheckEquals(nsCString & expected, nsCString & actual)
{
if (!(expected).Equals((actual))) {
fprintf(stderr, "FAILED: expected |%s| but was |%s|\n", (expected).get(),
(actual).get());
} else {
gPassedTests++;
}
gTotalTests++;
}
void TestUnescapeHelper(const char* in, const char* expected)
{
nsCString out, strIn(in), strExp(expected);
nsUrlClassifierUtils utils;
NS_UnescapeURL(strIn.get(), strIn.Length(), esc_AlwaysCopy, out);
CheckEquals(strExp, out);
}
// Make sure Unescape from nsEncode.h's unescape does what the server does.
void TestUnescape()
{
// test empty string
TestUnescapeHelper("\0", "\0");
// Test docoding of all characters.
nsCString allCharsEncoded, allCharsEncodedLowercase, allCharsAsString;
for (PRInt32 i = 1; i < 256; ++i) {
allCharsEncoded.Append('%');
allCharsEncoded.Append(int_to_hex_digit(i / 16));
allCharsEncoded.Append((int_to_hex_digit(i % 16)));
allCharsEncodedLowercase.Append('%');
allCharsEncodedLowercase.Append(tolower(int_to_hex_digit(i / 16)));
allCharsEncodedLowercase.Append(tolower(int_to_hex_digit(i % 16)));
allCharsAsString.Append(NS_STATIC_CAST(char, i));
}
nsUrlClassifierUtils utils;
nsCString out;
NS_UnescapeURL(allCharsEncoded.get(), allCharsEncoded.Length(), esc_AlwaysCopy, out);
CheckEquals(allCharsAsString, out);
out.Truncate();
NS_UnescapeURL(allCharsEncodedLowercase.get(), allCharsEncodedLowercase.Length(), esc_AlwaysCopy, out);
CheckEquals(allCharsAsString, out);
// Test %-related edge cases
TestUnescapeHelper("%", "%");
TestUnescapeHelper("%xx", "%xx");
TestUnescapeHelper("%%", "%%");
TestUnescapeHelper("%%%", "%%%");
TestUnescapeHelper("%%%%", "%%%%");
TestUnescapeHelper("%1", "%1");
TestUnescapeHelper("%1z", "%1z");
TestUnescapeHelper("a%1z", "a%1z");
TestUnescapeHelper("abc%d%e%fg%hij%klmno%", "abc%d%e%fg%hij%klmno%");
// A few more tests
TestUnescapeHelper("%25", "%");
TestUnescapeHelper("%25%32%35", "%25");
}
void TestEncodeHelper(const char* in, const char* expected)
{
nsCString out, strIn(in), strExp(expected);
nsUrlClassifierUtils utils;
utils.SpecialEncode(strIn, out);
CheckEquals(strExp, out);
}
void TestEnc()
{
// Test empty string
TestEncodeHelper("", "");
// Test that all characters we shouldn't encode ([33-36],[38,126]) are not.
nsCString noenc;
for (PRInt32 i = 33; i < 127; i++) {
if (i != 37) { // skip %
noenc.Append(NS_STATIC_CAST(char, i));
}
}
nsUrlClassifierUtils utils;
nsCString out;
utils.SpecialEncode(noenc, out);
CheckEquals(noenc, out);
// Test that all the chars that we should encode [0,32],37,[127,255] are
nsCString yesAsString, yesExpectedString;
for (PRInt32 i = 1; i < 256; i++) {
if (i < 33 || i == 37 || i > 126) {
yesAsString.Append(NS_STATIC_CAST(char, i));
yesExpectedString.Append('%');
yesExpectedString.Append(int_to_hex_digit(i / 16));
yesExpectedString.Append(int_to_hex_digit(i % 16));
}
}
out.Truncate();
utils.SpecialEncode(yesAsString, out);
CheckEquals(yesExpectedString, out);
}
void TestCanonicalizeHelper(const char* in, const char* expected)
{
nsCString out, strIn(in), strExp(expected);
nsUrlClassifierUtils utils;
nsresult rv = utils.CanonicalizeURL(strIn, out);
NS_ASSERTION(rv == NS_OK, "com didn't return NS_OK");
CheckEquals(strExp, out);
}
void TestCanonicalize()
{
// Test repeated %-decoding. Note: %25 --> %, %32 --> 2, %35 --> 5
TestCanonicalizeHelper("%25", "%25");
TestCanonicalizeHelper("%25%32%35", "%25");
TestCanonicalizeHelper("asdf%25%32%35asd", "asdf%25asd");
TestCanonicalizeHelper("%%%25%32%35asd%%", "%25%25%25asd%25%25");
TestCanonicalizeHelper("%25%32%35%25%32%35%25%32%35", "%25%25%25");
TestCanonicalizeHelper("%25", "%25");
TestCanonicalizeHelper("%257Ea%2521b%2540c%2523d%2524e%25f%255E00%252611%252A22%252833%252944_55%252B",
"~a!b@c#d$e%25f^00&11*22(33)44_55+");
TestCanonicalizeHelper("", "");
TestCanonicalizeHelper("http://www.google.com", "http://www.google.com");
TestCanonicalizeHelper("http://%31%36%38%2e%31%38%38%2e%39%39%2e%32%36/%2E%73%65%63%75%72%65/%77%77%77%2E%65%62%61%79%2E%63%6F%6D/",
"http://168.188.99.26/.secure/www.ebay.com/");
TestCanonicalizeHelper("http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/",
"http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/");
}
int main(int argc, char **argv)
{
TestUnescape();
TestEnc();
TestCanonicalize();
printf("%d of %d tests passed\n", gPassedTests, gTotalTests);
return (gPassedTests != gTotalTests);
}

View File

@ -126,21 +126,19 @@ function SetForcedCharset(charset)
var gPrevCharset = null;
function UpdateCurrentCharset()
{
var menuitem = null;
// exctract the charset from DOM
// extract the charset from DOM
var wnd = document.commandDispatcher.focusedWindow;
if ((window == wnd) || (wnd == null)) wnd = window.content;
menuitem = document.getElementById('charset.' + wnd.document.characterSet);
// Uncheck previous item
if (gPrevCharset) {
var pref_item = document.getElementById('charset.' + gPrevCharset);
if (pref_item)
pref_item.setAttribute('checked', 'false');
}
var menuitem = document.getElementById('charset.' + wnd.document.characterSet);
if (menuitem) {
// uncheck previously checked item to workaround Mac checkmark problem
// bug 98625
if (gPrevCharset) {
var pref_item = document.getElementById('charset.' + gPrevCharset);
if (pref_item)
pref_item.setAttribute('checked', 'false');
}
menuitem.setAttribute('checked', 'true');
}
}

View File

@ -221,7 +221,7 @@ function commonDialogFocus(aEvent)
var script = "document.documentElement.getButton('accept').disabled = false; ";
script += "document.documentElement.getButton('extra1').disabled = false; ";
script += "document.documentElement.getButton('extra2').disabled = false;";
setTimeout(script, 250);
setTimeout(script, 1000);
}
}

View File

@ -334,7 +334,7 @@ function internalSave(aURL, aDocument, aDefaultFileName, aContentDisposition,
saveAsType == kSaveAsType_Text) ?
"text/plain" : aContentType,
target : fileURL,
postData : isDocument ? getPostData() : null,
postData : isDocument ? getPostData(aDocument) : null,
bypassCache : aShouldBypassCache
};
@ -707,14 +707,16 @@ function appendFiltersForContentType(aFilePicker, aContentType, aFileExtension,
aFilePicker.appendFilters(Components.interfaces.nsIFilePicker.filterAll);
}
function getPostData()
function getPostData(aDocument)
{
try {
var sessionHistory = getWebNavigation().sessionHistory;
var entry = sessionHistory.getEntryAtIndex(sessionHistory.index, false);
entry = entry.QueryInterface(Components.interfaces.nsISHEntry);
return entry.postData;
var sessionHistory = aDocument.defaultView
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.sessionHistory;
return sessionHistory.getEntryAtIndex(sessionHistory.index, false)
.QueryInterface(Components.interfaces.nsISHEntry)
.postData;
}
catch (e) {
}
@ -900,6 +902,9 @@ function getNormalizedLeafName(aFile, aDefaultExtension)
// Remove trailing dots and spaces on windows
aFile = aFile.replace(/[\s.]+$/, "");
#endif
// Remove leading dots
aFile = aFile.replace(/^\.+/, "");
// Fix up the file name we're saving to to include the default extension
var i = aFile.lastIndexOf(".");

View File

@ -701,11 +701,12 @@ under either the MPL or the [___] License."
</p>
<p>
<!-- This list created from the entire Mozilla source tree on 2006-03-30.
<!-- This list created from the entire Mozilla source tree on 2007-05-30.
It was created using a modified version of the "relic" script in
tools/relic, along with the make-id-list script in the same directory. -->
Aaron Leventhal,
Aaron Schulman,
ActiveState Tool Corp,
Akkana Peck,
Alex Fritze,
@ -714,6 +715,7 @@ Alexander Surkov,
Andreas Otte,
Andreas Premstaller,
Andrew Thompson,
ArentJan Banck,
Asaf Romano,
Axel Hecht,
Ben Bucksch,
@ -727,9 +729,12 @@ Brendan Eich,
Brian Bober,
Brian Ryner,
Brian Stell,
Bruce Davidson,
Bruno Haible,
Calum Robinson,
Cedric Chantepie,
Chiaki Koufugata,
Chris McAfee,
Christian Biesinger,
Christopher A. Aillon,
Christopher Blizzard,
@ -740,6 +745,7 @@ Conrad Carlen,
Crocodile Clips Ltd,
Cyrus Patel,
Dainis Jonitis,
Dan Mosedale,
Daniel Brooks,
Daniel Glazman,
Daniel Kouril,
@ -756,18 +762,20 @@ Digital Creations 2 Inc,
Doron Rosenberg,
Doug Turner,
Elika J. Etemad,
Eric Belhaire,
Eric Hodel,
Esben Mose Hansen,
Frank Sch&ouml;nheit,
Fredrik Holmqvist,
Gavin Sharp,
Geoff Beier,
Gervase Markham,
Giorgio Maone,
Google,
Google Inc,
H&aring;kan Waara,
Henri Torgemane,
Heriot-Watt University,
Hewlett-Packard Company,
H&aring;kan Waara,
i-DNS.net International,
Ian Hickson,
Ian Oeschger,
@ -780,8 +788,10 @@ James Ross,
Jamie Zawinski,
Jan Varga,
Jason Barnabe,
Jean-Francois Ducarroz,
Jeff Tsai,
Jeff Walden,
Jefferson Software Inc,
Joe Hewitt,
Joey Minta,
John B. Keiser,
@ -790,27 +800,36 @@ John Fairhurst,
John Wolfe,
Jonas Sicking,
Jonathan Watt,
Josh Aas,
Josh Soref,
Juan Lang,
Jungshik Shin,
Jussi Kukkonen,
Karsten D&uuml;sterloh,
Keith Visco,
Ken Herron,
Kevin Gerich,
Kipp E.B. Hickman,
L. David Baron,
Lixto GmbH,
Makoto Kato,
Marc Bevand,
Marco Manfredini,
Marco Pesenti Gritti,
Mark Hammond,
Mark Mentovai,
Markus G. Kuhn,
Matt Judy,
Matthew Willis,
Merle Sterling,
Michael J. Fromberger,
Michal Ceresna,
Michiel van Leeuwen,
Mike Connor,
Mike Pinkerton,
Mike Potter,
Mike Shaver,
MITRE Corporation,
Mozdev Group,
Mozilla Corporation,
Mozilla Foundation,
@ -822,16 +841,21 @@ Netscape Commmunications Corp,
Netscape Communications Corporation,
New Dimensions Consulting,
Novell Inc,
OEone Corporation,
Olli Pettay,
Oracle Corporation,
Owen Taylor,
Paul Ashford,
Paul Kocher of Cryptography Research,
Paul Kocher,
Paul Sandoz,
Peter Annema,
Peter Hartshorn,
Peter Van der Beken,
Phil Ringnalda,
Philipp Kewisch,
Pierre Chanial,
Prachi Gauriar,
Qualcomm Inc,
R.J. Keller,
Rajiv Dayal,
Ramalingam Saravanan,
@ -858,25 +882,29 @@ Sergei Dolgov,
Seth Spitzer,
Shy Shalom,
Silverstone Interactive,
Simdesk Technologies Inc,
Simon B&uuml;nzli,
Simon Fraser,
Simon Montagu,
Simon Paquet,
Simon Wilkinson,
Sqlite Project,
Srilatha Moturi,
Stefan Sitter,
Stephen Horlander,
Steve Swanson,
Stuart Morgan,
Stuart Parmenter,
Sun Microsystems Inc,
The MITRE Corporation,
The Mozilla Corporation,
The sqlite Project,
The University of Queensland,
Tim Copperfield,
Tom Germeau,
Tomas M&uuml;ller,
University of Queensland,
Vincent B&eacute;ron,
Vladimir Vukicevic,
Wolfgang Rosenauer,
YAMASHITA Makoto,
Zack Rusin and
Zack Rusin,
Zero-Knowledge Systems.
</p>
@ -2175,8 +2203,13 @@ SOFTWARE.
<h1><a name="other-notices"></a>Other Required Notices</h1>
<p>This software is based in part on the work of the Independent
JPEG Group.</p>
<ul>
<li>This software is based in part on the work of the Independent
JPEG Group.</li>
<li>Portions of the OS/2 version of this software are copyright
&copy;1996-2002 <a href="http://www.freetype.org/">The FreeType Project</a>.
All rights reserved.</li>
</ul>
<hr>
@ -2213,7 +2246,7 @@ SOFTWARE.
SupportSoft, Inc. All Rights Reserved.)
<li>Image files containing the trademarks and logos of the Mozilla
Foundation, which may not be reproduced without permission.
(Copyright &copy;2004-2007 The Mozilla Foundation.
(Copyright &copy;2004-2008 The Mozilla Foundation.
All Rights Reserved.)
</ul>

View File

@ -599,12 +599,13 @@
// If location bar is hidden and the URL type supports a host,
// add the scheme and host to the title to prevent spoofing.
// XXX https://bugzilla.mozilla.org/show_bug.cgi?id=22183#c239
// (only for schemes that support a host)
try {
if (docElement.getAttribute("chromehidden").indexOf("location") != -1) {
var uri = this.mURIFixup.createExposableURI(
this.mCurrentBrowser.currentURI);
if (uri.host)
if (uri.scheme == "about")
newTitle = uri.spec + sep + newTitle;
else
newTitle = uri.prePath + sep + newTitle;
}
} catch (e) {}

View File

@ -150,7 +150,7 @@
<handler event="focus" phase="capturing">
<![CDATA[
if (!this.hasAttribute("focused")) {
if (document.commandDispatcher.focusedElement != this.inputField)
if (event.originalTarget != this.inputField)
this.inputField.focus();
else if (this.mIgnoreFocus)
this.mIgnoreFocus = false;

View File

@ -139,8 +139,11 @@ COMPONENT_LIBS += \
jsd \
$(NULL)
ifdef MOZ_PLACES
ifdef MOZ_STORAGE
COMPONENT_LIBS += storagecomps
endif
ifdef MOZ_PLACES
STATIC_LIBS += morkreader_s
else
COMPONENT_LIBS += \
@ -348,6 +351,9 @@ endif
ifneq (,$(filter gtk gtk2 qt xlib,$(MOZ_WIDGET_TOOLKIT)))
EXTRA_DSO_LDOPTS += $(XLDFLAGS) $(XLIBS) $(MOZ_GTK_LDFLAGS) $(MOZ_XFT_LIBS) $(MOZ_GTK2_LIBS) $(XT_LIBS)
ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
EXTRA_DSO_LDOPTS += -lgthread-2.0
endif
endif
ifdef MOZ_ENABLE_XPRINT
@ -363,7 +369,7 @@ EXTRA_DSO_LDOPTS += -lbe
endif
ifeq ($(OS_ARCH),WINNT)
EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME,shell32 ole32 uuid version winspool Comdlg32)
EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME,shell32 ole32 uuid version winspool comdlg32)
ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC))
EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME,imagehlp)
endif

View File

@ -151,9 +151,14 @@
#define XREMOTE_MODULES
#endif
#ifdef MOZ_STORAGE
#define STORAGE_MODULE MODULE(mozStorageModule)
#else
#define STORAGE_MODULE
#endif
#ifdef MOZ_PLACES
#define PLACES_MODULES \
MODULE(mozStorageModule)
#define PLACES_MODULES
#else
#define PLACES_MODULES \
MODULE(nsMorkModule)
@ -195,6 +200,7 @@
MODULE(application) \
MODULE(Apprunner) \
MODULE(CommandLineModule) \
STORAGE_MODULE \
PLACES_MODULES \
MODULE(nsToolkitCompsModule) \
XREMOTE_MODULES \

View File

@ -6,7 +6,7 @@
<!ENTITY about.version "version">
<!ENTITY about.copy.beforeLink "Copyright &copy; 1998-2007 by">
<!ENTITY about.copy.beforeLink "Copyright &copy; 1998-2008 by">
<!ENTITY about.copy.linkTitle "contributors">
<!ENTITY about.copy.afterLink "to the Mozilla Project.">

View File

@ -273,6 +273,10 @@ nsUnknownContentTypeDialog.prototype = {
if (!aLocalFile || !aLocalFile.exists())
return null;
// Remove any leading periods, since we don't want to save hidden files
// automatically.
aLeafName = aLeafName.replace(/^\.+/, "");
if (aLeafName == "")
aLeafName = "unnamed" + (aFileExt ? "." + aFileExt : "");
aLocalFile.append(aLeafName);
@ -286,6 +290,7 @@ nsUnknownContentTypeDialog.prototype = {
f.remove(false);
this.makeFileUnique(aLocalFile);
}
return aLocalFile;
},
@ -490,7 +495,7 @@ nsUnknownContentTypeDialog.prototype = {
const nsITimer = Components.interfaces.nsITimer;
this._timer = Components.classes["@mozilla.org/timer;1"]
.createInstance(nsITimer);
this._timer.initWithCallback(this, 250, nsITimer.TYPE_ONE_SHOT);
this._timer.initWithCallback(this, 1000, nsITimer.TYPE_ONE_SHOT);
},
_timer: null,
@ -591,7 +596,7 @@ nsUnknownContentTypeDialog.prototype = {
this._blurred = false;
if (this._delayExpired) {
var script = "document.documentElement.getButton('accept').disabled = false";
this.mDialog.setTimeout(script, 250);
this.mDialog.setTimeout(script, 1000);
}
},

View File

@ -605,6 +605,11 @@ function Startup()
catch (e) {
if (window.arguments[0] == "updates-only") {
gUpdatesOnly = true;
#ifdef MOZ_PHOENIX
// If we are a browser when updating on startup don't display context
// menuitems that can open a browser window.
gUpdateContextMenus = gUpdateContextMenusNoBrowser;
#endif
document.getElementById("viewGroup").hidden = true;
document.getElementById("extensionsView").setAttribute("norestart", "");
showView("updates");
@ -1022,8 +1027,10 @@ var gAddonContextMenus = ["menuitem_useTheme", "menuitem_options", "menuitem_hom
"menuitem_cancelUninstall", "menuitem_checkUpdate",
"menuitem_enable", "menuitem_disable"];
var gUpdateContextMenus = ["menuitem_homepage", "menuitem_about", "menuseparator_1",
"menuitem_installUpdate", "menuitem_includeUpdate"]
var gInstallContextMenus = ["menuitem_homepage", "menuitem_about"]
"menuitem_installUpdate", "menuitem_includeUpdate"];
// For browsers don't display context menuitems that can open a browser window.
var gUpdateContextMenusNoBrowser = ["menuitem_installUpdate", "menuitem_includeUpdate"];
var gInstallContextMenus = ["menuitem_homepage", "menuitem_about"];
function buildContextMenu(aEvent)
{

View File

@ -78,6 +78,9 @@ const PREF_BLOCKLIST_DETAILS_URL = "extensions.blocklist.detailsURL";
const PREF_BLOCKLIST_ENABLED = "extensions.blocklist.enabled";
const PREF_BLOCKLIST_INTERVAL = "extensions.blocklist.interval";
const PREF_UPDATE_NOTIFYUSER = "extensions.update.notifyUser";
const PREF_GENERAL_USERAGENT_LOCALE = "general.useragent.locale";
const PREF_PARTNER_BRANCH = "app.partner.";
const PREF_APP_UPDATE_CHANNEL = "app.update.channel";
const DIR_EXTENSIONS = "extensions";
const DIR_CHROME = "chrome";
@ -166,6 +169,8 @@ var gPref = null;
var gRDF = null;
var gOS = null;
var gXPCOMABI = null;
var gABI = null;
var gOSVersion = null;
var gOSTarget = null;
var gConsole = null;
var gInstallManifestRoot = null;
@ -2328,6 +2333,60 @@ var StartupCache = {
}
};
/**
* Gets the current value of the locale. It's possible for this preference to
* be localized, so we have to do a little extra work here. Similar code
* exists in nsHttpHandler.cpp when building the UA string.
*/
function getLocale() {
try {
// Get the default branch
var defaultPrefs = gPref.QueryInterface(Components.interfaces.nsIPrefService)
.getDefaultBranch(null);
return defaultPrefs.getCharPref(PREF_GENERAL_USERAGENT_LOCALE);
} catch (e) {}
return gPref.getCharPref(PREF_GENERAL_USERAGENT_LOCALE);
}
/**
* Read the update channel from defaults only. We do this to ensure that
* the channel is tightly coupled with the application and does not apply
* to other installations of the application that may use the same profile.
*/
function getUpdateChannel() {
var channel = "default";
var prefName;
var prefValue;
var defaults =
gPref.QueryInterface(Components.interfaces.nsIPrefService).
getDefaultBranch(null);
try {
channel = defaults.getCharPref(PREF_APP_UPDATE_CHANNEL);
} catch (e) {
// use default when pref not found
}
try {
var partners = gPref.getChildList(PREF_PARTNER_BRANCH, { });
if (partners.length) {
channel += "-cck";
partners.sort();
for each (prefName in partners) {
prefValue = gPref.getCharPref(prefName);
channel += "-" + prefValue;
}
}
}
catch (e) {
Components.utils.reportError(e);
}
return channel;
}
/**
* Manages the Blocklist. The Blocklist is a representation of the contents of
* blocklist.xml and allows us to remotely disable / re-enable blocklisted
@ -2366,6 +2425,19 @@ var Blocklist = {
dsURI = dsURI.replace(/%APP_ID%/g, gApp.ID);
dsURI = dsURI.replace(/%APP_VERSION%/g, gApp.version);
dsURI = dsURI.replace(/%PRODUCT%/g, gApp.name);
dsURI = dsURI.replace(/%VERSION%/g, gApp.version);
dsURI = dsURI.replace(/%BUILD_ID%/g, gApp.appBuildID);
dsURI = dsURI.replace(/%BUILD_TARGET%/g, gApp.OS + "_" + gABI);
dsURI = dsURI.replace(/%OS_VERSION%/g, gOSVersion);
dsURI = dsURI.replace(/%LOCALE%/g, getLocale());
dsURI = dsURI.replace(/%CHANNEL%/g, getUpdateChannel());
dsURI = dsURI.replace(/%PLATFORM_VERSION%/g, gApp.platformVersion);
// Distribution values are not present in 1.8 branch
dsURI = dsURI.replace(/%DISTRIBUTION%/g, "default");
dsURI = dsURI.replace(/%DISTRIBUTION_VERSION%/g, "default");
dsURI = dsURI.replace(/\+/g, "%2B");
// Verify that the URI is valid
try {
var uri = newURI(dsURI);
@ -2658,6 +2730,38 @@ function ExtensionManager() {
// transmitted to update URLs.
gXPCOMABI = UNKNOWN_XPCOM_ABI;
}
gABI = gXPCOMABI;
var osVersion;
var sysInfo = Components.classes["@mozilla.org/system-info;1"]
.getService(Components.interfaces.nsIPropertyBag2);
try {
osVersion = sysInfo.getProperty("name") + " " + sysInfo.getProperty("version");
}
catch (e) {
LOG("ExtensionManager: OS Version unknown.");
}
if (osVersion) {
try {
osVersion += " (" + sysInfo.getProperty("secondaryLibrary") + ")";
}
catch (e) {
// Not all platforms have a secondary widget library, so an error is nothing to worry about.
}
gOSVersion = encodeURIComponent(osVersion);
}
#ifdef XP_MACOSX
// Mac universal build should report a different ABI than either macppc
// or mactel.
var macutils = Components.classes["@mozilla.org/xpcom/mac-utils;1"]
.getService(Components.interfaces.nsIMacUtils);
if (macutils.isUniversalBinary)
gABI = "Universal-gcc3";
#endif
gPref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch2);
@ -2981,6 +3085,12 @@ ExtensionManager.prototype = {
_installGlobalItem: function(file) {
if (!file || !file.exists())
throw new Error("Unable to find the file specified on the command line!");
#ifdef XP_WIN
// make sure the file is local on Windows
file.normalize();
if (file.path[1] != ':')
throw new Error("Can't install global chrome from non-local file "+file.path);
#endif
var installManifestFile = extractRDFFileToTempDir(file, FILE_INSTALL_MANIFEST, true);
if (!installManifestFile.exists())
throw new Error("The package is missing an install manifest!");
@ -3593,15 +3703,12 @@ ExtensionManager.prototype = {
items = PendingOperations.getOperations(OP_NEEDS_UPGRADE);
for (i = items.length - 1; i >= 0; --i) {
id = items[i].id;
var oldLocation = this.getInstallLocation(id);
var newLocation = InstallLocations.get(items[i].locationKey);
if (newLocation.priority <= oldLocation.priority) {
// check if there is updated app compatibility info
var newTargetAppInfo = ds.getUpdatedTargetAppInfo(id);
if (newTargetAppInfo)
updatedTargetAppInfos.push(newTargetAppInfo);
this._finalizeUpgrade(id);
}
// check if there is updated app compatibility info
var newTargetAppInfo = ds.getUpdatedTargetAppInfo(id);
if (newTargetAppInfo)
updatedTargetAppInfos.push(newTargetAppInfo);
this._finalizeUpgrade(id, newLocation);
}
PendingOperations.clearItems(OP_NEEDS_UPGRADE);
@ -4644,7 +4751,7 @@ ExtensionManager.prototype = {
this._upgradeItem(installManifest, installData.id, installLocation,
installData.type);
if (!restartRequired) {
this._finalizeUpgrade(installData.id);
this._finalizeUpgrade(installData.id, installLocation);
this._finalizeInstall(installData.id, stagedFile);
}
}
@ -4848,11 +4955,12 @@ ExtensionManager.prototype = {
* Removes an item's metadata in preparation for an upgrade-install.
* @param id
* The GUID of the item to uninstall.
* @param installLocation
* The nsIInstallLocation of the item
*/
_finalizeUpgrade: function(id) {
_finalizeUpgrade: function(id, installLocation) {
// Retrieve the item properties *BEFORE* we clean the resource!
var ds = this.datasource;
var installLocation = this.getInstallLocation(id);
var stagedFile = null;
if ("getStageFile" in installLocation)
@ -6132,12 +6240,15 @@ RDFItemUpdater.prototype = {
this._versionUpdateOnly = aVersionUpdateOnly;
this._item = aItem;
var itemStatus;
var itemStatus = "userEnabled";
if (emDS.getItemProperty(aItem.id, "userDisabled") == "true" ||
emDS.getItemProperty(aItem.id, "userDisabled") == OP_NEEDS_ENABLE)
itemStatus = "userDisabled";
else
itemStatus = "userEnabled";
else if (emDS.getItemProperty(aItem.id, "type") == nsIUpdateItem.TYPE_THEME) {
var currentSkin = gPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
if (emDS.getItemProperty(aItem.id, "internalName") != currentSkin)
itemStatus = "userDisabled";
}
if (emDS.getItemProperty(aItem.id, "compatible") == "false")
itemStatus += ",incompatible";
@ -6926,16 +7037,6 @@ ExtensionsDataSource.prototype = {
{
// Update the Extensions datasource
this.setTargetApplicationInfo(id, minVersion, maxVersion, null);
var installLocation = InstallLocations.get(this.getInstallLocationKey(id));
if (installLocation.name != KEY_APP_PROFILE)
return;
var installManifestFile = installLocation.getItemFile(id, FILE_INSTALL_MANIFEST);
// Only update if the item exists and we can write to the location
if (installManifestFile.exists() && installLocation.canAccess)
this.setTargetApplicationInfo(id, minVersion, maxVersion,
getInstallManifest(installManifestFile));
},
/**

View File

@ -59,6 +59,25 @@ endif
ifeq ($(OS_ARCH),OS2)
MOZ_PKG_PLATFORM := os2
endif
ifeq ($(OS_ARCH), BeOS)
ifeq (,$(filter-out 6.%, $(OS_RELEASE)))
MOZ_PKG_PLATFORM := Zeta
else
ifeq (,$(filter-out 5.1, $(OS_RELEASE)))
MOZ_PKG_PLATFORM := BeOS-bone
else
ifeq (,$(filter-out 5.0.4, $(OS_RELEASE)))
MOZ_PKG_PLATFORM := BeOS-bone
else
ifeq (,$(filter-out 5.0, $(OS_RELEASE)))
MOZ_PKG_PLATFORM := BeOS-net_server
else
MOZ_PKG_PLATFORM := BeOS-$(OS_RELEASE)
endif # 5.0
endif # 5.0.4
endif # 5.1
endif # 6.
endif # OS_ARCH BeOS
# GTK2 is the default, so we mark gtk1 builds
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk)

View File

@ -48,13 +48,15 @@ ifndef MOZ_PKG_FORMAT
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
MOZ_PKG_FORMAT = DMG
else
ifeq (,$(filter-out OS2 WINNT, $(OS_ARCH)))
ifeq (,$(filter-out OS2 WINNT BeOS, $(OS_ARCH)))
MOZ_PKG_FORMAT = ZIP
ifeq ($(OS_ARCH),OS2)
INSTALLER_DIR = os2
else
ifeq ($(OS_ARCH), WINNT)
INSTALLER_DIR = windows
endif
endif
else
ifeq (,$(filter-out SunOS, $(OS_ARCH)))
MOZ_PKG_FORMAT = BZ2
@ -125,8 +127,11 @@ _ABS_TOPSRCDIR = $(shell cd $(topsrcdir) && pwd)
ifdef UNIVERSAL_BINARY
STAGEPATH = universal/
endif
ifndef PKG_DMG_SOURCE
PKG_DMG_SOURCE = $(STAGEPATH)$(MOZ_PKG_APPNAME)
endif
MAKE_PACKAGE = $(_ABS_TOPSRCDIR)/build/package/mac_osx/pkg-dmg \
--source "$(STAGEPATH)$(MOZ_PKG_APPNAME)" --target "$(PACKAGE)" \
--source "$(PKG_DMG_SOURCE)" --target "$(PACKAGE)" \
--volname "$(MOZ_APP_DISPLAYNAME)" $(PKG_DMG_FLAGS)
UNMAKE_PACKAGE = \
set -ex; \

View File

@ -389,11 +389,11 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
!macroend
!macro GetParentDir
Exch $R0
Push $R1
Push $R2
Push $R3
StrLen $R3 $R0
Exch $R0
Push $R1
Push $R2
Push $R3
StrLen $R3 $R0
${DoWhile} 1 > 0
IntOp $R1 $R1 - 1
${If} $R1 <= -$R3
@ -744,6 +744,7 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
* to this reg cleanup since the referenced key would be for an app that is no
* longer installed on the system.
*
* $R1 = stores the long path to $INSTDIR
* $R2 = _KEY
* $R3 = value returned from the outer loop's EnumRegKey
* $R4 = value returned from the inner loop's EnumRegKey
@ -767,9 +768,11 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
Push $R5
Push $R6
Push $R7
Push $R1
Push $R8
Push $R9
${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R1
StrCpy $R6 0 ; set the counter for the outer loop to 0
outerloop:
@ -797,8 +800,9 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
${GetParentDir}
Pop $R9
IfFileExists "$R8" 0 +2
StrCmp $R9 $INSTDIR 0 innerloop
IfFileExists "$R9" 0 +3
${${_MOZFUNC_UN}GetLongPath} "$R9" $R9
StrCmp "$R9" "$R1" 0 innerloop
ClearErrors
DeleteRegKey SHCTX "$R2\$R3\$R4"
IfErrors innerloop
@ -815,8 +819,9 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
${GetParentDir}
Pop $R9
IfFileExists "$R8" 0 +2
StrCmp $R9 $INSTDIR 0 outerloop
IfFileExists "$R9" 0 +3
${${_MOZFUNC_UN}GetLongPath} "$R9" $R9
StrCmp "$R9" "$R1" 0 outerloop
ClearErrors
DeleteRegKey SHCTX "$R2\$R3"
IfErrors outerloop
@ -830,6 +835,7 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
Pop $R9
Pop $R8
Pop $R1
Pop $R7
Pop $R6
Pop $R5
@ -877,6 +883,7 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
* Removes all registry keys from HKLM\Software\Windows\CurrentVersion\Uninstall
* that reference this install location.
*
* $R4 = stores the long path to $INSTDIR
* $R5 = value returned from ReadRegStr
* $R6 = string for the base reg key (e.g. Software\Microsoft\Windows\CurrentVersion\Uninstall)
* $R7 = value returned from the EnumRegKey
@ -896,7 +903,9 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
Push $R7
Push $R6
Push $R5
Push $R4
${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R4
StrCpy $R6 "Software\Microsoft\Windows\CurrentVersion\Uninstall"
StrCpy $R8 0
StrCpy $R7 ""
@ -904,18 +913,19 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
loop:
EnumRegKey $R7 HKLM $R6 $R8
StrCmp $R7 "" end
IntOp $R8 $R8 + 1
IntOp $R8 $R8 + 1 ; Increment the counter
ClearErrors
ReadRegStr $R5 HKLM "$R6\$R7" "InstallLocation"
IfErrors loop
Push $R5
${GetPathFromRegStr}
Pop $R9
StrCmp $R9 $INSTDIR 0 loop
${${_MOZFUNC_UN}GetLongPath} "$R9" $R9
StrCmp "$R9" "$R4" 0 loop
ClearErrors
DeleteRegKey HKLM "$R6\$R7"
IfErrors loop
IntOp $R8 $R8 + 1
IntOp $R8 $R8 - 1 ; Decrement the counter on successful deletion
GoTo loop
end:
@ -1071,6 +1081,9 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
/**
* Writes a registry string using SHCTX and the supplied params and logs the
* action to the install log and the uninstall log if _LOG_UNINSTALL equals 1.
*
* Define NO_LOG to prevent all logging when calling this from the uninstaller.
*
* @param _ROOT
* The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.).
* This will only be used for logging.
@ -1176,6 +1189,9 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
/**
* Writes a registry dword using SHCTX and the supplied params and logs the
* action to the install log and the uninstall log if _LOG_UNINSTALL equals 1.
*
* Define NO_LOG to prevent all logging when calling this from the uninstaller.
*
* @param _ROOT
* The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.).
* This will only be used for logging.
@ -1281,6 +1297,9 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
/**
* Writes a registry string to HKCR using the supplied params and logs the
* action to the install log and the uninstall log if _LOG_UNINSTALL equals 1.
*
* Define NO_LOG to prevent all logging when calling this from the uninstaller.
*
* @param _ROOT
* The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.).
* This will only be used for logging.
@ -1399,6 +1418,9 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
* Creates a registry key. This will log the actions to the install and
* uninstall logs. Alternatively you can set a registry value to create the key
* and then delete the value.
*
* Define NO_LOG to prevent all logging when calling this from the uninstaller.
*
* @param _ROOT
* The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.).
* @param _KEY
@ -1613,6 +1635,117 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
!endif
!macroend
/**
* Finds an existing installation path of the application based on the
* application name so we can default to using this path for the install. If
* there is zero or more than one installation for the application then we
* default to the normal default path. This uses SHCTX to determine the
* registry hive so you must call SetShellVarContext first.
*
* IMPORTANT! $R9 will be overwritten by this macro with the return value so
* protect yourself!
*
* @param _KEY
* The registry subkey (typically this will be Software\Mozilla\App Name).
* @return _RESULT
* false if a single install location for this app name isn't found,
* path to the install directory if a single install location is found.
*
* $R5 = _KEY
* $R6 = value returned from EnumRegKey
* $R7 = value returned from ReadRegStr
* $R8 = counter for the loop's EnumRegKey
* $R9 = _RESULT
*/
!macro GetSingleInstallPath
!ifndef ${_MOZFUNC_UN}GetSingleInstallPath
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}GetSingleInstallPath "!insertmacro ${_MOZFUNC_UN}GetSingleInstallPathCall"
Function ${_MOZFUNC_UN}GetSingleInstallPath
Exch $R5
Push $R6
Push $R7
Push $R8
StrCpy $R9 "false"
StrCpy $R8 0 ; set the counter for the loop to 0
loop:
ClearErrors
EnumRegKey $R6 SHCTX $R5 $R8
IfErrors cleanup
StrCmp $R6 "" cleanup ; if empty there are no more keys to enumerate
IntOp $R8 $R8 + 1 ; increment the loop's counter
ClearErrors
ReadRegStr $R7 SHCTX "$R5\$R6\Main" "PathToExe"
IfErrors loop
GetFullPathName $R7 "$R7"
IfErrors loop
StrCmp "$R9" "false" 0 +3
StrCpy $R9 "$R7"
GoTo Loop
StrCpy $R9 "false"
cleanup:
StrCmp $R9 "false" end
${${_MOZFUNC_UN}GetParent} "$R9" $R9
StrCpy $R8 $R9 "" -1 ; Copy the last char.
StrCmp $R8 '\' end ; Is it a \?
StrCpy $R9 "$R9\" ; Append \ to the string
end:
ClearErrors
Pop $R8
Pop $R7
Pop $R6
Exch $R5
Push $R9
FunctionEnd
!verbose pop
!endif
!macroend
!macro GetSingleInstallPathCall _KEY _RESULT
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_KEY}"
Call GetSingleInstallPath
Pop ${_RESULT}
!verbose pop
!macroend
!macro un.GetSingleInstallPathCall _KEY _RESULT
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_KEY}"
Call un.GetSingleInstallPath
Pop ${_RESULT}
!verbose pop
!macroend
!macro un.GetSingleInstallPath
!ifndef un.GetSingleInstallPath
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!insertmacro GetSingleInstallPath
!undef _MOZFUNC_UN
!define _MOZFUNC_UN
!verbose pop
!endif
!macroend
/**
* Writes common registry values for a handler using SHCTX.
* @param _KEY
@ -1673,9 +1806,13 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
DeleteRegValue SHCTX "$R4" "EditFlags"
WriteRegDWord SHCTX "$R4" "EditFlags" 0x00000002
StrCmp "$R9" "true" 0 +13
StrCmp "$R6" "" +2 0
WriteRegStr SHCTX "$R4\DefaultIcon" "" "$R6"
StrCmp "$R5" "" +2 0
WriteRegStr SHCTX "$R4\shell\open\command" "" "$R5"
StrCmp "$R9" "true" 0 +11
WriteRegStr SHCTX "$R4\shell\open\ddeexec" "" "$\"%1$\",,0,0,,,,"
WriteRegStr SHCTX "$R4\shell\open\ddeexec" "NoActivateHandler" ""
WriteRegStr SHCTX "$R4\shell\open\ddeexec\Application" "" "${DDEApplication}"
@ -1749,54 +1886,471 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
!macroend
/**
* Displays a error message when a file can't be copied.
*
* $0 = file name inserted into the error message
*/
!macro DisplayCopyErrMsg
* Returns the path found within a passed in string. The path is quoted or not
* with the exception of an unquoted non 8dot3 path without arguments that is
* also not a DefaultIcon path, is a 8dot3 path or not, has command line
* arguments, or is a registry DefaultIcon path (e.g. <path to binary>,# where #
* is the icon's resuorce id). The string does not need to be a valid path or
* exist. It is up to the caller to pass in a string of one of the forms noted
* above and to verify existence if necessary.
*
* IMPORTANT! $R9 will be overwritten by this macro with the return value so
* protect yourself!
*
* Examples:
* In: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE -url "%1" -requestPending
* In: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE,0
* In: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE
* In: "C:\PROGRA~1\MOZILL~1\FIREFOX.EXE"
* In: "C:\PROGRA~1\MOZILL~1\FIREFOX.EXE" -url "%1" -requestPending
* Out: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE
*
* In: "C:\Program Files\Mozilla Firefox\firefox.exe" -url "%1" -requestPending
* In: C:\Program Files\Mozilla Firefox\firefox.exe,0
* In: "C:\Program Files\Mozilla Firefox\firefox.exe"
* Out: C:\Program Files\Mozilla Firefox\firefox.exe
*
* @param _STRING
* The string containing the path
* @param _RESULT
* The register to store the path to.
*
* $R6 = counter for the outer loop's EnumRegKey
* $R7 = value returned from ReadRegStr
* $R8 = _STRING
* $R9 = _RESULT
*/
!macro GetPathFromString
!ifndef ${_MOZFUNC_UN}DisplayCopyErrMsg
!ifndef ${_MOZFUNC_UN}GetPathFromString
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}DisplayCopyErrMsg "!insertmacro ${_MOZFUNC_UN}DisplayCopyErrMsgCall"
!define ${_MOZFUNC_UN}GetPathFromString "!insertmacro ${_MOZFUNC_UN}GetPathFromStringCall"
Function ${_MOZFUNC_UN}DisplayCopyErrMsg
Exch $0
Function ${_MOZFUNC_UN}GetPathFromString
Exch $R8
Push $R7
Push $R6
ClearErrors
MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$(^FileError_NoIgnore)" IDRETRY +2
Quit
StrCpy $R9 $R8
StrCpy $R6 0 ; Set the counter to 0.
Exch $0
ClearErrors
; Handle quoted paths with arguments.
StrCpy $R7 $R9 1 ; Copy the first char.
StrCmp $R7 '"' +2 +1 ; Is it a "?
StrCmp $R7 "'" +1 +9 ; Is it a '?
StrCpy $R9 $R9 "" 1 ; Remove the first char.
IntOp $R6 $R6 + 1 ; Increment the counter.
StrCpy $R7 $R9 1 $R6 ; Starting from the counter copy the next char.
StrCmp $R7 "" end ; Are there no more chars?
StrCmp $R7 '"' +2 +1 ; Is it a " char?
StrCmp $R7 "'" +1 -4 ; Is it a ' char?
StrCpy $R9 $R9 $R6 ; Copy chars up to the counter.
GoTo end
; Handle DefaultIcon paths. DefaultIcon paths are not quoted and end with
; a , and a number.
IntOp $R6 $R6 - 1 ; Decrement the counter.
StrCpy $R7 $R9 1 $R6 ; Copy one char from the end minus the counter.
StrCmp $R7 '' +4 ; Are there no more chars?
StrCmp $R7 ',' +1 -3 ; Is it a , char?
StrCpy $R9 $R9 $R6 ; Copy chars up to the end minus the counter.
GoTo end
; Handle unquoted paths with arguments. An unquoted path with arguments
; must be an 8dot3 path.
StrCpy $R6 -1 ; Set the counter to -1 so it will start at 0.
IntOp $R6 $R6 + 1 ; Increment the counter.
StrCpy $R7 $R9 1 $R6 ; Starting from the counter copy the next char.
StrCmp $R7 "" end ; Are there no more chars?
StrCmp $R7 " " +1 -3 ; Is it a space char?
StrCpy $R9 $R9 $R6 ; Copy chars up to the counter.
end:
Pop $R6
Pop $R7
Exch $R8
Push $R9
FunctionEnd
!verbose pop
!endif
!macroend
!macro DisplayCopyErrMsgCall _FILE
!macro GetPathFromStringCall _STRING _RESULT
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_FILE}"
Call DisplayCopyErrMsg
Push "${_STRING}"
Call GetPathFromString
Pop ${_RESULT}
!verbose pop
!macroend
!macro un.DisplayCopyErrMsgCall _FILE
!macro un.GetPathFromStringCall _STRING _RESULT
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_FILE}"
Call un.DisplayCopyErrMsg
Push "${_STRING}"
Call un.GetPathFromString
Pop ${_RESULT}
!verbose pop
!macroend
!macro un.DisplayCopyErrMsg
!ifndef un.DisplayCopyErrMsg
!macro un.GetPathFromString
!ifndef un.GetPathFromString
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!insertmacro DisplayCopyErrMsg
!insertmacro GetPathFromString
!undef _MOZFUNC_UN
!define _MOZFUNC_UN
!verbose pop
!endif
!macroend
/**
* If present removes the VirtualStore directory for this installation. Uses the
* program files directory path and the current install location to determine
* the sub-directory in the VirtualStore directory.
*/
!macro CleanVirtualStore
!ifndef ${_MOZFUNC_UN}CleanVirtualStore
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}CleanVirtualStore "!insertmacro ${_MOZFUNC_UN}CleanVirtualStoreCall"
Function ${_MOZFUNC_UN}CleanVirtualStore
Push $R9
Push $R8
Push $R7
StrLen $R9 "$INSTDIR"
; Get the installation's directory name including the preceding slash
start:
IntOp $R8 $R8 - 1
IntCmp $R8 -$R9 end end 0
StrCpy $R7 "$INSTDIR" 1 $R8
StrCmp $R7 "\" 0 start
StrCpy $R9 "$INSTDIR" "" $R8
ClearErrors
GetFullPathName $R8 "$PROGRAMFILES$R9"
IfErrors end
GetFullPathName $R7 "$INSTDIR"
; Compare the installation's directory path with the path created by
; concatenating the installation's directory name and the path to the
; program files directory.
StrCmp "$R7" "$R8" 0 end
StrCpy $R8 "$PROGRAMFILES" "" 2 ; Remove the drive letter and colon
StrCpy $R7 "$PROFILE\AppData\Local\VirtualStore$R8$R9"
IfFileExists "$R7" 0 end
RmDir /r "$R7"
end:
ClearErrors
Pop $R7
Pop $R8
Pop $R9
FunctionEnd
!verbose pop
!endif
!macroend
!macro CleanVirtualStoreCall
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Call CleanVirtualStore
!verbose pop
!macroend
!macro un.CleanVirtualStoreCall
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Call un.CleanVirtualStore
!verbose pop
!macroend
!macro un.CleanVirtualStore
!ifndef un.CleanVirtualStore
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!insertmacro CleanVirtualStore
!undef _MOZFUNC_UN
!define _MOZFUNC_UN
!verbose pop
!endif
!macroend
/**
* Updates the uninstall.log with new files added by software update.
*
* Requires FileJoin, LineFind, TextCompare, and TrimNewLines.
*
* IMPORTANT! The LineFind docs claim that it uses all registers except $R0-$R3.
* Though it appears that this is not true all registers besides
* $R0-$R3 may be overwritten so protect yourself!
*/
!macro UpdateUninstallLog
!ifndef ${_MOZFUNC_UN}UpdateUninstallLog
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}UpdateUninstallLog "!insertmacro ${_MOZFUNC_UN}UpdateUninstallLogCall"
Function ${_MOZFUNC_UN}UpdateUninstallLog
Push $R3
Push $R2
Push $R1
Push $R0
ClearErrors
GetFullPathName $R3 "$INSTDIR\uninstall"
IfFileExists "$R3\uninstall.update" +2 0
Return
${${_MOZFUNC_UN}LineFind} "$R3\uninstall.update" "" "1:-1" "${_MOZFUNC_UN}CleanupUpdateLog"
GetTempFileName $R2 "$R3"
FileOpen $R1 $R2 w
${${_MOZFUNC_UN}TextCompare} "$R3\uninstall.update" "$R3\uninstall.log" "SlowDiff" "${_MOZFUNC_UN}CreateUpdateDiff"
FileClose $R1
IfErrors +2 0
${${_MOZFUNC_UN}FileJoin} "$R3\uninstall.log" "$R2" "$R3\uninstall.log"
${DeleteFile} "$R2"
ClearErrors
Pop $R0
Pop $R1
Pop $R2
Pop $R3
FunctionEnd
; This callback MUST use labels vs. relative line numbers.
Function ${_MOZFUNC_UN}CleanupUpdateLog
StrCpy $R2 "$R9" 12
StrCmp "$R2" "EXECUTE ADD " 0 skip
StrCpy $R9 "$R9" "" 12
Push $R6
Push $R5
Push $R4
StrCpy $R4 "" ; Initialize to an empty string.
StrCpy $R6 -1 ; Set the counter to -1 so it will start at 0.
loop:
IntOp $R6 $R6 + 1 ; Increment the counter.
StrCpy $R5 $R9 1 $R6 ; Starting from the counter copy the next char.
StrCmp $R5 "" copy ; Are there no more chars?
StrCmp $R5 "/" 0 +2 ; Is the char a /?
StrCpy $R5 "\" ; Replace the char with a \.
StrCpy $R4 "$R4$R5"
GoTo loop
copy:
StrCpy $R9 "File: \$R4"
Pop $R6
Pop $R5
Pop $R4
GoTo end
skip:
StrCpy $0 "SkipWrite"
end:
Push $0
FunctionEnd
Function ${_MOZFUNC_UN}CreateUpdateDiff
${${_MOZFUNC_UN}TrimNewLines} "$9" "$9"
StrCmp $9 "" +2 0
FileWrite $R1 "$9$\r$\n"
Push 0
FunctionEnd
!verbose pop
!endif
!macroend
!macro UpdateUninstallLogCall
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Call UpdateUninstallLog
!verbose pop
!macroend
!macro un.UpdateUninstallLogCall
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Call un.UpdateUninstallLog
!verbose pop
!macroend
!macro un.UpdateUninstallLog
!ifndef un.UpdateUninstallLog
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!insertmacro UpdateUninstallLog
!undef _MOZFUNC_UN
!define _MOZFUNC_UN
!verbose pop
!endif
!macroend
/**
* Returns the long path for an existing file or directory. GetLongPathNameA
* may not be available on Win95 if Microsoft Layer for Unicode is not
* installed and GetFullPathName only returns a long path for the last file or
* directory that doesn't end with a \ in the path that it is passed. If the
* path does not exist on the file system this will return an empty string. To
* provide a consistent result trailing back-slashes are always removed.
*
* Note: 1024 used by GetLongPathNameA is the maximum NSIS string length.
*
* @param _IN_PATH
* The string containing the path.
* @param _OUT_PATH
* The register to store the long path.
*
* $R4 = counter value when the previous \ was found
* $R5 = directory or file name found during loop
* $R6 = return value from GetLongPathNameA and loop counter
* $R7 = long path from GetLongPathNameA and single char from path for comparison
* $R8 = _IN_PATH
* $R9 = _OUT_PATH
*/
!macro GetLongPath
!ifndef ${_MOZFUNC_UN}GetLongPath
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}GetLongPath "!insertmacro ${_MOZFUNC_UN}GetLongPathCall"
Function ${_MOZFUNC_UN}GetLongPath
Exch $R9
Exch 1
Exch $R8
Push $R7
Push $R6
Push $R5
Push $R4
ClearErrors
StrCpy $R9 ""
GetFullPathName $R8 "$R8"
IfErrors end_GetLongPath +1 ; If the path doesn't exist return an empty string.
; Remove trailing \'s from the path.
StrCpy $R6 "$R8" "" -1
StrCmp $R6 "\" +1 +2
StrCpy $R9 "$R8" -1
System::Call 'kernel32::GetLongPathNameA(t r18, t .r17, i 1024)i .r16'
StrCmp "$R7" "" +4 +1 ; Empty string when GetLongPathNameA is not present.
StrCmp $R6 0 +3 +1 ; Should never equal 0 since the path exists.
StrCpy $R9 "$R7"
GoTo end_GetLongPath
; Do it the hard way.
StrCpy $R4 0 ; Stores the position in the string of the last \ found.
StrCpy $R6 -1 ; Set the counter to -1 so it will start at 0.
loop_GetLongPath:
IntOp $R6 $R6 + 1 ; Increment the counter.
StrCpy $R7 $R8 1 $R6 ; Starting from the counter copy the next char.
StrCmp $R7 "" +2 ; Are there no more chars?
StrCmp $R7 "\" +1 -3 ; Is it a \?
; Copy chars starting from the previously found \ to the counter.
StrCpy $R5 $R8 $R6 $R4
; If this is the first \ found we want to swap R9 with R5 so a \ will
; be appended to the drive letter and colon (e.g. C: will become C:\).
StrCmp $R4 0 +1 +3
StrCpy $R9 $R5
StrCpy $R5 ""
GetFullPathName $R9 "$R9\$R5"
StrCmp $R7 "" end_GetLongPath ; Are there no more chars?
; Store the counter for the current \ and prefix it for StrCpy operations.
StrCpy $R4 "+$R6"
IntOp $R6 $R6 + 1 ; Increment the counter so we skip over the \.
StrCpy $R8 $R8 "" $R6 ; Copy chars starting from the counter to the end.
StrCpy $R6 -1 ; Reset the counter to -1 so it will start over at 0.
GoTo loop_GetLongPath
end_GetLongPath:
ClearErrors
Pop $R4
Pop $R5
Pop $R6
Pop $R7
Exch $R8
Exch 1
Exch $R9
FunctionEnd
!verbose pop
!endif
!macroend
!macro GetLongPathCall _IN_PATH _OUT_PATH
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_IN_PATH}"
Push "${_OUT_PATH}"
Call GetLongPath
Pop ${_OUT_PATH}
!verbose pop
!macroend
!macro un.GetLongPathCall _IN_PATH _OUT_PATH
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_IN_PATH}"
Push "${_OUT_PATH}"
Call un.GetLongPath
Pop ${_OUT_PATH}
!verbose pop
!macroend
!macro un.GetLongPath
!ifndef un.GetLongPath
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!insertmacro GetLongPath
!undef _MOZFUNC_UN
!define _MOZFUNC_UN

View File

@ -81,8 +81,8 @@ uninstaller::
$(INSTALL) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/setup.ico $(CONFIG_DIR)
cd $(CONFIG_DIR) && makensis.exe uninstaller.nsi
$(NSINSTALL) -D $(DIST)/bin/uninstall
ifdef MOZ_PHOENIX
cp $(CONFIG_DIR)/helper.exe $(DIST)/bin/uninstall
else
ifdef MOZ_SUNBIRD
cp $(CONFIG_DIR)/uninst.exe $(DIST)/bin/uninstall
else
cp $(CONFIG_DIR)/helper.exe $(DIST)/bin/uninstall
endif

View File

@ -13,4 +13,5 @@ VIAddVersionKey "CompanyName" "${CompanyName}"
VIAddVersionKey "LegalTrademarks" "${BrandShortName} is a Trademark of The Mozilla Foundation."
VIAddVersionKey "LegalCopyright" "${CompanyName}"
VIAddVersionKey "FileVersion" "${AppVersion}"
VIAddVersionKey "ProductVersion" "${AppVersion}"
;VIAddVersionKey "Comments" "Comments"

View File

@ -48,6 +48,7 @@ function nsRDFItemUpdater(aClientOS, aChromeLocale){
.getService(Components.interfaces.nsIXULAppInfo);
this.appID = app.ID;
this.buildID = app.platformBuildID;
this.appRelease = app.version;
this.clientOS = aClientOS;
this.chromeLocale = aChromeLocale;
@ -64,6 +65,7 @@ nsRDFItemUpdater.prototype = {
dsURI = dsURI.replace(/%PLUGIN_MIMETYPE%/g, encodeURIComponent(aPluginRequestItem.mimetype));
dsURI = dsURI.replace(/%APP_ID%/g, this.appID);
dsURI = dsURI.replace(/%APP_VERSION%/g, this.buildID);
dsURI = dsURI.replace(/%APP_RELEASE%/g, this.appRelease);
dsURI = dsURI.replace(/%CLIENT_OS%/g, this.clientOS);
dsURI = dsURI.replace(/%CHROME_LOCALE%/g, this.chromeLocale);
@ -109,27 +111,31 @@ nsRDFItemUpdater.prototype = {
target = child;
}
function getPFSValueFromRDF(aValue, aDatasource, aRDFService){
var rdfs = this._rdfService;
function getPFSValueFromRDF(aValue){
var rv = null;
var myTarget = aDatasource.GetTarget(target, aRDFService.GetResource(PFS_NS + aValue), true);
var myTarget = aDatasource.GetTarget(target, rdfs.GetResource(PFS_NS + aValue), true);
if (myTarget)
rv = myTarget.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
return rv;
}
pluginInfo = new Object();
pluginInfo.name = getPFSValueFromRDF("name", aDatasource, this._rdfService);
pluginInfo.pid = getPFSValueFromRDF("guid", aDatasource, this._rdfService);
pluginInfo.version = getPFSValueFromRDF("version", aDatasource, this._rdfService);
pluginInfo.IconUrl = getPFSValueFromRDF("IconUrl", aDatasource, this._rdfService);
pluginInfo.XPILocation = getPFSValueFromRDF("XPILocation", aDatasource, this._rdfService);
pluginInfo.InstallerShowsUI = getPFSValueFromRDF("InstallerShowsUI", aDatasource, this._rdfService);
pluginInfo.manualInstallationURL = getPFSValueFromRDF("manualInstallationURL", aDatasource, this._rdfService);
pluginInfo.requestedMimetype = getPFSValueFromRDF("requestedMimetype", aDatasource, this._rdfService);
pluginInfo.licenseURL = getPFSValueFromRDF("licenseURL", aDatasource, this._rdfService);
pluginInfo.needsRestart = getPFSValueFromRDF("needsRestart", aDatasource, this._rdfService);
pluginInfo = {
name: getPFSValueFromRDF("name"),
pid: getPFSValueFromRDF("guid"),
version: getPFSValueFromRDF("version"),
IconUrl: getPFSValueFromRDF("IconUrl"),
XPILocation: getPFSValueFromRDF("XPILocation"),
XPIHash: getPFSValueFromRDF("XPIHash"),
InstallerShowsUI: getPFSValueFromRDF("InstallerShowsUI"),
manualInstallationURL: getPFSValueFromRDF("manualInstallationURL"),
requestedMimetype: getPFSValueFromRDF("requestedMimetype"),
licenseURL: getPFSValueFromRDF("licenseURL"),
needsRestart: getPFSValueFromRDF("needsRestart")
};
}
catch (ex){}
}

View File

@ -43,12 +43,15 @@ var PluginInstallService = {
pluginPidArray: null,
startPluginInsallation: function (aPluginXPIUrlsArray, aPluginPidArray) {
startPluginInstallation: function (aPluginXPIUrlsArray,
aPluginHashes,
aPluginPidArray) {
this.pluginPidArray = aPluginPidArray;
var xpiManager = Components.classes["@mozilla.org/xpinstall/install-manager;1"]
.createInstance(Components.interfaces.nsIXPInstallManager);
xpiManager.initManagerFromChrome(aPluginXPIUrlsArray, aPluginXPIUrlsArray.length, this);
xpiManager.initManagerWithHashes(aPluginXPIUrlsArray, aPluginHashes,
aPluginXPIUrlsArray.length, this);
},
// XPI progress listener stuff

View File

@ -342,6 +342,7 @@ nsPluginInstallerWizard.prototype.startPluginInstallation = function (){
// mimetype. So store the pids.
var pluginURLArray = new Array();
var pluginHashArray = new Array();
var pluginPidArray = new Array();
for (pluginInfoItem in this.mPluginInfoArray){
@ -351,12 +352,15 @@ nsPluginInstallerWizard.prototype.startPluginInstallation = function (){
// will complain.
if (pluginItem.toBeInstalled && pluginItem.XPILocation && pluginItem.licenseAccepted) {
pluginURLArray.push(pluginItem.XPILocation);
pluginHashArray.push(pluginItem.XPIHash);
pluginPidArray.push(pluginItem.pid);
}
}
if (pluginURLArray.length > 0)
PluginInstallService.startPluginInsallation(pluginURLArray, pluginPidArray);
PluginInstallService.startPluginInstallation(pluginURLArray,
pluginHashArray,
pluginPidArray);
else
this.advancePage(null, true, false, false);
}
@ -554,7 +558,8 @@ nsPluginInstallerWizard.prototype.showPluginResults = function (){
"&appID=" + app.ID +
"&appVersion=" + app.platformBuildID +
"&clientOS=" + this.getOS() +
"&chromeLocale=" + this.getChromeLocale();
"&chromeLocale=" + this.getChromeLocale() +
"&appRelease=" + app.version;
document.getElementById("moreInfoLink").addEventListener("click", function() { gPluginInstaller.loadURL("https://pfs.mozilla.org/plugins/" + notInstalledList) }, false);
@ -617,6 +622,7 @@ function PluginInfo(aResult) {
this.version = aResult.version;
this.IconUrl = aResult.IconUrl;
this.XPILocation = aResult.XPILocation;
this.XPIHash = aResult.XPIHash;
this.InstallerShowsUI = aResult.InstallerShowsUI;
this.manualInstallationURL = aResult.manualInstallationURL;
this.requestedMimetype = aResult.requestedMimetype;

View File

@ -46,8 +46,7 @@ const URI_BRAND_PROPERTIES = "chrome://branding/locale/brand.properties";
const KEY_APPDIR = "XCurProcD";
const KEY_TMPDIR = "TmpD";
const KEY_LOCALDATA = "DefProfLRt";
const KEY_PROGRAMFILES = "ProgF";
const KEY_UPDROOT = "UpdRootD";
const KEY_UAPPDATA = "UAppData";
// see prio.h
@ -187,29 +186,15 @@ InstallLogWriter.prototype = {
// See the local appdata first if app dir is under Program Files.
var file = null;
var updRoot = getFile(KEY_APPDIR);
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
// Fallback to previous behavior since getting ProgF
// (e.g. KEY_PROGRAMFILES) may fail on Win9x.
try {
var programFilesDir = fileLocator.get(KEY_PROGRAMFILES,
Components.interfaces.nsILocalFile);
if (programFilesDir.contains(updRoot, true)) {
var relativePath = updRoot.QueryInterface(Components.interfaces.nsILocalFile).
getRelativeDescriptor(programFilesDir);
var userLocalDir = fileLocator.get(KEY_LOCALDATA,
Components.interfaces.nsILocalFile).parent;
updRoot.setRelativeDescriptor(userLocalDir, relativePath);
file = appendUpdateLogPath(updRoot);
file = appendUpdateLogPath(getFile(KEY_UPDROOT));
// When updating from Fx 2.0.0.1 to 2.0.0.3 (or later) on Vista,
// we will have to see also user app data (see bug 351949).
if (!file)
file = appendUpdateLogPath(getFile(KEY_UAPPDATA));
}
// When updating from Fx 2.0.0.1 to 2.0.0.3 (or later) on Vista,
// we will have to see also user app data (see bug 351949).
if (!file)
file = appendUpdateLogPath(getFile(KEY_UAPPDATA));
} catch (e) {
}
catch (e) {}
// See the app dir if not found or app dir is out of Program Files.
if (!file)
@ -540,12 +525,15 @@ function haveOldInstall(key, brandFullName, version) {
function checkRegistry()
{
// XXX todo
// this is firefox specific
// figure out what to do about tbird and sunbird, etc
LOG("checkRegistry");
var result = false;
// Firefox is the only toolkit app that needs to do this.
// return false for other applications.
var app = Components.classes["@mozilla.org/xre/app-info;1"].
getService(Components.interfaces.nsIXULAppInfo);
if (app.name == "Firefox") {
try {
var key = new RegKey();
key.open(RegKey.prototype.ROOT_KEY_CLASSES_ROOT, "FirefoxHTML\\shell\\open\\command", key.ACCESS_READ);
@ -557,6 +545,7 @@ function checkRegistry()
LOG("failed to open command key for FirefoxHTML: " + e);
}
key.close();
}
return result;
}
@ -605,6 +594,16 @@ nsPostUpdateWin.prototype = {
},
run: function() {
// When uninstall/uninstall.update exists the uninstaller has already
// updated the uninstall.log with the files added by software update.
var updateUninstallFile = getFile(KEY_APPDIR);
updateUninstallFile.append("uninstall");
updateUninstallFile.append("uninstall.update");
if (updateUninstallFile.exists()) {
LOG("nothing to do, uninstall.log has already been updated");
return;
}
try {
installLogWriter = new InstallLogWriter();
try {

View File

@ -67,8 +67,7 @@ const URI_UPDATE_NS = "http://www.mozilla.org/2005/app-update";
const KEY_APPDIR = "XCurProcD";
#ifdef XP_WIN
const KEY_LOCALDATA = "DefProfLRt";
const KEY_PROGRAMFILES = "ProgF";
const KEY_UPDROOT = "UpdRootD";
const KEY_UAPPDATA = "UAppData";
#endif
@ -238,22 +237,13 @@ function getUpdateDir(pathArray) {
function getDirInternal(key, pathArray, shouldCreate, update) {
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
var dir = fileLocator.get(key, Components.interfaces.nsILocalFile);
var dir = fileLocator.get(key, Components.interfaces.nsIFile);
#ifdef XP_WIN
if (update) {
// Fallback to previous behavior since getting ProgF
// (e.g. KEY_PROGRAMFILES) may fail on Win9x.
try {
var programFilesDir = fileLocator.get(KEY_PROGRAMFILES,
Components.interfaces.nsILocalFile);
if (programFilesDir.contains(dir, true)) {
var relativePath = dir.getRelativeDescriptor(programFilesDir);
var userLocalDir = fileLocator.get(KEY_LOCALDATA,
Components.interfaces.nsILocalFile).parent;
dir.setRelativeDescriptor(userLocalDir, relativePath);
}
dir = fileLocator.get(KEY_UPDROOT, Components.interfaces.nsIFile);
} catch (e) {
}
catch (e) {}
}
#endif
for (var i = 0; i < pathArray.length; ++i) {
@ -283,7 +273,7 @@ function getFile(key, pathArray) {
}
/**
* Gets the file at the speciifed hierarchy under the update root directory.
* Gets the file at the specified hierarchy under the update root directory.
* @param pathArray
* An array of path components to locate beneath the directory
* specified by |key|. The last item in this array must be the
@ -358,23 +348,14 @@ function getUpdatesDir(key) {
getService(Components.interfaces.nsIProperties);
var appDir;
if (key)
appDir = fileLocator.get(key, Components.interfaces.nsILocalFile);
appDir = fileLocator.get(key, Components.interfaces.nsIFile);
else {
appDir = fileLocator.get(KEY_APPDIR, Components.interfaces.nsILocalFile);
appDir = fileLocator.get(KEY_APPDIR, Components.interfaces.nsIFile);
#ifdef XP_WIN
// Fallback to previous behavior since getting ProgF
// (e.g. KEY_PROGRAMFILES) may fail on Win9x.
try {
var programFilesDir = fileLocator.get(KEY_PROGRAMFILES,
Components.interfaces.nsILocalFile);
if (programFilesDir.contains(appDir, true)) {
var relativePath = appDir.getRelativeDescriptor(programFilesDir);
var userLocalDir = fileLocator.get(KEY_LOCALDATA,
Components.interfaces.nsILocalFile).parent;
appDir.setRelativeDescriptor(userLocalDir, relativePath);
}
appDir = fileLocator.get(KEY_UPDROOT, Components.interfaces.nsIFile);
} catch (e) {
}
catch (e) {}
#endif
}
appDir.append(DIR_UPDATES);
@ -512,8 +493,11 @@ function getPref(func, preference, defaultValue) {
*/
function getLocale() {
try {
return gPref.getComplexValue(PREF_GENERAL_USERAGENT_LOCALE,
nsIPrefLocalizedString).data;
// Get the default branch
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
var defaultPrefs = prefs.getDefaultBranch(null);
return defaultPrefs.getCharPref(PREF_GENERAL_USERAGENT_LOCALE);
} catch (e) {}
return gPref.getCharPref(PREF_GENERAL_USERAGENT_LOCALE);
@ -1018,18 +1002,27 @@ function UpdateService() {
LOG("UpdateService", "XPCOM ABI unknown: updates are not possible.");
}
try {
var sysInfo =
Components.classes["@mozilla.org/system-info;1"]
.getService(Components.interfaces.nsIPropertyBag2);
var osVersion;
var sysInfo = Components.classes["@mozilla.org/system-info;1"]
.getService(Components.interfaces.nsIPropertyBag2);
gOSVersion = encodeURIComponent(sysInfo.getProperty("name") + " " +
sysInfo.getProperty("version"));
try {
osVersion = sysInfo.getProperty("name") + " " + sysInfo.getProperty("version");
}
catch (e) {
LOG("UpdateService", "OS Version unknown: updates are not possible.");
}
if (osVersion) {
try {
osVersion += " (" + sysInfo.getProperty("secondaryLibrary") + ")";
}
catch (e) {
// Not all platforms have a secondary widget library, so an error is nothing to worry about.
}
gOSVersion = encodeURIComponent(osVersion);
}
#ifdef XP_MACOSX
// Mac universal build should report a different ABI than either macppc
// or mactel.
@ -1199,12 +1192,10 @@ UpdateService.prototype = {
LOG("UpdateService", "_postUpdateProcessing: Install Succeeded, Showing UI");
prompter.showUpdateInstalled(update);
#ifdef MOZ_PHOENIX
// for now, this is firefox only.
#ifdef MOZ_SUNBIRD
// we need to fix both nsPostUpdateWin.js and
// the uninstaller to work for thunderbird and sunbird
//
// the uninstaller to work for sunbird
#else
// Perform platform-specific post-update processing.
if (POST_UPDATE_CONTRACTID in Components.classes) {
Components.classes[POST_UPDATE_CONTRACTID].
@ -1519,6 +1510,7 @@ UpdateService.prototype = {
get canUpdate() {
try {
var appDirFile = getUpdateFile([FILE_PERMS_TEST]);
LOG("UpdateService", "canUpdate? testing " + appDirFile.path);
if (!appDirFile.exists()) {
appDirFile.create(nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
appDirFile.remove(false);
@ -1526,12 +1518,45 @@ UpdateService.prototype = {
var updateDir = getUpdatesDir();
var upDirFile = updateDir.clone();
upDirFile.append(FILE_PERMS_TEST);
LOG("UpdateService", "canUpdate? testing " + upDirFile.path);
if (!upDirFile.exists()) {
upDirFile.create(nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
upDirFile.remove(false);
}
#ifdef XP_WIN
var sysInfo =
Components.classes["@mozilla.org/system-info;1"]
.getService(Components.interfaces.nsIPropertyBag2);
// On Windows, we no longer store the update under the app dir
// if the app dir is under C:\Program Files.
//
// If we are on Windows, but not Vista, we need to check that
// we can create and remove files from the actual app directory
// (like C:\Program Files\Mozilla Firefox). If we can't,
// because this user is not an adminstrator, for example
// canUpdate() should return false (like it used to).
//
// For Vista, don't perform this check because non-admin users
// can update firefox (by granting the updater access via the
// UAC prompt)
var windowsVersion = sysInfo.getProperty("version");
LOG("UpdateService", "canUpdate? version = " + windowsVersion);
// Example windowsVersion: Windows XP == 5.1
if (parseFloat(windowsVersion) < 6) {
var actualAppDir = getDir(KEY_APPDIR, []);
var actualAppDirFile = actualAppDir.clone();
actualAppDirFile.append(FILE_PERMS_TEST);
LOG("UpdateService", "canUpdate? testing " + actualAppDirFile.path);
if (!actualAppDirFile.exists()) {
actualAppDirFile.create(nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
actualAppDirFile.remove(false);
}
}
#endif
}
catch (e) {
LOG("UpdateService", "can't update, no privileges: " + e);
// No write privileges to install directory
return false;
}
@ -1539,17 +1564,24 @@ UpdateService.prototype = {
// OFF - this is not just a user setting, so disable the manual
// UI too.
var enabled = getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true);
if (!enabled && gPref.prefIsLocked(PREF_APP_UPDATE_ENABLED))
if (!enabled && gPref.prefIsLocked(PREF_APP_UPDATE_ENABLED)) {
LOG("UpdateService", "can't update, disabled by pref");
return false;
}
// If we don't know the binary platform we're updating, we can't update.
if (!gABI)
if (!gABI) {
LOG("UpdateService", "can't update, unknown ABI");
return false;
}
// If we don't know the OS version we're updating, we can't update.
if (!gOSVersion)
if (!gOSVersion) {
LOG("UpdateService", "can't update, unknown OS version");
return false;
}
LOG("UpdateService", "can update");
return true;
},
@ -1860,7 +1892,9 @@ Checker.prototype = {
* The URL of the update service XML file to connect to that contains details
* about available updates.
*/
get updateURL() {
getUpdateURL: function(force) {
this._forced = force;
var defaults =
gPref.QueryInterface(Components.interfaces.nsIPrefService).
getDefaultBranch(null);
@ -1890,6 +1924,9 @@ Checker.prototype = {
url = url.replace(/%CHANNEL%/g, getUpdateChannel());
url = url.replace(/\+/g, "%2B");
if (force)
url += "?force=1"
LOG("Checker", "update url: " + url);
return url;
},
@ -1901,13 +1938,13 @@ Checker.prototype = {
if (!listener)
throw Components.results.NS_ERROR_NULL_POINTER;
if (!this.updateURL || (!this.enabled && !force))
if (!this.getUpdateURL(force) || (!this.enabled && !force))
return;
this._request =
Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].
createInstance(Components.interfaces.nsIXMLHttpRequest);
this._request.open("GET", this.updateURL, true);
this._request.open("GET", this.getUpdateURL(force), true);
this._request.channel.notificationCallbacks = new BadCertHandler();
this._request.overrideMimeType("text/xml");
this._request.setRequestHeader("Cache-Control", "no-cache");
@ -1917,7 +1954,7 @@ Checker.prototype = {
this._request.onload = function(event) { self.onLoad(event); };
this._request.onprogress = function(event) { self.onProgress(event); };
LOG("Checker", "checkForUpdates: sending request to " + this.updateURL);
LOG("Checker", "checkForUpdates: sending request to " + this.getUpdateURL(force));
this._request.send(null);
this._callback = listener;
@ -1962,7 +1999,7 @@ Checker.prototype = {
LOG("Checker", "Invalid <update/>, ignoring...");
continue;
}
update.serviceURL = this.updateURL;
update.serviceURL = this.getUpdateURL(this._forced);
update.channel = getUpdateChannel();
updates.push(update);
}

View File

@ -110,6 +110,11 @@ ArchiveReader::ExtractItemToStream(const MarItem *item, FILE *fp)
offset = 0;
for (;;) {
if (!item->length) {
ret = UNEXPECTED_ERROR;
break;
}
if (offset < (int) item->length && strm.avail_in == 0) {
inlen = mar_read(mArchive, item, offset, inbuf, BUFSIZ);
if (inlen <= 0)

View File

@ -1,4 +1,4 @@
/* Localized versions of Info.plist keys */
CFBundleName = "@APP_NAME@ Software Update";
NSHumanReadableCopyright = "Copyright © 2005-2007 Mozilla Foundation";
NSHumanReadableCopyright = "Copyright © 2005-2008 Mozilla Foundation";

View File

@ -47,6 +47,26 @@
#define TIMER_ID 1
#define TIMER_INTERVAL 100
#define MAX_INFO_LENGTH 512
#define RESIZE_WINDOW(hwnd, extrax, extray) \
{ \
RECT windowSize; \
GetWindowRect(hwnd, &windowSize); \
SetWindowPos(hwnd, 0, 0, 0, windowSize.right - windowSize.left + extrax, \
windowSize.bottom - windowSize.top + extray, \
SWP_NOMOVE | SWP_NOZORDER); \
}
#define MOVE_WINDOW(hwnd, dx, dy) \
{ \
WINDOWPLACEMENT windowPos; \
windowPos.length = sizeof(windowPos); \
GetWindowPlacement(hwnd, &windowPos); \
SetWindowPos(hwnd, 0, windowPos.rcNormalPosition.left + dx, windowPos.rcNormalPosition.top + dy, 0, 0, \
SWP_NOSIZE | SWP_NOZORDER); \
}
static float sProgress; // between 0 and 100
static BOOL sQuit = FALSE;
static HFONT sSystemFont = 0;
@ -72,6 +92,52 @@ UpdateDialog(HWND hDlg)
SendDlgItemMessage(hDlg, IDC_PROGRESS, PBM_SETPOS, pos, 0L);
}
static void
ResizeDialogToFit(HWND hDlg)
{
char text[MAX_INFO_LENGTH];
RECT infoSize, textSize;
HFONT hInfoFont, hOldFont;
HWND hWndInfo = GetDlgItem(hDlg, IDC_INFO);
HWND hWndPro = GetDlgItem(hDlg, IDC_PROGRESS);
// Get the text that is displayed - this is what we're going to make fit.
if (!GetWindowText(hWndInfo, text, sizeof(text)))
return;
// We need the current size and font to calculate the adjustment.
GetClientRect(hWndInfo, &infoSize);
HDC hDCInfo = GetDC(hWndInfo);
hInfoFont = (HFONT)SendMessage(hWndInfo, WM_GETFONT, 0, 0);
if (hInfoFont)
hOldFont = (HFONT)SelectObject(hDCInfo, hInfoFont);
// Measure the space needed for the text - DT_CALCRECT means nothing is drawn.
if (DrawText(hDCInfo, text, -1, &textSize,
DT_CALCRECT | DT_NOCLIP | DT_SINGLELINE)) {
SIZE extra;
extra.cx = (textSize.right - textSize.left) - (infoSize.right - infoSize.left);
extra.cy = (textSize.bottom - textSize.top) - (infoSize.bottom - infoSize.top);
if (extra.cx < 0)
extra.cx = 0;
if (extra.cy < 0)
extra.cy = 0;
if ((extra.cx > 0) || (extra.cy > 0)) {
RESIZE_WINDOW(hDlg, extra.cx, extra.cy);
RESIZE_WINDOW(hWndInfo, extra.cx, extra.cy);
RESIZE_WINDOW(hWndPro, extra.cx, 0);
MOVE_WINDOW(hWndPro, 0, extra.cy);
}
}
if (hOldFont)
SelectObject(hDCInfo, hOldFont);
ReleaseDC(hWndInfo, hDCInfo);
}
// The code in this function is from MSDN:
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/dialogboxes/usingdialogboxes.asp
static void
@ -109,7 +175,7 @@ CenterDialog(HWND hDlg)
static void
SetItemText(HWND hwnd, const char *key, const char *ini)
{
char text[512];
char text[MAX_INFO_LENGTH];
if (!GetPrivateProfileString("Strings", key, NULL, text, sizeof(text), ini))
return;
SetWindowText(hwnd, text);
@ -147,6 +213,9 @@ InitDialog(HWND hDlg)
SendDlgItemMessage(hDlg, IDC_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
// Resize dialog to fit all the text.
ResizeDialogToFit(hDlg);
CenterDialog(hDlg); // make dialog appear in the center of the screen
SetTimer(hDlg, TIMER_ID, TIMER_INTERVAL, NULL);

View File

@ -245,11 +245,10 @@ public:
return 0;
}
private:
static unsigned ThreadMain(void *p)
static void ThreadMain(void *p)
{
Thread *self = (Thread *) p;
self->mThreadFunc(self->mThreadParam);
return 0;
}
int mThread;
ThreadFunc mThreadFunc;
@ -264,6 +263,9 @@ private:
static char* gSourcePath;
static ArchiveReader gArchiveReader;
#ifdef XP_WIN
static bool gSucceeded = FALSE;
#endif
static const char kWhitespace[] = " \t";
static const char kNL[] = "\r\n";
@ -1007,6 +1009,61 @@ PatchIfFile::Finish(int status)
#ifdef XP_WIN
#include "nsWindowsRestart.cpp"
static void
LaunchWinPostProcess(const char *appExe)
{
// Launch helper.exe to perform post processing (e.g. registry and log file
// modifications) for the update.
char inifile[MAXPATHLEN];
strcpy(inifile, appExe);
char *slash = strrchr(inifile, '\\');
if (!slash)
return;
strcpy(slash + 1, "updater.ini");
char exefile[MAXPATHLEN];
char exearg[MAXPATHLEN];
if (!GetPrivateProfileString("PostUpdateWin", "ExeRelPath", NULL, exefile,
sizeof(exefile), inifile))
return;
if (!GetPrivateProfileString("PostUpdateWin", "ExeArg", NULL, exearg,
sizeof(exearg), inifile))
return;
char exefullpath[MAXPATHLEN];
strcpy(exefullpath, appExe);
slash = strrchr(exefullpath, '\\');
strcpy(slash + 1, exefile);
char dlogFile[MAXPATHLEN];
strcpy(dlogFile, exefullpath);
slash = strrchr(dlogFile, '\\');
strcpy(slash + 1, "uninstall.update");
char slogFile[MAXPATHLEN];
snprintf(slogFile, MAXPATHLEN, "%s/update.log", gSourcePath);
// We want to launch the post update helper app to update the Windows
// registry even if there is a failure with removing the uninstall.update
// file or copying the update.log file.
ensure_remove(dlogFile);
copy_file(slogFile, dlogFile);
static int argc = 2;
static char **argv = (char**) malloc(sizeof(char*) * (argc + 1));
argv[0] = "argv0ignoredbywinlaunchchild";
argv[1] = exearg;
argv[2] = "\0";
WinLaunchChild(exefullpath, argc, argv, 1);
free(argv);
}
#endif
static void
@ -1129,6 +1186,11 @@ int main(int argc, char **argv)
LogFinish();
#ifdef XP_WIN
if (gSucceeded && argc > 4)
LaunchWinPostProcess(argv[4]);
#endif
// The callback to execute is given as the last N arguments of our command
// line. The first of those arguments specifies the working directory for
// the callback.
@ -1234,6 +1296,11 @@ ActionList::Finish(int status)
a = a->mNext;
}
#ifdef XP_WIN
if (status == OK)
gSucceeded = TRUE;
#endif
UpdateProgressUI(100.0f);
}

View File

@ -13,6 +13,10 @@ classic.jar:
+ skin/classic/global/arrow/arrow-dn-dis.gif (arrow/arrow-dn-dis.gif)
+ skin/classic/global/arrow/arrow-lft-dis.gif (arrow/arrow-lft-dis.gif)
+ skin/classic/global/arrow/arrow-rit-dis.gif (arrow/arrow-rit-dis.gif)
+ skin/classic/global/arrow/arrow-up-hov.gif (arrow/arrow-up.gif)
+ skin/classic/global/arrow/arrow-dn-hov.gif (arrow/arrow-dn.gif)
+ skin/classic/global/arrow/arrow-lft-hov.gif (arrow/arrow-lft.gif)
+ skin/classic/global/arrow/arrow-rit-hov.gif (arrow/arrow-rit.gif)
+ skin/classic/global/arrow/thumb-vrt.gif (arrow/thumb-vrt.gif)
+ skin/classic/global/arrow/thumb-hrz.gif (arrow/thumb-hrz.gif)
+ skin/classic/global/browser.css

View File

@ -40,6 +40,10 @@
*
* ***** END LICENSE BLOCK ***** */
#if defined(XP_OS2) && defined(MOZ_OS2_HIGH_MEMORY)
// os2safe.h has to be included before os2.h, needed for high mem
#include <os2safe.h>
#endif
#define XPCOM_TRANSLATE_NSGM_ENTRY_POINT 1
@ -306,6 +310,12 @@ strimatch(const char* lowerstr, const char* mixedstr)
return PR_TRUE;
}
enum RemoteResult {
REMOTE_NOT_FOUND = 0,
REMOTE_FOUND = 1,
REMOTE_ARG_BAD = 2
};
enum ArgResult {
ARG_NONE = 0,
ARG_FOUND = 1,
@ -328,13 +338,16 @@ static void RemoveArg(char **argv)
* --arg (or /arg on win32/OS2).
*
* @param aArg the parameter to check. Must be lowercase.
* @param aCheckOSInt if true returns ARG_BAD if the osint argument is present
* when aArg is also present.
* @param if non-null, the -arg <data> will be stored in this pointer. This is *not*
* allocated, but rather a pointer to the argv data.
*/
static ArgResult
CheckArg(const char* aArg, const char **aParam = nsnull)
CheckArg(const char* aArg, PRBool aCheckOSInt = PR_FALSE, const char **aParam = nsnull)
{
char **curarg = gArgv + 1; // skip argv[0]
ArgResult ar = ARG_NONE;
while (*curarg) {
char *arg = curarg[0];
@ -351,7 +364,8 @@ CheckArg(const char* aArg, const char **aParam = nsnull)
if (strimatch(aArg, arg)) {
RemoveArg(curarg);
if (!aParam) {
return ARG_FOUND;
ar = ARG_FOUND;
break;
}
if (*curarg) {
@ -364,7 +378,8 @@ CheckArg(const char* aArg, const char **aParam = nsnull)
*aParam = *curarg;
RemoveArg(curarg);
return ARG_FOUND;
ar = ARG_FOUND;
break;
}
return ARG_BAD;
}
@ -373,7 +388,15 @@ CheckArg(const char* aArg, const char **aParam = nsnull)
++curarg;
}
return ARG_NONE;
if (aCheckOSInt && ar == ARG_FOUND) {
ArgResult arOSInt = CheckArg("osint");
if (arOSInt == ARG_FOUND) {
ar = ARG_BAD;
PR_fprintf(PR_STDERR, "Error: argument -osint is invalid\n");
}
}
return ar;
}
#if defined(XP_WIN)
@ -1115,14 +1138,14 @@ HandleRemoteArgument(const char* remote)
ToLowerCase(program);
const char *username = getenv("LOGNAME");
ar = CheckArg("p", &profile);
ar = CheckArg("p", PR_FALSE, &profile);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -p requires a profile name\n");
return 1;
}
const char *temp = nsnull;
ar = CheckArg("a", &temp);
ar = CheckArg("a", PR_FALSE, &temp);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -a requires an application name\n");
return 1;
@ -1130,7 +1153,7 @@ HandleRemoteArgument(const char* remote)
program.Assign(temp);
}
ar = CheckArg("u", &username);
ar = CheckArg("u", PR_FALSE, &username);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -u requires a username\n");
return 1;
@ -1162,7 +1185,7 @@ HandleRemoteArgument(const char* remote)
return 0;
}
static PRBool
static RemoteResult
RemoteCommandLine()
{
nsresult rv;
@ -1173,24 +1196,24 @@ RemoteCommandLine()
const char *username = getenv("LOGNAME");
const char *temp = nsnull;
ar = CheckArg("a", &temp);
ar = CheckArg("a", PR_TRUE, &temp);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -a requires an application name\n");
return PR_FALSE;
return REMOTE_ARG_BAD;
} else if (ar == ARG_FOUND) {
program.Assign(temp);
}
ar = CheckArg("u", &username);
ar = CheckArg("u", PR_TRUE, &username);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -u requires a username\n");
return PR_FALSE;
return REMOTE_ARG_BAD;
}
XRemoteClient client;
rv = client.Init();
if (NS_FAILED(rv))
return PR_FALSE;
return REMOTE_NOT_FOUND;
nsXPIDLCString response;
PRBool success = PR_FALSE;
@ -1199,9 +1222,9 @@ RemoteCommandLine()
getter_Copies(response), &success);
// did the command fail?
if (NS_FAILED(rv) || !success)
return PR_FALSE;
return REMOTE_NOT_FOUND;
return PR_TRUE;
return REMOTE_FOUND;
}
#endif // MOZ_ENABLE_XREMOTE
@ -1355,33 +1378,98 @@ XRE_GetBinaryPath(const char* argv0, nsILocalFile* *aResult)
return NS_OK;
}
// copied from nsXREDirProvider.cpp
#ifdef XP_WIN
static nsresult
GetShellFolderPath(int folder, char result[MAXPATHLEN])
{
LPITEMIDLIST pItemIDList = NULL;
nsresult rv;
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, folder, &pItemIDList)) &&
SUCCEEDED(SHGetPathFromIDList(pItemIDList, result))) {
rv = NS_OK;
} else {
rv = NS_ERROR_NOT_AVAILABLE;
}
CoTaskMemFree(pItemIDList);
return rv;
}
#endif
#define NS_ERROR_LAUNCHED_CHILD_PROCESS NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PROFILE, 200)
#ifdef XP_WIN
#include "nsWindowsRestart.cpp"
#endif
#if defined(XP_OS2) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3) // broken OS/2 GCC
// Copy the environment maintained by the C library into an ASCIIZ array
// that can be used to pass it on to the OS/2 Dos* APIs (which otherwise
// don't know anything about the stuff set by PR_SetEnv() or setenv()).
char *createEnv()
{
// just allocate the maximum amount (24 kB = 0x60000 bytes), to be able to
// copy the existing environment
char *env = (char *)calloc(0x6000, sizeof(char));
if (!env) {
return NULL;
}
// walk along the environ string array of the C library and copy
// everything (that fits) into the output environment array, leaving
// null bytes between the entries
char *penv = env; // movable pointer to result environment ASCIIZ array
int i = 0, space = 0x6000;
while (environ[i] && environ[i][0]) {
int len = strlen(environ[i]);
if (space - len <= 0) {
break;
}
strcpy(penv, environ[i]);
i++; // next environment variable
penv += len + 1; // jump to after next null byte
space -= len - 1; // subtract consumed length from usable space
}
return env;
}
// OS2LaunchChild() is there to replace _execv() which is broken in the C
// runtime library that comes with GCC 3.3.5 on OS/2. It uses createEnv()
// to copy the process environment and add necessary variables
//
// returns -1 on failure and 0 on success
int OS2LaunchChild(const char *aExePath, int aArgc, char **aArgv)
{
// find total length of aArgv
int len = 0;
for (int i = 0; i < aArgc; i++) {
len += strlen(aArgv[i]) + 1; // plus space in between
}
len++; // leave space for null byte at end
// allocate enough space for all strings and nulls,
// calloc helpfully initializes to null
char *args = (char *)calloc(len, sizeof(char));
if (!args) {
return -1;
}
char *pargs = args; // extra pointer to after the last argument
// build argument list in the format the DosStartSession() wants,
// adding spaces between the arguments
for (int i = 0; i < aArgc; i++, *pargs++ = ' ') {
strcpy(pargs, aArgv[i]);
pargs += strlen(aArgv[i]);
}
if (aArgc > 1) {
*(pargs-1) = '\0'; // replace last space
}
*pargs = '\0';
// make sure that the program is separated by null byte
pargs = strchr(args, ' ');
if (pargs) {
*pargs = '\0';
}
char *env = createEnv();
char error[CCHMAXPATH] = { 0 };
RESULTCODES crc = { 0 };
ULONG rc = DosExecPgm(error, sizeof(error), EXEC_ASYNC, args, env,
&crc, (PSZ)aExePath);
free(args); // done with the arguments
if (env) {
free(env);
}
if (rc != NO_ERROR) {
return -1;
}
return 0;
}
#endif
// If aBlankCommandLine is true, then the application will be launched with a
// blank command line instead of being launched with the same command line that
// it was initially started with.
@ -1417,6 +1505,10 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative,
#if defined(XP_WIN)
if (!WinLaunchChild(exePath.get(), gRestartArgc, gRestartArgv, needElevation))
return NS_ERROR_FAILURE;
#elif defined(XP_OS2) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3)
// implementation of _execv() is broken with GCC 3.3.x on OS/2
if (OS2LaunchChild(exePath.get(), gRestartArgc, gRestartArgv) == -1)
return NS_ERROR_FAILURE;
#elif defined(XP_OS2)
if (_execv(exePath.get(), gRestartArgv) == -1)
return NS_ERROR_FAILURE;
@ -1667,10 +1759,17 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
*aResult = nsnull;
*aStartOffline = PR_FALSE;
ar = CheckArg("offline", PR_TRUE);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -offline is invalid when argument -osint is specified\n");
return NS_ERROR_FAILURE;
}
arg = PR_GetEnv("XRE_START_OFFLINE");
if ((arg && *arg) || CheckArg("offline"))
if ((arg && *arg) || ar)
*aStartOffline = PR_TRUE;
arg = PR_GetEnv("XRE_PROFILE_PATH");
if (arg && *arg) {
nsCOMPtr<nsILocalFile> lf;
@ -1690,17 +1789,22 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
// Clear out flags that we handled (or should have handled!) last startup.
const char *dummy;
CheckArg("p", &dummy);
CheckArg("profile", &dummy);
CheckArg("p", PR_FALSE, &dummy);
CheckArg("profile", PR_FALSE, &dummy);
CheckArg("profilemanager");
return NS_LockProfilePath(lf, localDir, nsnull, aResult);
}
if (CheckArg("migration"))
ar = CheckArg("migration", PR_TRUE);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -migration is invalid when argument -osint is specified\n");
return NS_ERROR_FAILURE;
} else if (ar == ARG_FOUND) {
gDoMigration = PR_TRUE;
}
ar = CheckArg("profile", &arg);
ar = CheckArg("profile", PR_TRUE, &arg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -profile requires a path\n");
return NS_ERROR_FAILURE;
@ -1725,7 +1829,7 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
rv = NS_NewToolkitProfileService(getter_AddRefs(profileSvc));
NS_ENSURE_SUCCESS(rv, rv);
ar = CheckArg("createprofile", &arg);
ar = CheckArg("createprofile", PR_TRUE, &arg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -createprofile requires a profile name\n");
return NS_ERROR_FAILURE;
@ -1782,11 +1886,21 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
}
}
ar = CheckArg("p", &arg);
ar = CheckArg("p", PR_FALSE, &arg);
if (ar == ARG_BAD) {
ar = CheckArg("osint");
if (ar == ARG_FOUND) {
PR_fprintf(PR_STDERR, "Error: argument -p is invalid when argument -osint is specified\n");
return NS_ERROR_FAILURE;
}
return ShowProfileManager(profileSvc, aNative);
}
if (ar) {
ar = CheckArg("osint");
if (ar == ARG_FOUND) {
PR_fprintf(PR_STDERR, "Error: argument -p is invalid when argument -osint is specified\n");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIToolkitProfile> profile;
rv = profileSvc->GetProfileByName(nsDependentCString(arg),
getter_AddRefs(profile));
@ -1811,7 +1925,11 @@ SelectProfile(nsIProfileLock* *aResult, nsINativeAppSupport* aNative,
return ShowProfileManager(profileSvc, aNative);
}
if (CheckArg("profilemanager")) {
ar = CheckArg("profilemanager", PR_TRUE);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -profilemanager is invalid when argument -osint is specified\n");
return NS_ERROR_FAILURE;
} else if (ar == ARG_FOUND) {
return ShowProfileManager(profileSvc, aNative);
}
@ -2086,6 +2204,7 @@ int
XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
{
nsresult rv;
ArgResult ar;
NS_TIMELINE_MARK("enter main");
#ifdef DEBUG
@ -2201,13 +2320,23 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
ScopedFPHandler handler;
#endif /* XP_OS2 */
if (CheckArg("safe-mode"))
ar = CheckArg("safe-mode", PR_TRUE);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -safe-mode is invalid when argument -osint is specified\n");
return 1;
} else if (ar == ARG_FOUND) {
gSafeMode = PR_TRUE;
}
// Handle -no-remote command line argument. Setup the environment to
// better accommodate other components and various restart scenarios.
if (CheckArg("no-remote"))
ar = CheckArg("no-remote", PR_TRUE);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -a requires an application name\n");
return 1;
} else if (ar == ARG_FOUND) {
PR_SetEnv("MOZ_NO_REMOTE=1");
}
// Handle -help and -version command line arguments.
// They should return quickly, so we deal with them here.
@ -2233,7 +2362,12 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
}
// Check for -register, which registers chrome and then exits immediately.
if (CheckArg("register")) {
ar = CheckArg("register", PR_TRUE);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -register is invalid when argument -osint is specified\n");
return 1;
} else if (ar == ARG_FOUND) {
ScopedXPCOMStartup xpcom;
rv = xpcom.Initialize();
NS_ENSURE_SUCCESS(rv, 1);
@ -2253,6 +2387,9 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
// in nsAppShell::Create, but we need to get in before gtk
// has been initialized to make sure everything is running
// consistently.
#if defined(MOZ_WIDGET_GTK2)
g_thread_init(NULL);
#endif
if (CheckArg("install"))
gdk_rgb_set_install(TRUE);
@ -2331,7 +2468,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
// handle -remote now that xpcom is fired up
const char* xremotearg;
ArgResult ar = CheckArg("remote", &xremotearg);
ar = CheckArg("remote", PR_TRUE, &xremotearg);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: -remote requires an argument\n");
return 1;
@ -2342,8 +2479,11 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
if (!PR_GetEnv("MOZ_NO_REMOTE")) {
// Try to remote the entire command line. If this fails, start up normally.
if (RemoteCommandLine())
RemoteResult rr = RemoteCommandLine();
if (rr == REMOTE_FOUND)
return 0;
else if (rr == REMOTE_ARG_BAD)
return 1;
}
#endif
@ -2367,50 +2507,18 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
}
// Check for and process any available updates
nsCOMPtr<nsIFile> updRoot = dirProvider.GetAppDir();
nsCOMPtr<nsILocalFile> updRootl(do_QueryInterface(updRoot));
#ifdef XP_WIN
// Use <UserLocalDataDir>\updates\<relative path to app dir from
// Program Files> if app dir is under Program Files to avoid the
// folder virtualization mess on Windows Vista
char path[MAXPATHLEN];
rv = GetShellFolderPath(CSIDL_PROGRAM_FILES, path);
// Fallback to previous behavior since getting CSIDL_PROGRAM_FILES may fail
// on Win9x.
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsILocalFile> programFilesDir;
rv = NS_NewNativeLocalFile(nsDependentCString(path), PR_FALSE,
getter_AddRefs(programFilesDir));
NS_ENSURE_SUCCESS(rv, 1);
PRBool descendant;
rv = programFilesDir->Contains(updRootl, PR_TRUE, &descendant);
NS_ENSURE_SUCCESS(rv, 1);
if (descendant) {
nsCAutoString relativePath;
rv = updRootl->GetRelativeDescriptor(programFilesDir, relativePath);
NS_ENSURE_SUCCESS(rv, 1);
nsCOMPtr<nsILocalFile> userLocalDir;
rv = dirProvider.GetUserLocalDataDirectory(getter_AddRefs(userLocalDir));
NS_ENSURE_SUCCESS(rv, 1);
rv = NS_NewNativeLocalFile(EmptyCString(), PR_FALSE,
getter_AddRefs(updRootl));
NS_ENSURE_SUCCESS(rv, 1);
rv = updRootl->SetRelativeDescriptor(userLocalDir, relativePath);
NS_ENSURE_SUCCESS(rv, 1);
}
}
#endif
nsCOMPtr<nsIFile> updRoot;
PRBool persistent;
rv = dirProvider.GetFile(XRE_UPDATE_ROOT_DIR, &persistent,
getter_AddRefs(updRoot));
// XRE_UPDATE_ROOT_DIR may fail. Fallback to appDir if failed
if (NS_FAILED(rv))
updRoot = dirProvider.GetAppDir();
// Check for and process any available updates
ProcessUpdates(greDir,
appDir,
updRootl,
updRoot,
gRestartArgc,
gRestartArgv);
#endif
@ -2591,7 +2699,21 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
nsCOMPtr<nsIExtensionManager> em(do_GetService("@mozilla.org/extensions/manager;1"));
NS_ENSURE_TRUE(em, 1);
if (CheckArg("install-global-extension") || CheckArg("install-global-theme")) {
ar = CheckArg("install-global-extension", PR_TRUE);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -install-global-extension is invalid when argument -osint is specified\n");
return 1;
} else if (ar == ARG_FOUND) {
// Do the required processing and then shut down.
em->HandleCommandLineArgs(cmdLine);
return 0;
}
ar = CheckArg("install-global-theme", PR_TRUE);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument -install-global-theme is invalid when argument -osint is specified\n");
return 1;
} else if (ar == ARG_FOUND) {
// Do the required processing and then shut down.
em->HandleCommandLineArgs(cmdLine);
return 0;

View File

@ -71,6 +71,16 @@
// such as showing the profile manager uI, this key will not be available.
#define NS_APP_PROFILE_LOCAL_DIR_STARTUP "ProfLDS"
/**
* A directory service key which provides the update directory.
* At present this is supported only on Windows.
* Windows: Documents and Settings\<User>\Local Settings\Application Data\
* <Vendor>\<Application>\<relative path to app dir from Program Files>
* If appDir is not under the Program Files, directory service will fail.
* Callers should fallback to appDir.
*/
#define XRE_UPDATE_ROOT_DIR "UpdRootD"
class nsACString;
struct nsXREAppData;
struct nsStaticModuleInfo;

View File

@ -68,6 +68,9 @@
#ifndef CSIDL_LOCAL_APPDATA
#define CSIDL_LOCAL_APPDATA 0x001C
#endif
#ifndef CSIDL_PROGRAM_FILES
#define CSIDL_PROGRAM_FILES 0x0026
#endif
#endif
#ifdef XP_MACOSX
#include "nsILocalFileMac.h"
@ -134,13 +137,6 @@ nsXREDirProvider::SetProfile(nsIFile* aDir, nsIFile* aLocalDir)
{
NS_ASSERTION(aDir && aLocalDir, "We don't support no-profile apps yet!");
#ifdef DEBUG_bsmedberg
nsCAutoString path, path2;
aDir->GetNativePath(path);
aLocalDir->GetNativePath(path2);
printf("nsXREDirProvider::SetProfile('%s', '%s')\n", path.get(), path2.get());
#endif
nsresult rv;
rv = EnsureDirectoryExists(aDir);
@ -205,6 +201,11 @@ nsXREDirProvider::GetFile(const char* aProperty, PRBool* aPersistent,
!strcmp(aProperty, XRE_USER_APP_DATA_DIR)) {
rv = GetUserAppDataDirectory((nsILocalFile**)(nsIFile**) getter_AddRefs(file));
}
#ifdef XP_WIN
else if (!strcmp(aProperty, XRE_UPDATE_ROOT_DIR)) {
rv = GetUpdateRootDir(getter_AddRefs(file));
}
#endif
else if (!strcmp(aProperty, NS_APP_APPLICATION_REGISTRY_FILE)) {
rv = GetUserAppDataDirectory((nsILocalFile**)(nsIFile**) getter_AddRefs(file));
rv |= file->AppendNative(NS_LITERAL_CSTRING(APP_REGISTRY_NAME));
@ -725,6 +726,65 @@ GetShellFolderPath(int folder, char result[MAXPATHLEN])
pMalloc->Release();
return rv;
}
nsresult
nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
{
nsCOMPtr<nsIFile> appDir = GetAppDir();
nsCAutoString appPath;
nsresult rv = appDir->GetNativePath(appPath);
NS_ENSURE_SUCCESS(rv, rv);
// AppDir may be a short path. Convert to long path to make sure
// the consistency of the update folder location
nsCString longPath;
longPath.SetLength(MAXPATHLEN);
char *buf = longPath.BeginWriting();
DWORD (WINAPI *pGetLongPathName)(LPCTSTR, LPTSTR, DWORD);
// GetLongPathName() is not present on WinNT 4.0
*(FARPROC *)&pGetLongPathName =
GetProcAddress(GetModuleHandle("kernel32.dll"), "GetLongPathNameA");
if (pGetLongPathName) {
DWORD len = pGetLongPathName(appPath.get(), buf, MAXPATHLEN);
// Failing GetLongPathName() is not fatal.
if (len <= 0 || len >= MAXPATHLEN)
longPath.Assign(appPath);
else
longPath.SetLength(len);
}
else {
longPath.Assign(appPath);
}
// Use <UserLocalDataDir>\updates\<relative path to app dir from
// Program Files> if app dir is under Program Files to avoid the
// folder virtualization mess on Windows Vista
char programFiles[MAXPATHLEN];
rv = GetShellFolderPath(CSIDL_PROGRAM_FILES, programFiles);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 programFilesLen = strlen(programFiles);
programFiles[programFilesLen++] = '\\';
programFiles[programFilesLen] = '\0';
if (longPath.Length() < programFilesLen)
return NS_ERROR_FAILURE;
if (_strnicmp(programFiles, longPath.get(), programFilesLen) != 0)
return NS_ERROR_FAILURE;
nsCOMPtr<nsILocalFile> updRoot;
rv = GetUserLocalDataDirectory(getter_AddRefs(updRoot));
NS_ENSURE_SUCCESS(rv, rv);
rv = updRoot->AppendRelativeNativePath(Substring(longPath, programFilesLen));
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*aResult = updRoot);
return NS_OK;
}
#endif
nsresult

View File

@ -80,6 +80,13 @@ public:
/* make sure you clone it, if you need to do stuff to it */
nsIFile* GetAppDir() { return mAppDir; }
/**
* Get the directory under which update directory is created.
* This method may be called before XPCOM is started. aResult
* is a clone, it may be modified.
*/
nsresult GetUpdateRootDir(nsIFile* *aResult);
protected:
static nsresult GetUserDataDirectory(nsILocalFile* *aFile, PRBool aLocal);
static nsresult EnsureDirectoryExists(nsIFile* aDirectory);

View File

@ -37,7 +37,7 @@
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../..
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
@ -47,7 +47,7 @@ include $(DEPTH)/config/autoconf.mk
MODULE = xpinstall
installer:
$(PERL) $(srcdir)/build.pl
$(PERL) build.pl
include $(topsrcdir)/config/rules.mk

View File

@ -56,13 +56,11 @@ use File::Copy;
use File::Path;
use File::Basename;
$DEPTH = "../../../../../obj-sm95-release/";
#$topsrcdir = "/c/projects/moz95/mozilla";
$DEPTH = "../../../..";
$topsrcdir = GetTopSrcDir();
# ensure that Packager.pm is in @INC, since we might not be called from
# mozilla/xpinstall/packager
# line below is "<source dir>/xpinstall/packager"
push(@INC, "/c/projects/moz95/mozilla/xpinstall/packager");
push(@INC, "$topsrcdir/../mozilla/xpinstall/packager");
require StageUtils;
ParseArgv(@ARGV);
@ -74,8 +72,7 @@ $inStagePath = "$topobjdir/stage" if !defined($inStagePath);
$inDistPath = "$topobjdir/dist" if !defined($inDistPath);
$cwdBuilder = "$topsrcdir/xpinstall/wizard/windows/builder";
$gDistInstallPath = "$inDistPath/install";
$gPackagerPath = "/c/projects/moz95/mozilla/xpinstall/packager";
$gPackagerPath = "$topsrcdir/xpinstall/packager";
if(defined($ENV{DEBUG_INSTALLER_BUILD}))
{

View File

@ -59,8 +59,13 @@ DEFINES += -DAB_CD=$(AB_CD)
ifeq ($(USE_SHORT_LIBNAME), 1)
PROGRAM = xulrunner$(BIN_SUFFIX)
else
ifeq ($(OS_ARCH), BeOS)
PROGRAM = xulrunner$(BIN_SUFFIX)
else
PROGRAM = xulrunner-bin$(BIN_SUFFIX)
endif
endif
DEFINES += -DXULRUNNER_PROGNAME=\"xulrunner\"
ifdef MOZ_JAVAXPCOM
@ -237,7 +242,7 @@ LDFLAGS += -Zlinker /NOE
endif
endif
ifneq (,$(filter-out OS2 WINNT Darwin,$(OS_ARCH)))
ifneq (,$(filter-out OS2 WINNT Darwin BeOS,$(OS_ARCH)))
xulrunner:: mozilla.in Makefile.in Makefile $(DEPTH)/config/autoconf.mk
cat $< | sed -e "s|%MOZAPPDIR%|$(mozappdir)|" \

View File

@ -36,7 +36,7 @@
#
# ***** END LICENSE BLOCK *****
## $Id: mozilla.in,v 1.2.8.1 2005/09/20 21:13:06 dbaron%dbaron.org Exp $
## $Id: mozilla.in,v 1.2.8.2 2008/01/11 03:20:02 reed%reedloden.com Exp $
##
## Usage:
##
@ -112,6 +112,7 @@ else
bn=`basename "$progname"`
cd `dirname "$progname"`
progname=`/bin/ls -l "$bn" | sed -e 's/^.* -> //' `
progbase=`basename "$progname"`
if [ ! -x "$progname" ]; then
break
fi

View File

@ -6,7 +6,7 @@
name="Mozilla.XULRunner"
type="win32"
/>
<description>Mozilla Thunderbird</description>
<description>Mozilla XULRunner</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
@ -19,4 +19,12 @@
/>
</dependentAssembly>
</dependency>
<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
<ms_asmv3:security>
<ms_asmv3:requestedPrivileges>
<ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false">
</ms_asmv3:requestedExecutionLevel>
</ms_asmv3:requestedPrivileges>
</ms_asmv3:security>
</ms_asmv3:trustInfo>
</assembly>

View File

@ -54,3 +54,19 @@ pref("intl.charset.detector", "chrome://global/locale/intl.properties");
pref("intl.charset.default", "chrome://global-platform/locale/intl.properties");
pref("intl.menuitems.alwaysappendaccesskeys","chrome://global/locale/intl.properties");
pref("intl.menuitems.insertseparatorbeforeaccesskeys","chrome://global/locale/intl.properties");
pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul");
pref("xpinstall.dialog.progress.chrome", "chrome://mozapps/content/extensions/extensions.xul");
pref("xpinstall.dialog.progress.skin", "chrome://mozapps/content/extensions/extensions.xul");
pref("xpinstall.dialog.progress.type.chrome", "Extension:Manager");
pref("xpinstall.dialog.progress.type.skin", "Extension:Manager");
pref("xpinstall.enabled", true);
#ifdef XP_WIN
pref("browser.preferences.instantApply", false);
#else
pref("browser.preferences.instantApply", true);
#endif
#ifdef XP_MACOSX
pref("browser.preferences.animateFadeIn", true);
#else
pref("browser.preferences.animateFadeIn", false);
#endif

View File

@ -54,12 +54,53 @@ NO_PKG_FILES = \
xpt_link* \
$(NULL)
# If we're on mac, we want to make the .pkg first, in the mac/
# directory. Then packager.mk can put it into a DMG
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
DIRS += mac
_APPNAME = $(PKG_BASENAME).pkg
PKG_SKIP_STRIP = 1
MOZ_PKG_SPECIAL = pkg
PKG_DMG_SOURCE = $(STAGEPATH)xulrunner-pkg
endif
include $(topsrcdir)/config/rules.mk
include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
#
# Package the SDK directory
#
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
SDK_APPNAME = $(MOZ_APP_NAME)
else
SDK_APPNAME = $(MOZ_PKG_APPNAME)
endif
SDK_BASENAME = $(SDK_APPNAME)-$(MOZ_PKG_VERSION).$(AB_CD).$(MOZ_PKG_PLATFORM)
SDK = $(SDK_BASENAME).sdk$(PKG_SUFFIX)
ifeq ($(MOZ_PKG_FORMAT),TAR)
MAKE_SDK = $(CREATE_FINAL_TAR) - gecko-sdk > $(SDK)
else
ifeq ($(MOZ_PKG_FORMAT),TGZ)
MAKE_SDK = $(CREATE_FINAL_TAR) - gecko-sdk | gzip -vf9 > $(SDK)
else
ifeq ($(MOZ_PKG_FORMAT),BZ2)
MAKE_SDK = $(CREATE_FINAL_TAR) - gecko-sdk | bzip2 -vf > $(SDK)
else
# default to zip
MAKE_SDK = $(ZIP) -r9D $(SDK_BASENAME).sdk.zip gecko-sdk
endif
endif
endif
make-sdk:
@echo "Packaging SDK..."
@rm -rf $(DIST)/gecko-sdk
@mkdir $(DIST)/gecko-sdk
@cd $(DIST)/sdk && tar $(TAR_CREATE_FLAGS) - * | (cd ../gecko-sdk; tar -xf -)
cd $(DIST) && $(MAKE_SDK)
libs:: make-sdk

View File

@ -58,19 +58,21 @@ NO_PKG_FILES = \
include $(topsrcdir)/config/rules.mk
libs:: stage-package
%.plist: %.plist.in
$(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) $< > $@
PACKAGER_NO_LIBS=1
_APPNAME = XUL.framework
_BINPATH = /$(_APPNAME)/Versions/Current
# Include this solely for additional NO_PKG_FILES
include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
BINARY_DIR = $(DIST)/package-stage/XUL.framework/Versions/$(MOZILLA_VERSION)
SOFTOKN = $(BINARY_DIR)/$(DLL_PREFIX)softokn3$(DLL_SUFFIX)
FREEBL_HYBRID = $(BINARY_DIR)/$(DLL_PREFIX)freebl_hybrid_3$(DLL_SUFFIX)
FREEBL_PURE = $(BINARY_DIR)/$(DLL_PREFIX)freebl_pure32_3$(DLL_SUFFIX)
FREEBL = $(BINARY_DIR)/$(DLL_PREFIX)freebl3$(DLL_SUFFIX)
_ABS_OBJDIR := $(shell pwd)
_ABS_DIST := $(shell cd $(DIST) && pwd)
@ -89,45 +91,22 @@ CHOWN_REVERT ?= $(error CHOWN_REVERT must be set to a setuid script.)
libs:: Info.plist Description.plist
$(RM) -rf resource-stage
mkdir resource-stage
$(RM) -rf $(DIST)/package-stage
mkdir $(DIST)/package-stage
rsync --copy-unsafe-links -a $(DIST)/XUL.framework $(DIST)/package-stage
cd $(BINARY_DIR) && $(RM) -rf $(NO_PKG_FILES)
echo "Stripping package directory..."
find $(BINARY_DIR) ! -type d \
! -name "*.js" \
! -name "*.xpt" \
! -name "*.gif" \
! -name "*.jpg" \
! -name "*.png" \
! -name "*.xpm" \
! -name "*.txt" \
! -name "*.rdf" \
! -name "*.sh" \
! -name "*.properties" \
! -name "*.dtd" \
! -name "*.html" \
! -name "*.xul" \
! -name "*.css" \
! -name "*.xml" \
! -name "*.jar" \
! -name "*.dat" \
! -name "*.tbl" \
! -name "*.src" \
! -name "*.reg" \
$(PLATFORM_EXCLUDE_LIST) \
-exec $(STRIP) $(STRIP_FLAGS) {} >/dev/null 2>&1 \;
$(SIGN_NSS)
chmod -R a+rX,u+w,go-w,-s,-t $(DIST)/package-stage
$(RM) -rf $(DIST)/$(STAGEPATH)xulrunner-pkg
mkdir $(DIST)/$(STAGEPATH)xulrunner-pkg
chmod -R a+rX,u+w,go-w,-s,-t $(DIST)/$(STAGEPATH)$(MOZ_PKG_APPNAME)
# For some unknown reason, PackageMaker requires absolute paths to everything.
unset NEXT_ROOT; \
$(CHOWN_ROOT) $(DIST)/package-stage && \
/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker -build \
-p $(_ABS_DIST)/$(PKG_BASENAME).pkg \
-f $(_ABS_DIST)/package-stage \
$(CHOWN_ROOT) $(DIST)/$(STAGEPATH)$(MOZ_PKG_APPNAME) && \
/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker -build -v \
-p $(_ABS_DIST)/$(STAGEPATH)xulrunner-pkg/$(PKG_BASENAME).pkg \
-f $(_ABS_DIST)/$(STAGEPATH)$(MOZ_PKG_APPNAME) \
-r $(_ABS_OBJDIR)/resource-stage \
-i $(_ABS_OBJDIR)/Info.plist \
-d $(_ABS_OBJDIR)/Description.plist; \
-d $(_ABS_OBJDIR)/Description.plist > packagemaker.log; \
SAVED=$$?; \
$(CHOWN_REVERT) $(DIST)/package-stage; \
if [ "$$SAVED" == "1" -a \
`grep -c 'was completed with the following non-fatal errors' < packagemaker.log` -gt 0 ]; then \
SAVED=0; \
fi; \
$(CHOWN_REVERT) $(DIST)/$(STAGEPATH)$(MOZ_PKG_APPNAME); \
exit $$SAVED

View File

@ -247,7 +247,8 @@ const AppInstall = {
aDirectory = Components.classes["@mozilla.org/file/local;1"].
createInstance(nsILocalFile);
aDirectory.initWithPath("/usr/lib");
aDirectory.append(vendor.toLowerCase());
if (vendor)
aDirectory.append(vendor.toLowerCase());
#endif
#endif
}

View File

@ -57,6 +57,12 @@
#define XULRUNNER_BIN "xulrunner-bin"
#endif
//Added code to include necessary BEOS header for BEOS specific code
#ifdef XP_BEOS
#include <Entry.h>
#include <Path.h>
#endif
#define VERSION_MAXLEN 128
int
@ -66,12 +72,26 @@ main(int argc, char **argv)
char *lastSlash;
char iniPath[MAXPATHLEN];
char tmpPath[MAXPATHLEN];
#ifdef XP_WIN
if (!::GetModuleFileName(NULL, iniPath, sizeof(iniPath)))
return 1;
#else
//Added Beos specific code to get the Path
#elif defined ( XP_BEOS )
BEntry e((const char *)argv[0], true); // traverse symlink
BPath p;
status_t err;
err = e.GetPath(&p);
NS_ASSERTION(err == B_OK, "realpath failed");
if (err == B_OK)
//p.Path returns a pointer, so use strcpy to store path in iniPath
strcpy(iniPath, p.Path());
#else
// on unix, there is no official way to get the path of the current binary.
// instead of using the MOZILLA_FIVE_HOME hack, which doesn't scale to
@ -96,11 +116,12 @@ main(int argc, char **argv)
PRBool found = PR_FALSE;
char *token = strtok(pathdup, ":");
while (token) {
sprintf(iniPath, "%s/%s", token, argv[0]);
if (stat(iniPath, &fileStat) == 0) {
sprintf(tmpPath, "%s/%s", token, argv[0]);
if (realpath(tmpPath, iniPath) && stat(iniPath, &fileStat) == 0) {
found = PR_TRUE;
break;
}
token = strtok(NULL, ":");
}
free (pathdup);
if (!found)
@ -186,8 +207,13 @@ main(int argc, char **argv)
"%s" XPCOM_FILE_PATH_SEPARATOR XULRUNNER_BIN, greDir);
#ifndef XP_WIN
#ifdef XP_BEOS
putenv(strcat("XPCOM_SEARCH_KEY=", greDir));
#else
setenv(XPCOM_SEARCH_KEY, greDir, 1);
#endif
#endif
argv2[0] = xulBin;
argv2[1] = iniPath;