mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 07:15:46 +00:00
Bug 1237219 - Lock patch files while applying updates; r=rstrong
MozReview-Commit-ID: 8m4SQVhZy4D
This commit is contained in:
parent
7a6cb90bcf
commit
187af240d4
@ -84,6 +84,7 @@
|
||||
#define WRITE_ERROR_EXTRACT 70
|
||||
#define REMOVE_FILE_SPEC_ERROR 71
|
||||
#define INVALID_STAGED_PARENT_ERROR 72
|
||||
#define LOCK_ERROR_PATCH_FILE 73
|
||||
|
||||
// Error codes 80 through 99 are reserved for nsUpdateService.js
|
||||
|
||||
|
@ -1377,18 +1377,31 @@ private:
|
||||
MBSPatchHeader header;
|
||||
unsigned char *buf;
|
||||
NS_tchar spath[MAXPATHLEN];
|
||||
AutoFile mPatchStream;
|
||||
};
|
||||
|
||||
int PatchFile::sPatchIndex = 0;
|
||||
|
||||
PatchFile::~PatchFile()
|
||||
{
|
||||
// delete the temporary patch file
|
||||
if (spath[0])
|
||||
NS_tremove(spath);
|
||||
// Make sure mPatchStream gets unlocked on Windows; the system will do that,
|
||||
// but not until some indeterminate future time, and we want determinism.
|
||||
// Normally this happens at the end of Execute, when we close the stream;
|
||||
// this call is here in case Execute errors out.
|
||||
#ifdef XP_WIN
|
||||
if (mPatchStream) {
|
||||
UnlockFile((HANDLE)_get_osfhandle(fileno(mPatchStream)), 0, 0, -1, -1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (buf)
|
||||
// delete the temporary patch file
|
||||
if (spath[0]) {
|
||||
NS_tremove(spath);
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@ -1409,8 +1422,9 @@ PatchFile::LoadSourceFile(FILE* ofile)
|
||||
}
|
||||
|
||||
buf = (unsigned char *) malloc(header.slen);
|
||||
if (!buf)
|
||||
if (!buf) {
|
||||
return UPDATER_MEM_ERROR;
|
||||
}
|
||||
|
||||
size_t r = header.slen;
|
||||
unsigned char *rb = buf;
|
||||
@ -1447,17 +1461,20 @@ PatchFile::Parse(NS_tchar *line)
|
||||
|
||||
// Get the path to the patch file inside of the mar
|
||||
mPatchFile = mstrtok(kQuote, &line);
|
||||
if (!mPatchFile)
|
||||
if (!mPatchFile) {
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
|
||||
// consume whitespace between args
|
||||
NS_tchar *q = mstrtok(kQuote, &line);
|
||||
if (!q)
|
||||
if (!q) {
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
|
||||
mFile = get_valid_path(&line);
|
||||
if (!mFile)
|
||||
if (!mFile) {
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -1475,11 +1492,19 @@ PatchFile::Prepare()
|
||||
|
||||
NS_tremove(spath);
|
||||
|
||||
FILE *fp = NS_tfopen(spath, NS_T("wb"));
|
||||
if (!fp)
|
||||
mPatchStream = NS_tfopen(spath, NS_T("wb+"));
|
||||
if (!mPatchStream) {
|
||||
return WRITE_ERROR;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Lock the patch file, so it can't be messed with between
|
||||
// when we're done creating it and when we go to apply it.
|
||||
if (!LockFile((HANDLE)_get_osfhandle(fileno(mPatchStream)), 0, 0, -1, -1)) {
|
||||
LOG(("Couldn't lock patch file: %d", GetLastError()));
|
||||
return LOCK_ERROR_PATCH_FILE;
|
||||
}
|
||||
|
||||
char sourcefile[MAXPATHLEN];
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0, mPatchFile, -1, sourcefile, MAXPATHLEN,
|
||||
nullptr, nullptr)) {
|
||||
@ -1487,11 +1512,11 @@ PatchFile::Prepare()
|
||||
return STRING_CONVERSION_ERROR;
|
||||
}
|
||||
|
||||
int rv = gArchiveReader.ExtractFileToStream(sourcefile, fp);
|
||||
int rv = gArchiveReader.ExtractFileToStream(sourcefile, mPatchStream);
|
||||
#else
|
||||
int rv = gArchiveReader.ExtractFileToStream(mPatchFile, fp);
|
||||
int rv = gArchiveReader.ExtractFileToStream(mPatchFile, mPatchStream);
|
||||
#endif
|
||||
fclose(fp);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1500,13 +1525,12 @@ PatchFile::Execute()
|
||||
{
|
||||
LOG(("EXECUTE PATCH " LOG_S, mFile));
|
||||
|
||||
AutoFile pfile(NS_tfopen(spath, NS_T("rb")));
|
||||
if (pfile == nullptr)
|
||||
return READ_ERROR;
|
||||
fseek(mPatchStream, 0, SEEK_SET);
|
||||
|
||||
int rv = MBS_ReadHeader(pfile, &header);
|
||||
if (rv)
|
||||
int rv = MBS_ReadHeader(mPatchStream, &header);
|
||||
if (rv) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
FILE *origfile = nullptr;
|
||||
#ifdef XP_WIN
|
||||
@ -1545,8 +1569,9 @@ PatchFile::Execute()
|
||||
}
|
||||
|
||||
rv = backup_create(mFile);
|
||||
if (rv)
|
||||
if (rv) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
#if defined(HAVE_POSIX_FALLOCATE)
|
||||
AutoFile ofile(ensure_open(mFile, NS_T("wb+"), ss.st_mode));
|
||||
@ -1609,12 +1634,17 @@ PatchFile::Execute()
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = MBS_ApplyPatch(&header, pfile, buf, ofile);
|
||||
rv = MBS_ApplyPatch(&header, mPatchStream, buf, ofile);
|
||||
|
||||
// Go ahead and do a bit of cleanup now to minimize runtime overhead.
|
||||
// Set pfile to nullptr to make AutoFile close the file so it can be deleted
|
||||
// on Windows.
|
||||
pfile = nullptr;
|
||||
// Make sure mPatchStream gets unlocked on Windows; the system will do that,
|
||||
// but not until some indeterminate future time, and we want determinism.
|
||||
#ifdef XP_WIN
|
||||
UnlockFile((HANDLE)_get_osfhandle(fileno(mPatchStream)), 0, 0, -1, -1);
|
||||
#endif
|
||||
// Set mPatchStream to nullptr to make AutoFile close the file,
|
||||
// so it can be deleted on Windows.
|
||||
mPatchStream = nullptr;
|
||||
NS_tremove(spath);
|
||||
spath[0] = NS_T('\0');
|
||||
free(buf);
|
||||
|
Loading…
Reference in New Issue
Block a user