Fixing race on creating a unique file name. This race, which existed forever, caused installing 2 xpis simultaneously to fail. r=ssu, sr=dveditz, b=186038.

This commit is contained in:
dougt%netscape.com 2002-12-23 22:18:54 +00:00
Родитель 969c878538
Коммит c613c3a8ca
5 изменённых файлов: 37 добавлений и 77 удалений

Просмотреть файл

@ -208,17 +208,27 @@ CertReader::OnDataAvailable(nsIRequest *request,
PRUint32 cSize = xtolong ((unsigned char *) ziplocal->size);
if (orgSize == 0)
return NS_ERROR_FAILURE;
unsigned char* orgData = (unsigned char*) malloc(orgSize);
if (!orgData)
return NS_BINDING_ABORTED;
int err = my_inflate((unsigned char*)data,
cSize,
orgData,
orgSize);
unsigned char* orgData;
int err = 0;
orgData = (unsigned char*) malloc(orgSize);
if (!orgData)
return NS_BINDING_ABORTED;
if (xtoint(ziplocal->method) == DEFLATED) {
err = my_inflate((unsigned char*)data,
cSize,
orgData,
orgSize);
}
else {
memcpy(orgData, data, orgSize);
}
if (err == 0)
{
@ -228,10 +238,11 @@ CertReader::OnDataAvailable(nsIRequest *request,
}
if (orgData)
free(orgData);
return NS_BINDING_ABORTED;
}
return NS_ERROR_FAILURE;
return NS_BINDING_ABORTED;
}
NS_IMETHODIMP

Просмотреть файл

@ -267,9 +267,7 @@ PRInt32 ReplaceFileNow(nsIFile* replacementFile, nsIFile* doomedFile )
//Now reset the leafname
tmpLocalFile->SetNativeLeafName(leafname);
MakeUnique(tmpLocalFile); // for the call to MakeUnique
tmpLocalFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);
tmpLocalFile->GetParent(getter_AddRefs(parent)); //get the parent for later use in MoveTo
tmpLocalFile->GetNativeLeafName(uniqueLeafName);//this is the new "unique" leafname

Просмотреть файл

@ -2622,10 +2622,7 @@ nsInstall::ExtractFileFromJar(const nsString& aJarfile, nsIFile* aSuggestedName,
tempFileName += extension;
}
tempFile->Append(tempFileName);
// Create a temporary file to extract to
MakeUnique(tempFile);
tempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0664);
tempFile->Clone(getter_AddRefs(extractHereSpec));
if (extractHereSpec == nsnull)
@ -2663,8 +2660,7 @@ nsInstall::ExtractFileFromJar(const nsString& aJarfile, nsIFile* aSuggestedName,
//Now reset the leafname
tempFile->SetLeafName(newLeafName);
MakeUnique(tempFile);
tempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);
extractHereSpec = tempFile;
}
extractHereSpec = temp;
@ -2829,50 +2825,3 @@ nsInstall::DeleteVector(nsVoidArray* vector)
vector = nsnull;
}
}
// XXX what's wrong with nsIFile::createUnique?
nsresult MakeUnique(nsILocalFile* file)
{
PRBool flagExists;
nsresult rv = file->Exists(&flagExists);
if (NS_FAILED(rv)) return rv;
if (!flagExists) return NS_ERROR_FAILURE;
nsCAutoString leafNameBuf;
rv = file->GetNativeLeafName(leafNameBuf);
if (NS_FAILED(rv)) return rv;
// XXX this code should use iterators
char *leafName = (char *) leafNameBuf.get();
char* lastDot = strrchr(leafName, '.');
char* suffix = "";
if (lastDot)
{
suffix = nsCRT::strdup(lastDot); // include '.'
*lastDot = '\0'; // strip suffix and dot.
}
// 27 should work on Macintosh, Unix, and Win32.
const int maxRootLength = 27 - strlen(suffix) - 1;
if ((int)strlen(leafName) > (int)maxRootLength)
leafName[maxRootLength] = '\0';
for (short indx = 1; indx < 1000 && flagExists; indx++)
{
// start with "Picture-1.jpg" after "Picture.jpg" exists
char newName[32];
sprintf(newName, "%s-%d%s", leafName, indx, suffix);
file->SetNativeLeafName(nsDependentCString(newName));
rv = file->Exists(&flagExists);
if (NS_FAILED(rv)) return rv;
}
return NS_OK;
}

Просмотреть файл

@ -471,8 +471,8 @@ nsInstallPatch::NativePatch(nsIFile *sourceFile, nsIFile *patchFile, nsIFile **n
rv = sourceFile->Clone(getter_AddRefs(tempSrcFile)); //Clone the sourceFile
tempSrcFile->SetLeafName(tmpFileName); //Append the new leafname
uniqueSrcFile = do_QueryInterface(tempSrcFile, &rv); //Create an nsILocalFile version to pass to MakeUnique
MakeUnique(uniqueSrcFile);
uniqueSrcFile = do_QueryInterface(tempSrcFile, &rv);
uniqueSrcFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);
nsCAutoString realfile;
sourceFile->GetNativePath(realfile);
@ -535,9 +535,8 @@ nsInstallPatch::NativePatch(nsIFile *sourceFile, nsIFile *patchFile, nsIFile **n
outFileSpec->SetLeafName(newFileName); //Set new leafname
nsCOMPtr<nsILocalFile> outFileLocal = do_QueryInterface(outFileSpec, &rv); //Create an nsILocalFile version
//to send to MakeUnique()
MakeUnique(outFileLocal);
nsCOMPtr<nsILocalFile> outFileLocal = do_QueryInterface(outFileSpec, &rv);
outFileLocal->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);
// apply patch to the source file
//dd->fSrc = PR_Open ( realfile, PR_RDONLY, 0666);
@ -585,8 +584,8 @@ nsInstallPatch::NativePatch(nsIFile *sourceFile, nsIFile *patchFile, nsIFile **n
outFileSpec->Clone(getter_AddRefs(bsTemp)); //Clone because we'll be changing the name
anotherName = do_QueryInterface(bsTemp, &rv); //Set the old name
MakeUnique(anotherName); //Now give it the new name
anotherName->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);
// Close the out file so that we can read it
PR_Close( dd->fOut );
dd->fOut = NULL;

Просмотреть файл

@ -156,7 +156,9 @@ nsXPInstallManager::InitManager(nsIScriptGlobalObject* aGlobalObject, nsXPITrigg
NS_NewURI(getter_AddRefs(uri), NS_ConvertUCS2toUTF8(item->mURL.get()).get());
nsIStreamListener* listener = new CertReader(uri, nsnull, this);
NS_ADDREF(listener);
rv = NS_OpenURI(listener, nsnull, uri);
NS_RELEASE(listener);
if (NS_FAILED(rv)) {
NS_RELEASE_THIS();
@ -740,7 +742,7 @@ nsXPInstallManager::GetDestinationFile(nsString& url, nsILocalFile* *file)
if (NS_SUCCEEDED(rv))
{
temp->AppendNative(NS_LITERAL_CSTRING("tmp.xpi"));
MakeUnique(temp);
temp->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);
*file = temp;
NS_IF_ADDREF(*file);
}
@ -773,7 +775,7 @@ nsXPInstallManager::GetDestinationFile(nsString& url, nsILocalFile* *file)
if (NS_SUCCEEDED(rv))
{
userChrome->Append(leaf);
MakeUnique(userChrome);
userChrome->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);
*file = userChrome;
NS_IF_ADDREF(*file);
}
@ -1083,6 +1085,7 @@ nsXPInstallManager::OnCertAvailable(nsIURI *aURI,
NS_ADDREF(listener);
nsresult rv = NS_OpenURI(listener, nsnull, uri);
NS_ASSERTION(NS_SUCCEEDED(rv), "OpenURI failed");
NS_RELEASE(listener);