Merge mozilla-central to tracemonkey.

This commit is contained in:
Robert Sayre 2009-11-19 09:24:51 +01:00
commit 55f6ca7935
22 changed files with 229 additions and 116 deletions

View File

@ -4325,12 +4325,14 @@ var TabsProgressListener = {
},
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
#ifdef MOZ_CRASHREPORTER
if (!aRequest.URI)
aRequest.QueryInterface(Ci.nsIChannel);
if (aStateFlags & Ci.nsIWebProgressListener.STATE_START &&
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT) {
gCrashReporter.annotateCrashReport("URL", aRequest.URI.spec);
}
#endif
},
onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI) {

View File

@ -475,7 +475,7 @@ function buildHelpMenu()
#ifdef MOZ_UPDATER
var updates =
Components.classes["@mozilla.org/updates/update-service;1"].
getService(Components.interfaces.nsIApplicationUpdateService);
getService(Components.interfaces.nsIApplicationUpdateService2);
var um =
Components.classes["@mozilla.org/updates/update-manager;1"].
getService(Components.interfaces.nsIUpdateManager);
@ -483,9 +483,9 @@ function buildHelpMenu()
// Disable the UI if the update enabled pref has been locked by the
// administrator or if we cannot update for some other reason
var checkForUpdates = document.getElementById("checkForUpdates");
var canUpdate = updates.canUpdate;
checkForUpdates.setAttribute("disabled", !canUpdate);
if (!canUpdate)
var canCheckForUpdates = updates.canCheckForUpdates;
checkForUpdates.setAttribute("disabled", !canCheckForUpdates);
if (!canCheckForUpdates)
return;
var strings = document.getElementById("bundle_browser");

View File

@ -68,9 +68,8 @@ function test() {
gPrefService.setIntPref("browser.sessionstore.max_windows_undo", max_windows_undo + 1);
let closedWindowCount = ss.getClosedWindowCount();
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", testURL);
let newWin = openDialog(location, "", "chrome,all,dialog=no", testURL);
newWin.addEventListener("load", function(aEvent) {
newWin.removeEventListener("load", arguments.callee, false);
newWin.gBrowser.addEventListener("load", function(aEvent) {
newWin.gBrowser.removeEventListener("load", arguments.callee, true);
@ -99,7 +98,6 @@ function test() {
"The reopened window was removed from Recently Closed Windows");
newWin2.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, false);
newWin2.gBrowser.addEventListener("SSTabRestored", function(aEvent) {
newWin2.gBrowser.removeEventListener("SSTabRestored", arguments.callee, true);
@ -154,18 +152,17 @@ function test() {
let settings = "chrome,dialog=no," +
(winData.isPopup ? "all=no" : "all");
let url = "http://window" + windowsToOpen.length + ".example.com";
let window = openDialog(location, "_blank", settings, url);
window.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
window.gBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
let win = openDialog(location, "", settings, url);
win.addEventListener("load", function(aEvent) {
win.gBrowser.addEventListener("load", function(aEvent) {
win.gBrowser.removeEventListener("load", arguments.callee, true);
// the window _should_ have state with a tab of url, but it doesn't
// always happend before window.close(). addTab ensure we don't treat
// this window as a stateless window
window.gBrowser.addTab();
win.gBrowser.addTab();
executeSoon(function() {
window.close();
win.close();
executeSoon(function() {
openWindowRec(windowsToOpen, expectedResults, recCallback);
});
@ -203,6 +200,12 @@ function test() {
// backup old state
let oldState = ss.getBrowserState();
let oldState_wins = JSON.parse(oldState).windows.length;
if (oldState_wins != 1) {
ok(false, "oldState in test_purge has " + oldState_wins + " windows instead of 1");
info(oldState);
}
// create a new state for testing
const REMEMBER = Date.now(), FORGET = Math.random();
let testState = {
@ -269,30 +272,30 @@ function test() {
let closedWindowData = JSON.parse(ss.getClosedWindowData());
// First set of tests for _closedWindows[0] - tests basics
let window = closedWindowData[0];
is(window.tabs.length, 1, "1 tab was removed");
is(countOpenTabsByTitle(window.tabs, FORGET), 0,
let win = closedWindowData[0];
is(win.tabs.length, 1, "1 tab was removed");
is(countOpenTabsByTitle(win.tabs, FORGET), 0,
"The correct tab was removed");
is(countOpenTabsByTitle(window.tabs, REMEMBER), 1,
is(countOpenTabsByTitle(win.tabs, REMEMBER), 1,
"The correct tab was remembered");
is(window.selected, 1, "Selected tab has changed");
is(window.title, REMEMBER, "The window title was correctly updated");
is(win.selected, 1, "Selected tab has changed");
is(win.title, REMEMBER, "The window title was correctly updated");
// Test more complicated case
window = closedWindowData[1];
is(window.tabs.length, 3, "2 tabs were removed");
is(countOpenTabsByTitle(window.tabs, FORGET), 0,
win = closedWindowData[1];
is(win.tabs.length, 3, "2 tabs were removed");
is(countOpenTabsByTitle(win.tabs, FORGET), 0,
"The correct tabs were removed");
is(countOpenTabsByTitle(window.tabs, REMEMBER), 3,
is(countOpenTabsByTitle(win.tabs, REMEMBER), 3,
"The correct tabs were remembered");
is(window.selected, 3, "Selected tab has changed");
is(window.title, REMEMBER, "The window title was correctly updated");
is(win.selected, 3, "Selected tab has changed");
is(win.title, REMEMBER, "The window title was correctly updated");
// Tests handling of _closedTabs
window = closedWindowData[2];
is(countClosedTabsByTitle(window._closedTabs, REMEMBER), 1,
win = closedWindowData[2];
is(countClosedTabsByTitle(win._closedTabs, REMEMBER), 1,
"The correct number of tabs were removed, and the correct ones");
is(countClosedTabsByTitle(window._closedTabs, FORGET), 0,
is(countClosedTabsByTitle(win._closedTabs, FORGET), 0,
"All tabs to be forgotten were indeed removed");
// restore pre-test state

View File

@ -839,11 +839,6 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget,
PRBool aInPrintPreview,
PRBool aNeedMakeCX /*= PR_TRUE*/)
{
// We don't want any scripts to run here. That can cause flushing,
// which can cause reentry into initialization of this document viewer,
// which would be disastrous.
nsAutoScriptBlocker blockScripts;
mParentWidget = aParentWidget; // not ref counted
mBounds = aBounds;

View File

@ -8,5 +8,6 @@ load invalid-size.gif
load invalid-size-second-frame.gif
# Animated gifs with a very large canvas, but tiny actual content.
load delaytest.html?523528-1.gif
load delaytest.html?523528-2.gif
# Disabled temporarily until fatal assertion is removed
#load delaytest.html?523528-1.gif
#load delaytest.html?523528-2.gif

View File

@ -64,10 +64,10 @@
#
# ------------------------------------------------------------------
FROMTOP=/share/builds/components/nspr20/v4.8.2
TOTOP=./v4.8.2
NSPRDIR=nspr-4.8.2
SOURCETAG=NSPR_4_8_2_RTM
FROMTOP=/share/builds/components/nspr20/v4.8.3
TOTOP=./v4.8.3
NSPRDIR=nspr-4.8.3
SOURCETAG=NSPR_4_8_3_RTM
#
# enumerate Unix object directories on /s/b/c

View File

@ -42,3 +42,4 @@
*/
#error "Do not include this header file."

View File

@ -172,18 +172,13 @@ ifndef RELEASE_LIBS_DEST
RELEASE_LIBS_DEST = $(RELEASE_LIB_DIR)
endif
define MAKE_IN_DIR
$(MAKE) -C $(dir) $@
endef # do not remove the blank line!
ifdef DIRS
LOOP_OVER_DIRS = \
@for d in $(DIRS); do \
if test -d $$d; then \
set -e; \
echo "cd $$d; $(MAKE) $@"; \
$(MAKE) -C $$d $@; \
set +e; \
else \
echo "Skipping non-directory $$d..."; \
fi; \
done
LOOP_OVER_DIRS = $(foreach dir,$(DIRS),$(MAKE_IN_DIR))
endif
################################################################################

2
nsprpub/configure vendored
View File

@ -695,7 +695,7 @@ test "$host_alias" != "$target_alias" &&
MOD_MAJOR_VERSION=4
MOD_MINOR_VERSION=8
MOD_PATCH_VERSION=2
MOD_PATCH_VERSION=3
NSPR_MODNAME=nspr20
_HAVE_PTHREADS=
USE_PTHREADS=

View File

@ -50,7 +50,7 @@ dnl = Defaults
dnl ========================================================
MOD_MAJOR_VERSION=4
MOD_MINOR_VERSION=8
MOD_PATCH_VERSION=2
MOD_PATCH_VERSION=3
NSPR_MODNAME=nspr20
_HAVE_PTHREADS=
USE_PTHREADS=

View File

@ -63,11 +63,11 @@ PR_BEGIN_EXTERN_C
** The format of the version string is
** "<major version>.<minor version>[.<patch level>] [<Beta>]"
*/
#define PR_VERSION "4.8.2"
#define PR_VERSION "4.8.3 Beta"
#define PR_VMAJOR 4
#define PR_VMINOR 8
#define PR_VPATCH 2
#define PR_BETA PR_FALSE
#define PR_VPATCH 3
#define PR_BETA PR_TRUE
/*
** PRVersionCheck

View File

@ -456,7 +456,7 @@ PR_IMPLEMENT(void) PR_LogPrint(const char *fmt, ...)
PR_ExplodeTime(PR_Now(), PR_GMTParameters, &now);
nb_tid = PR_snprintf(line, sizeof(line)-1,
"%04d-%02d-%02d %02d:%02d:%02d.%06d UTC - ",
now.tm_year, now.tm_month, now.tm_mday,
now.tm_year, now.tm_month + 1, now.tm_mday,
now.tm_hour, now.tm_min, now.tm_sec,
now.tm_usec);
}

View File

@ -1728,6 +1728,8 @@ PR_strtod
}
}
dig_done:
if (nd > 64 * 1024)
goto ret0;
e = 0;
if (c == 'e' || c == 'E') {
if (!nd && !nz && !nz0) {

View File

@ -47,6 +47,7 @@
*
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <locale.h>
@ -61,6 +62,7 @@ int main(int argc, char **argv)
double num1;
double zero = 0.0;
char cnvt[50];
char *thousands;
num = 1e24;
num1 = PR_strtod("1e24",NULL);
@ -195,7 +197,6 @@ int main(int argc, char **argv)
failed_already = 1;
}
num = -1.0000000001e-21;
num1 = PR_strtod("-1.0000000001e-21",NULL);
if(num1 != num){
@ -215,6 +216,26 @@ int main(int argc, char **argv)
*/
num1 = PR_strtod("4e-356",NULL);
/*
* A very long input with ~384K digits.
* Bug 516396: Should not crash.
* Bug 521306: Should return 0 without converting the input.
*/
#define LENGTH (384 * 1024)
thousands = (char *)malloc(LENGTH);
thousands[0] = '0';
thousands[1] = '.';
memset(&thousands[2], '1', LENGTH - 3);
thousands[LENGTH - 1] = '\0';
num = 0;
num1 = PR_strtod(thousands,NULL);
free(thousands);
if(num1 != num){
fprintf(stderr,"Failed to convert numeric value %s\n",
"0.1111111111111111...");
failed_already = 1;
}
if (failed_already) {
printf("FAILED\n");
} else {

View File

@ -52,9 +52,9 @@
#include <stdlib.h>
/*
* This release (4.8.2) is backward compatible with the
* This release (4.8.3) is backward compatible with the
* 4.0.x, 4.1.x, 4.2.x, 4.3.x, 4.4.x, 4.5.x, 4.6.x, 4.7.x,
* 4.8, and 4.8.1 releases. It, of course, is compatible
* 4.8, 4.8.1, and 4.8.2 releases. It, of course, is compatible
* with itself.
*/
static char *compatible_version[] = {
@ -65,7 +65,7 @@ static char *compatible_version[] = {
"4.6.6", "4.6.7", "4.6.8",
"4.7", "4.7.1", "4.7.2", "4.7.3", "4.7.4", "4.7.5",
"4.7.6",
"4.8", "4.8.1", PR_VERSION
"4.8", "4.8.1", "4.8.2", PR_VERSION
};
/*

View File

@ -8,7 +8,7 @@ pref("app.update.interval", 86400);
pref("app.update.download.backgroundInterval", 600);
// URL user can browse to manually if for some reason all update installation
// attempts fail.
pref("app.update.url.manual", "http://%LOCALE%.www.mozilla.com/%LOCALE%/%APP%/");
pref("app.update.url.manual", "http://www.firefox.com");
// A default value for the "More information about this update" link
// supplied in the "An update is available" page of the update wizard.
pref("app.update.url.details", "http://%LOCALE%.www.mozilla.com/%LOCALE%/%APP%/releases/");

View File

@ -625,6 +625,15 @@ var gIncompatibleCheckPage = {
* Initialize
*/
onPageShow: function() {
var aus = CoC["@mozilla.org/updates/update-service;1"].
getService(CoI.nsIApplicationUpdateService2);
// Display the manual update page if the user is unable to apply the update
if (!aus.canApplyUpdates) {
gUpdates.wiz.currentPage.setAttribute("next", "manualUpdate");
gUpdates.wiz.advance();
return;
}
var ai = CoC["@mozilla.org/xre/app-info;1"].getService(CoI.nsIXULAppInfo);
var vc = CoC["@mozilla.org/xpcom/version-comparator;1"].
getService(CoI.nsIVersionComparator);
@ -740,6 +749,24 @@ var gIncompatibleCheckPage = {
}
};
/**
* The "Unable to Update" page. Provides the user information about why they
* were unable to update and a manual download url.
*/
var gManualUpdatePage = {
onPageShow: function() {
var formatter = CoC["@mozilla.org/toolkit/URLFormatterService;1"].
getService(CoI.nsIURLFormatter);
var manualURL = formatter.formatURLPref(PREF_UPDATE_MANUAL_URL);
var manualUpdateLinkLabel = document.getElementById("manualUpdateLinkLabel");
manualUpdateLinkLabel.value = manualURL;
manualUpdateLinkLabel.setAttribute("url", manualURL);
gUpdates.setButtons(null, null, "okButton", true);
gUpdates.wiz.getButton("finish").focus();
}
};
/**
* The "Updates Are Available" page. Provides the user information about the
* available update.

View File

@ -105,6 +105,18 @@
<progressmeter id="incompatibleCheckProgress" mode="undetermined" hidden="true"/>
</wizardpage>
<wizardpage id="manualUpdate" pageid="manualUpdate"
label="&manualUpdate.title;" object="gManualUpdatePage"
onpageshow="gManualUpdatePage.onPageShow();">
<description>&manualUpdate.desc;</description>
<separator class="thin"/>
<label>&manualUpdateGetMsg.label;</label>
<hbox>
<label class="text-link" id="manualUpdateLinkLabel" value=""
onclick="openUpdateURL(event);"/>
</hbox>
</wizardpage>
<wizardpage id="updatesfound" pageid="updatesfound" next="license"
object="gUpdatesAvailablePage" label=""
onpageshow="gUpdatesAvailablePage.onPageShow();"

View File

@ -403,6 +403,29 @@ interface nsIApplicationUpdateService : nsISupports
readonly attribute boolean canUpdate;
};
/**
* A temporary interface to allow adding new methods without changing existing
* interfaces for Gecko 1.9.2. After the 1.9.2 release this interface will be
* removed.
*/
[scriptable, uuid(e22e4bf1-b18c-40cd-a2be-2d565723d056)]
interface nsIApplicationUpdateService2 : nsIApplicationUpdateService
{
/**
* Whether or not the Update Service can check for updates. This is a function
* of whether or not application update is disabled by the application and the
* platform the application is running on.
*/
readonly attribute boolean canCheckForUpdates;
/**
* Whether or not the Update Service can download and install updates.
* This is a function of whether or not the current user has access
* privileges to the install directory.
*/
readonly attribute boolean canApplyUpdates;
};
/**
* An interface describing a global application service that maintains a list
* of updates previously performed as well as the current active update.

View File

@ -190,11 +190,11 @@ XPCOMUtils.defineLazyGetter(this, "gOSVersion", function aus_gOSVersion() {
return osVersion;
});
XPCOMUtils.defineLazyGetter(this, "gCanUpdate", function aus_gCanUpdate() {
XPCOMUtils.defineLazyGetter(this, "gCanApplyUpdates", function aus_gCanApplyUpdates() {
try {
const NORMAL_FILE_TYPE = Ci.nsILocalFile.NORMAL_FILE_TYPE;
var updateTestFile = getUpdateFile([FILE_PERMS_TEST]);
LOG("gCanUpdate - testing write access " + updateTestFile.path);
LOG("gCanApplyUpdates - testing write access " + updateTestFile.path);
if (updateTestFile.exists())
updateTestFile.remove(false);
updateTestFile.create(NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
@ -206,7 +206,7 @@ XPCOMUtils.defineLazyGetter(this, "gCanUpdate", function aus_gCanUpdate() {
// Example windowsVersion: Windows XP == 5.1
var windowsVersion = sysInfo.getProperty("version");
LOG("gCanUpdate - windowsVersion = " + windowsVersion);
LOG("gCanApplyUpdates - windowsVersion = " + windowsVersion);
/**
# For Vista, updates can be performed to a location requiring admin
@ -231,13 +231,13 @@ XPCOMUtils.defineLazyGetter(this, "gCanUpdate", function aus_gCanUpdate() {
// appDir is under Program Files, so check if the user can elevate
userCanElevate = gApp.QueryInterface(Ci.nsIWinAppHelper).
userCanElevate;
LOG("gCanUpdate - on Vista, userCanElevate: " + userCanElevate);
LOG("gCanApplyUpdates - on Vista, userCanElevate: " + userCanElevate);
}
catch (ex) {
// When the installation directory is not under Program Files,
// fall through to checking if write access to the
// installation directory is available.
LOG("gCanUpdate - on Vista, appDir is not under Program Files");
LOG("gCanApplyUpdates - on Vista, appDir is not under Program Files");
}
}
@ -265,7 +265,7 @@ XPCOMUtils.defineLazyGetter(this, "gCanUpdate", function aus_gCanUpdate() {
if (!userCanElevate) {
// if we're unable to create the test file this will throw an exception.
var appDirTestFile = FileUtils.getFile(KEY_APPDIR, [FILE_PERMS_TEST]);
LOG("gCanUpdate - testing write access " + appDirTestFile.path);
LOG("gCanApplyUpdates - testing write access " + appDirTestFile.path);
if (appDirTestFile.exists())
appDirTestFile.remove(false)
appDirTestFile.create(NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
@ -275,33 +275,40 @@ XPCOMUtils.defineLazyGetter(this, "gCanUpdate", function aus_gCanUpdate() {
#endif //XP_WIN
}
catch (e) {
LOG("gCanUpdate - unable to update. Exception: " + e);
LOG("gCanApplyUpdates - unable to apply updates. Exception: " + e);
// No write privileges to install directory
return false;
}
LOG("gCanApplyUpdates - able to apply updates");
return true;
});
XPCOMUtils.defineLazyGetter(this, "gCanCheckForUpdates", function aus_gCanCheckForUpdates() {
// If the administrator has locked the app update functionality
// 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)) {
LOG("gCanUpdate - unable to update, disabled by pref");
LOG("gCanCheckForUpdates - unable to automatically check for updates, " +
"disabled by pref");
return false;
}
// If we don't know the binary platform we're updating, we can't update.
if (!gABI) {
LOG("gCanUpdate - unable tp update, unknown ABI");
LOG("gCanCheckForUpdates - unable to check for updates, unknown ABI");
return false;
}
// If we don't know the OS version we're updating, we can't update.
if (!gOSVersion) {
LOG("gCanUpdate - unable to update, unknown OS version");
LOG("gCanCheckForUpdates - unable to check for updates, unknown OS " +
"version");
return false;
}
LOG("gCanUpdate - able to update");
LOG("gCanCheckForUpdates - able to check for updates");
return true;
});
@ -1079,7 +1086,8 @@ UpdateService.prototype = {
},
/**
* The following needs to happen during the profile-after-change notification:
* The following needs to happen during the post-update-processing
* notification from nsUpdateServiceStub.js:
* 1. post update processing
* 2. resume of a download that was in progress during a previous session
* 3. start of a complete update download after the failure to apply a partial
@ -1093,7 +1101,7 @@ UpdateService.prototype = {
* notify the user of install success.
*/
_postUpdateProcessing: function AUS__postUpdateProcessing() {
if (!gCanUpdate) {
if (!this.canUpdate) {
LOG("UpdateService:_postUpdateProcessing - unable to update");
return;
}
@ -1349,6 +1357,13 @@ UpdateService.prototype = {
return;
}
if (!gCanApplyUpdates) {
LOG("Checker:_selectAndInstallUpdate - prompting because the user is " +
"unable to apply updates");
this._showPrompt(update);
return;
}
if (!getPref("getBoolPref", PREF_APP_UPDATE_AUTO, true)) {
LOG("Checker:_selectAndInstallUpdate - prompting because silent " +
"install is disabled");
@ -1468,7 +1483,7 @@ UpdateService.prototype = {
* See nsIExtensionManager.idl
*/
onUpdateEnded: function AUS_onUpdateEnded() {
if (this._incompatAddonsCount > 0) {
if (this._incompatAddonsCount > 0 || !gCanApplyUpdates) {
LOG("Checker:onUpdateEnded - prompting because there are incompatible " +
"add-ons");
this._showPrompt(this._update);
@ -1520,7 +1535,21 @@ UpdateService.prototype = {
* See nsIUpdateService.idl
*/
get canUpdate() {
return gCanUpdate;
return gCanCheckForUpdates && gCanApplyUpdates;
},
/**
* See nsIUpdateService.idl
*/
get canCheckForUpdates() {
return gCanCheckForUpdates;
},
/**
* See nsIUpdateService.idl
*/
get canApplyUpdates() {
return gCanApplyUpdates;
},
/**
@ -1599,7 +1628,9 @@ UpdateService.prototype = {
implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
getHelperForLanguage: function(language) null,
getInterfaces: function AUS_getInterfaces(count) {
var interfaces = [Ci.nsIApplicationUpdateService, Ci.nsITimerCallback,
var interfaces = [Ci.nsIApplicationUpdateService,
Ci.nsIApplicationUpdateService2,
Ci.nsITimerCallback,
Ci.nsIObserver];
count.value = interfaces.length;
return interfaces;
@ -1614,6 +1645,7 @@ UpdateService.prototype = {
PREF_APP_UPDATE_INTERVAL + ",86400" }],
_xpcom_factory: UpdateServiceFactory,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIApplicationUpdateService,
Ci.nsIApplicationUpdateService2,
Ci.nsIAddonUpdateCheckListener,
Ci.nsITimerCallback,
Ci.nsIObserver])
@ -2060,7 +2092,7 @@ Checker.prototype = {
_enabled: true,
get enabled() {
return getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true) &&
gCanUpdate && this._enabled;
gCanCheckForUpdates && this._enabled;
},
/**

View File

@ -191,7 +191,7 @@ TimerManager.prototype = {
let interval = getPref("getIntPref", prefInterval, defaultInterval);
prefLastUpdate = PREF_APP_UPDATE_LASTUPDATETIME_FMT.replace(/%ID%/,
timerID);
timerID);
if (gPref.prefHasUserValue(prefLastUpdate)) {
lastUpdateTime = gPref.getIntPref(prefLastUpdate);
}

View File

@ -866,7 +866,7 @@ AddFile::Finish(int status)
class PatchFile : public Action
{
public:
PatchFile() : mPatchIndex(-1), pfile(NULL), buf(NULL) { }
PatchFile() : mPatchIndex(-1), buf(NULL) { }
virtual ~PatchFile();
virtual int Parse(char *line);
@ -884,25 +884,20 @@ private:
const NS_tchar *mDestFile;
int mPatchIndex;
MBSPatchHeader header;
FILE* pfile;
unsigned char *buf;
NS_tchar spath[MAXPATHLEN];
};
int PatchFile::sPatchIndex = 0;
PatchFile::~PatchFile()
{
if (pfile)
fclose(pfile);
// delete the temporary patch file
NS_tchar spath[MAXPATHLEN];
NS_tsnprintf(spath, MAXPATHLEN, NS_T("%s/%d.patch"),
gSourcePath, mPatchIndex);
if (spath[0])
NS_tremove(spath);
NS_tremove(spath);
free(buf);
if (buf)
free(buf);
}
int
@ -983,7 +978,6 @@ PatchFile::Prepare()
// extract the patch to a temporary file
mPatchIndex = sPatchIndex++;
NS_tchar spath[MAXPATHLEN];
NS_tsnprintf(spath, MAXPATHLEN, NS_T("%s/%d.patch"),
gSourcePath, mPatchIndex);
@ -995,28 +989,6 @@ PatchFile::Prepare()
int rv = gArchiveReader.ExtractFileToStream(mPatchFile, fp);
fclose(fp);
if (rv)
return rv;
// XXXdarin from here down should be moved into the Execute command.
// no need to open all of the patch files and read all of
// the source files before applying any patches.
pfile = NS_tfopen(spath, NS_T("rb"));
if (pfile == NULL)
return READ_ERROR;
rv = MBS_ReadHeader(pfile, &header);
if (rv)
return rv;
AutoFile ofile = NS_tfopen(mDestFile, NS_T("rb"));
if (ofile == NULL)
return READ_ERROR;
rv = LoadSourceFile(ofile);
if (rv)
LOG(("LoadSourceFile failed\n"));
return rv;
}
@ -1025,13 +997,32 @@ PatchFile::Execute()
{
LOG(("EXECUTE PATCH %s\n", mFile));
AutoFile pfile = NS_tfopen(spath, NS_T("rb"));
if (pfile == NULL)
return READ_ERROR;
int rv = MBS_ReadHeader(pfile, &header);
if (rv)
return rv;
FILE *origfile = NS_tfopen(mDestFile, NS_T("rb"));
if (!origfile)
return READ_ERROR;
rv = LoadSourceFile(origfile);
fclose(origfile);
if (rv) {
LOG(("LoadSourceFile failed\n"));
return rv;
}
// Create backup copy of the destination file before proceeding.
struct stat ss;
if (NS_tstat(mDestFile, &ss))
return READ_ERROR;
int rv = backup_create(mDestFile);
rv = backup_create(mDestFile);
if (rv)
return rv;
@ -1043,7 +1034,15 @@ PatchFile::Execute()
if (ofile == NULL)
return WRITE_ERROR;
return MBS_ApplyPatch(&header, pfile, buf, ofile);
rv = MBS_ApplyPatch(&header, pfile, buf, ofile);
// Go ahead and do a bit of cleanup now to minimize runtime overhead.
NS_tremove(spath);
spath[0] = '\0';
free(buf);
buf = NULL;
return rv;
}
void