diff --git a/modules/libjar/nsJAR.cpp b/modules/libjar/nsJAR.cpp index edfe08dfb78c..a8b1127da268 100644 --- a/modules/libjar/nsJAR.cpp +++ b/modules/libjar/nsJAR.cpp @@ -326,7 +326,6 @@ nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec, NS_ENSURE_ARG_POINTER(result); // Watch out for the jar:foo.zip!/ (aDir is empty) top-level special case! - PRFileDesc *fd = nsnull; nsZipItem *item = nsnull; if (*aEntryName) { // First check if item exists in jar @@ -343,12 +342,19 @@ nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec, rv = jis->InitDirectory(&mZip, aJarDirSpec, aEntryName); } else { // Open jarfile, to get its own filedescriptor for the stream + // XXX The file may have been overwritten, so |item| might not be + // valid. We really want to work from inode rather than file name. + PRFileDesc *fd = nsnull; fd = OpenFile(); - rv = fd ? jis->InitFile(&mZip, item, fd) : NS_ERROR_FAILURE; + if (fd) { + rv = jis->InitFile(&mZip, item, fd); + // |jis| now owns |fd| + } else { + rv = NS_ERROR_FAILURE; + } } if (NS_FAILED(rv)) { NS_RELEASE(*result); - if (fd) PR_Close(fd); } return rv; } diff --git a/modules/libjar/nsJARInputStream.cpp b/modules/libjar/nsJARInputStream.cpp index 9c6aab5ee4c0..b587c97139d8 100644 --- a/modules/libjar/nsJARInputStream.cpp +++ b/modules/libjar/nsJARInputStream.cpp @@ -61,6 +61,9 @@ nsJARInputStream::InitFile(nsZipArchive* aZip, nsZipItem *item, PRFileDesc *fd) { nsresult rv; + // Keep the file handle, even on failure + mFd = fd; + NS_ENSURE_ARG_POINTER(aZip); NS_ENSURE_ARG_POINTER(item); NS_ENSURE_ARG_POINTER(fd); @@ -68,9 +71,6 @@ nsJARInputStream::InitFile(nsZipArchive* aZip, nsZipItem *item, PRFileDesc *fd) // Mark it as closed, in case something fails in initialisation mClosed = PR_TRUE; - // Keep the file handle - mFd = fd; - // Keep the important bits of nsZipItem only mInSize = item->size; diff --git a/modules/libjar/nsJARInputStream.h b/modules/libjar/nsJARInputStream.h index 12cbd68f97f6..604b0d6555c3 100644 --- a/modules/libjar/nsJARInputStream.h +++ b/modules/libjar/nsJARInputStream.h @@ -60,7 +60,9 @@ class nsJARInputStream : public nsIInputStream NS_DECL_ISUPPORTS NS_DECL_NSIINPUTSTREAM + // takes ownership of |fd|, even on failure nsresult InitFile(nsZipArchive* aZip, nsZipItem *item, PRFileDesc *fd); + nsresult InitDirectory(nsZipArchive* aZip, const nsACString& aJarDirSpec, const char* aDir);