mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1744043: Clean up nsJAR r=nika,valentin,extension-reviewers,robwu
Differential Revision: https://phabricator.services.mozilla.com/D132794
This commit is contained in:
parent
7a9646220a
commit
703bd76404
@ -3962,10 +3962,9 @@ nsresult ArrayBufferBuilder::MapToFileInPackage(const nsCString& aFile,
|
||||
nsresult rv;
|
||||
|
||||
// Open Jar file to get related attributes of target file.
|
||||
RefPtr<nsZipArchive> zip = new nsZipArchive();
|
||||
rv = zip->OpenArchive(aJarFile);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
RefPtr<nsZipArchive> zip = nsZipArchive::OpenArchive(aJarFile);
|
||||
if (!zip) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsZipItem* zipItem = zip->GetItem(aFile.get());
|
||||
if (!zipItem) {
|
||||
|
@ -16,7 +16,7 @@ interface nsIUTF8StringEnumerator;
|
||||
interface nsIInputStream;
|
||||
interface nsIFile;
|
||||
|
||||
[scriptable, uuid(fad6f72f-13d8-4e26-9173-53007a4afe71)]
|
||||
[scriptable, builtinclass, uuid(fad6f72f-13d8-4e26-9173-53007a4afe71)]
|
||||
interface nsIZipEntry : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -24,23 +24,23 @@ interface nsIZipEntry : nsISupports
|
||||
* their meanings are defined in the zip file specification at
|
||||
* http://www.pkware.com/business_and_developers/developer/appnote/
|
||||
*/
|
||||
readonly attribute unsigned short compression;
|
||||
[infallible] readonly attribute unsigned short compression;
|
||||
/**
|
||||
* The compressed size of the data in the item.
|
||||
*/
|
||||
readonly attribute unsigned long size;
|
||||
[infallible] readonly attribute unsigned long size;
|
||||
/**
|
||||
* The uncompressed size of the data in the item.
|
||||
*/
|
||||
readonly attribute unsigned long realSize;
|
||||
[infallible] readonly attribute unsigned long realSize;
|
||||
/**
|
||||
* The CRC-32 hash of the file in the entry.
|
||||
*/
|
||||
readonly attribute unsigned long CRC32;
|
||||
[infallible] readonly attribute unsigned long CRC32;
|
||||
/**
|
||||
* True if the name of the entry ends with '/' and false otherwise.
|
||||
*/
|
||||
readonly attribute boolean isDirectory;
|
||||
[infallible] readonly attribute boolean isDirectory;
|
||||
/**
|
||||
* The time at which this item was last modified.
|
||||
*/
|
||||
@ -55,11 +55,11 @@ interface nsIZipEntry : nsISupports
|
||||
* this attribute will be false for the nsIZipEntry for that directory.
|
||||
* It is impossible for a file to be synthetic.
|
||||
*/
|
||||
readonly attribute boolean isSynthetic;
|
||||
[infallible] readonly attribute boolean isSynthetic;
|
||||
/**
|
||||
* The UNIX style file permissions of this item.
|
||||
*/
|
||||
readonly attribute unsigned long permissions;
|
||||
[infallible] readonly attribute unsigned long permissions;
|
||||
};
|
||||
|
||||
[scriptable, uuid(9ba4ef54-e0a0-4f65-9d23-128482448885)]
|
||||
|
@ -26,13 +26,9 @@ using namespace mozilla;
|
||||
|
||||
// The following initialization makes a guess of 10 entries per jarfile.
|
||||
nsJAR::nsJAR()
|
||||
: mZip(new nsZipArchive()),
|
||||
mReleaseTime(PR_INTERVAL_NO_TIMEOUT),
|
||||
mCache(nullptr),
|
||||
: mReleaseTime(PR_INTERVAL_NO_TIMEOUT),
|
||||
mLock("nsJAR::mLock"),
|
||||
mMtime(0),
|
||||
mOpened(false),
|
||||
mSkipArchiveClosing(false) {}
|
||||
mCache(nullptr) {}
|
||||
|
||||
nsJAR::~nsJAR() { Close(); }
|
||||
|
||||
@ -50,7 +46,7 @@ MozExternalRefCountType nsJAR::Release(void) {
|
||||
if (mRefCnt == 2) { // don't use a lock too frequently
|
||||
// Use a mutex here to guarantee mCache is not racing and the target
|
||||
// instance is still valid to increase ref-count.
|
||||
MutexAutoLock lock(mLock);
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
cache = mCache;
|
||||
mCache = nullptr;
|
||||
}
|
||||
@ -79,76 +75,83 @@ MozExternalRefCountType nsJAR::Release(void) {
|
||||
NS_IMETHODIMP
|
||||
nsJAR::Open(nsIFile* zipFile) {
|
||||
NS_ENSURE_ARG_POINTER(zipFile);
|
||||
if (mOpened) return NS_ERROR_FAILURE; // Already open!
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
if (mZip) return NS_ERROR_FAILURE; // Already open!
|
||||
|
||||
mZipFile = zipFile;
|
||||
mOuterZipEntry.Truncate();
|
||||
mOpened = true;
|
||||
|
||||
// The omnijar is special, it is opened early on and closed late
|
||||
// this avoids reopening it
|
||||
RefPtr<nsZipArchive> zip = mozilla::Omnijar::GetReader(zipFile);
|
||||
if (zip) {
|
||||
mZip = zip;
|
||||
mSkipArchiveClosing = true;
|
||||
return NS_OK;
|
||||
if (!zip) {
|
||||
zip = nsZipArchive::OpenArchive(zipFile);
|
||||
}
|
||||
return mZip->OpenArchive(zipFile);
|
||||
mZip = zip;
|
||||
return mZip ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJAR::OpenInner(nsIZipReader* aZipReader, const nsACString& aZipEntry) {
|
||||
NS_ENSURE_ARG_POINTER(aZipReader);
|
||||
if (mOpened) return NS_ERROR_FAILURE; // Already open!
|
||||
nsresult rv;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aZipReader);
|
||||
|
||||
nsCOMPtr<nsIFile> zipFile;
|
||||
rv = aZipReader->GetFile(getter_AddRefs(zipFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsJAR* outerJAR = static_cast<nsJAR*>(aZipReader);
|
||||
RefPtr<nsZipArchive> innerZip =
|
||||
mozilla::Omnijar::GetInnerReader(outerJAR->mZipFile, aZipEntry);
|
||||
mozilla::Omnijar::GetInnerReader(zipFile, aZipEntry);
|
||||
if (innerZip) {
|
||||
mOpened = true;
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
if (mZip) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mZip = innerZip;
|
||||
mSkipArchiveClosing = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool exist;
|
||||
nsresult rv = aZipReader->HasEntry(aZipEntry, &exist);
|
||||
rv = aZipReader->HasEntry(aZipEntry, &exist);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(exist, NS_ERROR_FILE_NOT_FOUND);
|
||||
|
||||
rv = aZipReader->GetFile(getter_AddRefs(mZipFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mOpened = true;
|
||||
|
||||
mOuterZipEntry.Assign(aZipEntry);
|
||||
|
||||
RefPtr<nsZipHandle> handle;
|
||||
rv = nsZipHandle::Init(static_cast<nsJAR*>(aZipReader)->mZip.get(),
|
||||
PromiseFlatCString(aZipEntry).get(),
|
||||
getter_AddRefs(handle));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
{
|
||||
nsJAR* outerJAR = static_cast<nsJAR*>(aZipReader);
|
||||
RecursiveMutexAutoLock outerLock(outerJAR->mLock);
|
||||
rv = nsZipHandle::Init(outerJAR->mZip.get(),
|
||||
PromiseFlatCString(aZipEntry).get(),
|
||||
getter_AddRefs(handle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return mZip->OpenArchive(handle);
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
MOZ_ASSERT(!mZip, "Another thread tried to open this nsJAR racily!");
|
||||
mZipFile = zipFile.forget();
|
||||
mOuterZipEntry.Assign(aZipEntry);
|
||||
mZip = nsZipArchive::OpenArchive(handle);
|
||||
return mZip ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJAR::OpenMemory(void* aData, uint32_t aLength) {
|
||||
NS_ENSURE_ARG_POINTER(aData);
|
||||
if (mOpened) return NS_ERROR_FAILURE; // Already open!
|
||||
|
||||
mOpened = true;
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
if (mZip) return NS_ERROR_FAILURE; // Already open!
|
||||
|
||||
RefPtr<nsZipHandle> handle;
|
||||
nsresult rv = nsZipHandle::Init(static_cast<uint8_t*>(aData), aLength,
|
||||
getter_AddRefs(handle));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return mZip->OpenArchive(handle);
|
||||
mZip = nsZipArchive::OpenArchive(handle);
|
||||
return mZip ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJAR::GetFile(nsIFile** result) {
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
*result = mZipFile;
|
||||
NS_IF_ADDREF(*result);
|
||||
return NS_OK;
|
||||
@ -156,24 +159,21 @@ nsJAR::GetFile(nsIFile** result) {
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJAR::Close() {
|
||||
if (!mOpened) {
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
if (!mZip) {
|
||||
return NS_ERROR_FAILURE; // Never opened or already closed.
|
||||
}
|
||||
|
||||
mOpened = false;
|
||||
|
||||
if (mSkipArchiveClosing) {
|
||||
// Reset state, but don't close the omnijar because we did not open it.
|
||||
mSkipArchiveClosing = false;
|
||||
mZip = new nsZipArchive();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return mZip->CloseArchive();
|
||||
mZip = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJAR::Test(const nsACString& aEntryName) {
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
if (!mZip) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return mZip->Test(
|
||||
aEntryName.IsEmpty() ? nullptr : PromiseFlatCString(aEntryName).get());
|
||||
}
|
||||
@ -182,7 +182,10 @@ NS_IMETHODIMP
|
||||
nsJAR::Extract(const nsACString& aEntryName, nsIFile* outFile) {
|
||||
// nsZipArchive and zlib are not thread safe
|
||||
// we need to use a lock to prevent bug #51267
|
||||
MutexAutoLock lock(mLock);
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
if (!mZip) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsZipItem* item = mZip->GetItem(PromiseFlatCString(aEntryName).get());
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_FILE_TARGET_DOES_NOT_EXIST);
|
||||
@ -219,6 +222,10 @@ nsJAR::Extract(const nsACString& aEntryName, nsIFile* outFile) {
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJAR::GetEntry(const nsACString& aEntryName, nsIZipEntry** result) {
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
if (!mZip) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsZipItem* zipItem = mZip->GetItem(PromiseFlatCString(aEntryName).get());
|
||||
NS_ENSURE_TRUE(zipItem, NS_ERROR_FILE_TARGET_DOES_NOT_EXIST);
|
||||
|
||||
@ -230,6 +237,10 @@ nsJAR::GetEntry(const nsACString& aEntryName, nsIZipEntry** result) {
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJAR::HasEntry(const nsACString& aEntryName, bool* result) {
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
if (!mZip) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
*result = mZip->GetItem(PromiseFlatCString(aEntryName).get()) != nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -238,6 +249,10 @@ NS_IMETHODIMP
|
||||
nsJAR::FindEntries(const nsACString& aPattern,
|
||||
nsIUTF8StringEnumerator** result) {
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
if (!mZip) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsZipFind* find;
|
||||
nsresult rv = mZip->FindInit(
|
||||
@ -260,6 +275,10 @@ nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec,
|
||||
const nsACString& aEntryName,
|
||||
nsIInputStream** result) {
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
if (!mZip) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Watch out for the jar:foo.zip!/ (aDir is empty) top-level special case!
|
||||
nsZipItem* item = nullptr;
|
||||
@ -277,7 +296,8 @@ nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec,
|
||||
if (!item || item->IsDirectory()) {
|
||||
rv = jis->InitDirectory(this, aJarDirSpec, entry.get());
|
||||
} else {
|
||||
rv = jis->InitFile(this, item);
|
||||
RefPtr<nsZipHandle> fd = mZip->GetFD();
|
||||
rv = jis->InitFile(fd, mZip->GetData(item), item);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(*result);
|
||||
@ -285,13 +305,27 @@ nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsJAR::GetJarPath(nsACString& aResult) {
|
||||
nsresult nsJAR::GetFullJarPath(nsACString& aResult) {
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
NS_ENSURE_ARG_POINTER(mZipFile);
|
||||
|
||||
return mZipFile->GetPersistentDescriptor(aResult);
|
||||
nsresult rv = mZipFile->GetPersistentDescriptor(aResult);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mOuterZipEntry.IsEmpty()) {
|
||||
aResult.InsertLiteral("file:", 0);
|
||||
} else {
|
||||
aResult.InsertLiteral("jar:", 0);
|
||||
aResult.AppendLiteral("!/");
|
||||
aResult.Append(mOuterZipEntry);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsJAR::GetNSPRFileDesc(PRFileDesc** aNSPRFileDesc) {
|
||||
RecursiveMutexAutoLock lock(mLock);
|
||||
if (!aNSPRFileDesc) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
@ -530,6 +564,7 @@ nsZipReaderCache::nsZipReaderCache()
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsZipReaderCache::Init(uint32_t cacheSize) {
|
||||
MutexAutoLock lock(mLock);
|
||||
mCacheSize = cacheSize;
|
||||
|
||||
// Register as a memory pressure observer
|
||||
@ -769,20 +804,14 @@ nsresult nsZipReaderCache::ReleaseZip(nsJAR* zip) {
|
||||
|
||||
// remove from hashtable
|
||||
nsAutoCString uri;
|
||||
rv = oldest->GetJarPath(uri);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (oldest->mOuterZipEntry.IsEmpty()) {
|
||||
uri.InsertLiteral("file:", 0);
|
||||
} else {
|
||||
uri.InsertLiteral("jar:", 0);
|
||||
uri.AppendLiteral("!/");
|
||||
uri.Append(oldest->mOuterZipEntry);
|
||||
rv = oldest->GetFullJarPath(uri);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Retrieving and removing the JAR must be done without an extra AddRef
|
||||
// Retrieving and removing the JAR should be done without an extra AddRef
|
||||
// and Release, or we'll trigger nsJAR::Release's magic refcount 1 case
|
||||
// an extra time and trigger a deadlock.
|
||||
// an extra time.
|
||||
RefPtr<nsJAR> removed;
|
||||
mZips.Remove(uri, getter_AddRefs(removed));
|
||||
NS_ASSERTION(removed, "botched");
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "prinrval.h"
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/RecursiveMutex.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsString.h"
|
||||
@ -53,8 +53,10 @@ class nsJAR final : public nsIZipReader {
|
||||
|
||||
NS_DECL_NSIZIPREADER
|
||||
|
||||
nsresult GetJarPath(nsACString& aResult);
|
||||
nsresult GetFullJarPath(nsACString& aResult);
|
||||
|
||||
// These access to mReleaseTime, which is locked by nsZipReaderCache's
|
||||
// mLock, not nsJAR's mLock
|
||||
PRIntervalTime GetReleaseTime() { return mReleaseTime; }
|
||||
|
||||
bool IsReleased() { return mReleaseTime != PR_INTERVAL_NO_TIMEOUT; }
|
||||
@ -64,29 +66,27 @@ class nsJAR final : public nsIZipReader {
|
||||
void ClearReleaseTime() { mReleaseTime = PR_INTERVAL_NO_TIMEOUT; }
|
||||
|
||||
void SetZipReaderCache(nsZipReaderCache* aCache) {
|
||||
mozilla::MutexAutoLock lock(mLock);
|
||||
mozilla::RecursiveMutexAutoLock lock(mLock);
|
||||
mCache = aCache;
|
||||
}
|
||||
|
||||
nsresult GetNSPRFileDesc(PRFileDesc** aNSPRFileDesc);
|
||||
|
||||
protected:
|
||||
//-- Private data members
|
||||
nsCOMPtr<nsIFile> mZipFile; // The zip/jar file on disk
|
||||
nsCString mOuterZipEntry; // The entry in the zip this zip is reading from
|
||||
RefPtr<nsZipArchive> mZip; // The underlying zip archive
|
||||
PRIntervalTime mReleaseTime; // used by nsZipReaderCache for flushing entries
|
||||
nsZipReaderCache*
|
||||
mCache; // if cached, this points to the cache it's contained in
|
||||
mozilla::Mutex mLock; // protect mCache and mZip
|
||||
int64_t mMtime;
|
||||
bool mOpened;
|
||||
|
||||
// true if mZip was adopted from elsewhere and should not be closed by us.
|
||||
bool mSkipArchiveClosing;
|
||||
|
||||
nsresult LoadEntry(const nsACString& aFilename, nsCString& aBuf);
|
||||
int32_t ReadLine(const char** src);
|
||||
|
||||
// used by nsZipReaderCache for flushing entries; access is locked by
|
||||
// nsZipReaderCache's mLock
|
||||
PRIntervalTime mReleaseTime;
|
||||
|
||||
//-- Private data members, protected by mLock
|
||||
mozilla::RecursiveMutex mLock;
|
||||
nsCString mOuterZipEntry; // The entry in the zip this zip is reading from
|
||||
nsCOMPtr<nsIFile> mZipFile; // The zip/jar file on disk
|
||||
RefPtr<nsZipArchive> mZip; // The underlying zip archive
|
||||
nsZipReaderCache*
|
||||
mCache; // if cached, this points to the cache it's contained in
|
||||
};
|
||||
|
||||
/**
|
||||
@ -105,14 +105,14 @@ class nsJARItem : public nsIZipEntry {
|
||||
private:
|
||||
virtual ~nsJARItem() {}
|
||||
|
||||
uint32_t mSize; /* size in original file */
|
||||
uint32_t mRealsize; /* inflated size */
|
||||
uint32_t mCrc32;
|
||||
PRTime mLastModTime;
|
||||
uint16_t mCompression;
|
||||
uint32_t mPermissions;
|
||||
bool mIsDirectory;
|
||||
bool mIsSynthetic;
|
||||
const uint32_t mSize; /* size in original file */
|
||||
const uint32_t mRealsize; /* inflated size */
|
||||
const uint32_t mCrc32;
|
||||
const PRTime mLastModTime;
|
||||
const uint16_t mCompression;
|
||||
const uint32_t mPermissions;
|
||||
const bool mIsDirectory;
|
||||
const bool mIsSynthetic;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -150,6 +150,8 @@ class nsJAREnumerator final : public nsStringEnumeratorBase {
|
||||
class nsZipReaderCache : public nsIZipReaderCache,
|
||||
public nsIObserver,
|
||||
public nsSupportsWeakReference {
|
||||
friend class nsJAR;
|
||||
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIZIPREADERCACHE
|
||||
@ -162,6 +164,8 @@ class nsZipReaderCache : public nsIZipReaderCache,
|
||||
typedef nsRefPtrHashtable<nsCStringHashKey, nsJAR> ZipsHashtable;
|
||||
|
||||
protected:
|
||||
void AssertLockOwned() { mLock.AssertCurrentThreadOwns(); }
|
||||
|
||||
virtual ~nsZipReaderCache();
|
||||
|
||||
mozilla::Mutex mLock MOZ_UNANNOTATED;
|
||||
|
@ -25,17 +25,19 @@ NS_IMPL_ISUPPORTS(nsJARInputStream, nsIInputStream)
|
||||
|
||||
/*----------------------------------------------------------
|
||||
* nsJARInputStream implementation
|
||||
* Takes ownership of |fd|, even on failure
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
nsresult nsJARInputStream::InitFile(nsJAR* aJar, nsZipItem* item) {
|
||||
nsresult nsJARInputStream::InitFile(nsZipHandle* aFd, const uint8_t* aData,
|
||||
nsZipItem* aItem) {
|
||||
nsresult rv = NS_OK;
|
||||
MOZ_ASSERT(aJar, "Argument may not be null");
|
||||
MOZ_ASSERT(item, "Argument may not be null");
|
||||
MOZ_ASSERT(aFd, "Argument may not be null");
|
||||
MOZ_ASSERT(aItem, "Argument may not be null");
|
||||
|
||||
// Mark it as closed, in case something fails in initialisation
|
||||
mMode = MODE_CLOSED;
|
||||
//-- prepare for the compression type
|
||||
switch (item->Compression()) {
|
||||
switch (aItem->Compression()) {
|
||||
case STORED:
|
||||
mMode = MODE_COPY;
|
||||
break;
|
||||
@ -45,23 +47,24 @@ nsresult nsJARInputStream::InitFile(nsJAR* aJar, nsZipItem* item) {
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mMode = MODE_INFLATE;
|
||||
mInCrc = item->CRC32();
|
||||
mInCrc = aItem->CRC32();
|
||||
mOutCrc = crc32(0L, Z_NULL, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
mFd = aFd;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Must keep handle to filepointer and mmap structure as long as we need
|
||||
// access to the mmapped data
|
||||
mFd = aJar->mZip->GetFD();
|
||||
mZs.next_in = (Bytef*)aJar->mZip->GetData(item);
|
||||
mFd = aFd;
|
||||
mZs.next_in = (Bytef*)aData;
|
||||
if (!mZs.next_in) {
|
||||
return NS_ERROR_FILE_CORRUPTED;
|
||||
}
|
||||
mZs.avail_in = item->Size();
|
||||
mOutSize = item->RealSize();
|
||||
mZs.avail_in = aItem->Size();
|
||||
mOutSize = aItem->RealSize();
|
||||
mZs.total_out = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -77,7 +80,8 @@ nsresult nsJARInputStream::InitDirectory(nsJAR* aJar,
|
||||
|
||||
// Keep the zipReader for getting the actual zipItems
|
||||
mJar = aJar;
|
||||
nsZipFind* find;
|
||||
mJar->mLock.AssertCurrentThreadIn();
|
||||
UniquePtr<nsZipFind> find;
|
||||
nsresult rv;
|
||||
// We can get aDir's contents as strings via FindEntries
|
||||
// with the following pattern (see nsIZipReader.findEntries docs)
|
||||
@ -113,7 +117,7 @@ nsresult nsJARInputStream::InitDirectory(nsJAR* aJar,
|
||||
++curr;
|
||||
}
|
||||
nsAutoCString pattern = escDirName + "?*~"_ns + escDirName + "?*/?*"_ns;
|
||||
rv = mJar->mZip->FindInit(pattern.get(), &find);
|
||||
rv = mJar->mZip->FindInit(pattern.get(), getter_Transfers(find));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
const char* name;
|
||||
@ -122,7 +126,6 @@ nsresult nsJARInputStream::InitDirectory(nsJAR* aJar,
|
||||
// Must copy, to make it zero-terminated
|
||||
mArray.AppendElement(nsCString(name, nameLen));
|
||||
}
|
||||
delete find;
|
||||
|
||||
if (rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST && NS_FAILED(rv)) {
|
||||
return NS_ERROR_FAILURE; // no error translation
|
||||
@ -301,6 +304,7 @@ nsresult nsJARInputStream::ReadDirectory(char* aBuffer, uint32_t aCount,
|
||||
uint32_t numRead = CopyDataToBuffer(aBuffer, aCount);
|
||||
|
||||
if (aCount > 0) {
|
||||
RecursiveMutexAutoLock lock(mJar->mLock);
|
||||
// empty the buffer and start writing directory entry lines to it
|
||||
mBuffer.Truncate();
|
||||
mCurPos = 0;
|
||||
|
@ -34,7 +34,7 @@ class nsJARInputStream final : public nsIInputStream {
|
||||
NS_DECL_NSIINPUTSTREAM
|
||||
|
||||
// takes ownership of |fd|, even on failure
|
||||
nsresult InitFile(nsJAR* aJar, nsZipItem* item);
|
||||
nsresult InitFile(nsZipHandle* aFd, const uint8_t* aData, nsZipItem* item);
|
||||
|
||||
nsresult InitDirectory(nsJAR* aJar, const nsACString& aJarDirSpec,
|
||||
const char* aDir);
|
||||
|
@ -5,9 +5,6 @@
|
||||
|
||||
/*
|
||||
* This module implements a simple archive extractor for the PKZIP format.
|
||||
*
|
||||
* The underlying nsZipArchive is NOT thread-safe. Do not pass references
|
||||
* or pointers to it across thread boundaries.
|
||||
*/
|
||||
|
||||
#define READTYPE int32_t
|
||||
@ -337,65 +334,20 @@ nsZipHandle::~nsZipHandle() {
|
||||
//---------------------------------------------
|
||||
// nsZipArchive::OpenArchive
|
||||
//---------------------------------------------
|
||||
nsresult nsZipArchive::OpenArchive(nsZipHandle* aZipHandle, PRFileDesc* aFd) {
|
||||
mFd = aZipHandle;
|
||||
|
||||
//-- get table of contents for archive
|
||||
nsresult rv = BuildFileList(aFd);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (aZipHandle->mFile && XRE_IsParentProcess()) {
|
||||
static char* env = PR_GetEnv("MOZ_JAR_LOG_FILE");
|
||||
if (env) {
|
||||
mUseZipLog = true;
|
||||
|
||||
zipLog.Init(env);
|
||||
// We only log accesses in jar/zip archives within the NS_GRE_DIR
|
||||
// and/or the APK on Android. For the former, we log the archive path
|
||||
// relative to NS_GRE_DIR, and for the latter, the nested-archive
|
||||
// path within the APK. This makes the path match the path of the
|
||||
// archives relative to the packaged dist/$APP_NAME directory in a
|
||||
// build.
|
||||
if (aZipHandle->mFile.IsZip()) {
|
||||
// Nested archive, likely omni.ja in APK.
|
||||
aZipHandle->mFile.GetPath(mURI);
|
||||
} else if (nsDirectoryService::gService) {
|
||||
// We can reach here through the initialization of Omnijar from
|
||||
// XRE_InitCommandLine, which happens before the directory service
|
||||
// is initialized. When that happens, it means the opened archive is
|
||||
// the APK, and we don't care to log that one, so we just skip
|
||||
// when the directory service is not initialized.
|
||||
nsCOMPtr<nsIFile> dir = aZipHandle->mFile.GetBaseFile();
|
||||
nsCOMPtr<nsIFile> gre_dir;
|
||||
nsAutoCString path;
|
||||
if (NS_SUCCEEDED(nsDirectoryService::gService->Get(
|
||||
NS_GRE_DIR, NS_GET_IID(nsIFile), getter_AddRefs(gre_dir)))) {
|
||||
nsAutoCString leaf;
|
||||
nsCOMPtr<nsIFile> parent;
|
||||
while (NS_SUCCEEDED(dir->GetNativeLeafName(leaf)) &&
|
||||
NS_SUCCEEDED(dir->GetParent(getter_AddRefs(parent)))) {
|
||||
if (!parent) {
|
||||
break;
|
||||
}
|
||||
dir = parent;
|
||||
if (path.Length()) {
|
||||
path.Insert('/', 0);
|
||||
}
|
||||
path.Insert(leaf, 0);
|
||||
bool equals;
|
||||
if (NS_SUCCEEDED(dir->Equals(gre_dir, &equals)) && equals) {
|
||||
mURI.Assign(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* static */
|
||||
already_AddRefed<nsZipArchive> nsZipArchive::OpenArchive(
|
||||
nsZipHandle* aZipHandle, PRFileDesc* aFd) {
|
||||
nsresult rv;
|
||||
RefPtr<nsZipArchive> self(new nsZipArchive(aZipHandle, aFd, rv));
|
||||
LOG(("ZipHandle::OpenArchive[%p]", self.get()));
|
||||
if (NS_FAILED(rv)) {
|
||||
self = nullptr;
|
||||
}
|
||||
return rv;
|
||||
return self.forget();
|
||||
}
|
||||
|
||||
nsresult nsZipArchive::OpenArchive(nsIFile* aFile) {
|
||||
/* static */
|
||||
already_AddRefed<nsZipArchive> nsZipArchive::OpenArchive(nsIFile* aFile) {
|
||||
RefPtr<nsZipHandle> handle;
|
||||
#if defined(XP_WIN)
|
||||
mozilla::AutoFDClose fd;
|
||||
@ -403,7 +355,7 @@ nsresult nsZipArchive::OpenArchive(nsIFile* aFile) {
|
||||
#else
|
||||
nsresult rv = nsZipHandle::Init(aFile, getter_AddRefs(handle));
|
||||
#endif
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) return nullptr;
|
||||
|
||||
#if defined(XP_WIN)
|
||||
return OpenArchive(handle, fd.get());
|
||||
@ -440,28 +392,6 @@ nsresult nsZipArchive::Test(const char* aEntryName) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
// nsZipArchive::CloseArchive
|
||||
//---------------------------------------------
|
||||
nsresult nsZipArchive::CloseArchive() {
|
||||
MutexAutoLock lock(mLock);
|
||||
if (mFd) {
|
||||
mArena.Clear();
|
||||
mFd = nullptr;
|
||||
}
|
||||
|
||||
// CAUTION:
|
||||
// We don't need to delete each of the nsZipItem as the memory for
|
||||
// the zip item and the filename it holds are both allocated from the Arena.
|
||||
// Hence, destroying the Arena is like destroying all the memory
|
||||
// for all the nsZipItem in one shot. But if the ~nsZipItem is doing
|
||||
// anything more than cleaning up memory, we should start calling it.
|
||||
// Let us also cleanup the mFiles table for re-use on the next 'open' call
|
||||
memset(mFiles, 0, sizeof(mFiles));
|
||||
mBuiltSynthetics = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
// nsZipArchive::GetItem
|
||||
//---------------------------------------------
|
||||
@ -504,6 +434,7 @@ nsZipItem* nsZipArchive::GetItem(const char* aEntryName) {
|
||||
//---------------------------------------------
|
||||
nsresult nsZipArchive::ExtractFile(nsZipItem* item, nsIFile* outFile,
|
||||
PRFileDesc* aFd) {
|
||||
MutexAutoLock lock(mLock);
|
||||
if (!item) return NS_ERROR_ILLEGAL_VALUE;
|
||||
if (!mFd) return NS_ERROR_FAILURE;
|
||||
|
||||
@ -651,7 +582,8 @@ nsZipItem* nsZipArchive::CreateZipItem() {
|
||||
// nsZipArchive::BuildFileList
|
||||
//---------------------------------------------
|
||||
nsresult nsZipArchive::BuildFileList(PRFileDesc* aFd) {
|
||||
MutexAutoLock lock(mLock);
|
||||
// We're only called from the constructor, but need to call
|
||||
// CreateZipItem(), which touches locked data, and modify mFiles.
|
||||
|
||||
// Get archive size using end pos
|
||||
const uint8_t* buf;
|
||||
@ -738,18 +670,6 @@ nsresult nsZipArchive::BuildFileList(PRFileDesc* aFd) {
|
||||
return NS_ERROR_FILE_CORRUPTED;
|
||||
}
|
||||
|
||||
// Make the comment available for consumers.
|
||||
if ((endp >= buf) && (endp - buf >= ZIPEND_SIZE)) {
|
||||
ZipEnd* zipend = (ZipEnd*)buf;
|
||||
|
||||
buf += ZIPEND_SIZE;
|
||||
uint16_t commentlen = xtoint(zipend->commentfield_len);
|
||||
if (endp - buf >= commentlen) {
|
||||
mCommentPtr = (const char*)buf;
|
||||
mCommentLen = commentlen;
|
||||
}
|
||||
}
|
||||
|
||||
MMAP_FAULT_HANDLER_CATCH(NS_ERROR_FAILURE)
|
||||
return NS_OK;
|
||||
}
|
||||
@ -821,10 +741,10 @@ nsresult nsZipArchive::BuildSynthetics() {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsZipHandle* nsZipArchive::GetFD() {
|
||||
if (!mFd) return nullptr;
|
||||
return mFd.get();
|
||||
}
|
||||
//---------------------------------------------
|
||||
// nsZipArchive::GetFD
|
||||
//---------------------------------------------
|
||||
nsZipHandle* nsZipArchive::GetFD() const { return mFd.get(); }
|
||||
|
||||
//---------------------------------------------
|
||||
// nsZipArchive::GetDataOffset
|
||||
@ -875,14 +795,6 @@ const uint8_t* nsZipArchive::GetData(nsZipItem* aItem) {
|
||||
return mFd->mFileData + offset;
|
||||
}
|
||||
|
||||
// nsZipArchive::GetComment
|
||||
bool nsZipArchive::GetComment(nsACString& aComment) {
|
||||
MMAP_FAULT_HANDLER_BEGIN_BUFFER(mCommentPtr, mCommentLen)
|
||||
aComment.Assign(mCommentPtr, mCommentLen);
|
||||
MMAP_FAULT_HANDLER_CATCH(false)
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
// nsZipArchive::SizeOfMapping
|
||||
//---------------------------------------------
|
||||
@ -892,22 +804,71 @@ int64_t nsZipArchive::SizeOfMapping() { return mFd ? mFd->SizeOfMapping() : 0; }
|
||||
// nsZipArchive constructor and destructor
|
||||
//------------------------------------------
|
||||
|
||||
nsZipArchive::nsZipArchive()
|
||||
: mRefCnt(0),
|
||||
mCommentPtr(nullptr),
|
||||
mCommentLen(0),
|
||||
mBuiltSynthetics(false),
|
||||
mUseZipLog(false) {
|
||||
nsZipArchive::nsZipArchive(nsZipHandle* aZipHandle, PRFileDesc* aFd,
|
||||
nsresult& aRv)
|
||||
: mRefCnt(0), mFd(aZipHandle), mUseZipLog(false), mBuiltSynthetics(false) {
|
||||
// initialize the table to nullptr
|
||||
memset(mFiles, 0, sizeof(mFiles));
|
||||
|
||||
//-- get table of contents for archive
|
||||
aRv = BuildFileList(aFd);
|
||||
if (NS_FAILED(aRv)) {
|
||||
return; // whomever created us must destroy us in this case
|
||||
}
|
||||
if (aZipHandle->mFile && XRE_IsParentProcess()) {
|
||||
static char* env = PR_GetEnv("MOZ_JAR_LOG_FILE");
|
||||
if (env) {
|
||||
mUseZipLog = true;
|
||||
|
||||
zipLog.Init(env);
|
||||
// We only log accesses in jar/zip archives within the NS_GRE_DIR
|
||||
// and/or the APK on Android. For the former, we log the archive path
|
||||
// relative to NS_GRE_DIR, and for the latter, the nested-archive
|
||||
// path within the APK. This makes the path match the path of the
|
||||
// archives relative to the packaged dist/$APP_NAME directory in a
|
||||
// build.
|
||||
if (aZipHandle->mFile.IsZip()) {
|
||||
// Nested archive, likely omni.ja in APK.
|
||||
aZipHandle->mFile.GetPath(mURI);
|
||||
} else if (nsDirectoryService::gService) {
|
||||
// We can reach here through the initialization of Omnijar from
|
||||
// XRE_InitCommandLine, which happens before the directory service
|
||||
// is initialized. When that happens, it means the opened archive is
|
||||
// the APK, and we don't care to log that one, so we just skip
|
||||
// when the directory service is not initialized.
|
||||
nsCOMPtr<nsIFile> dir = aZipHandle->mFile.GetBaseFile();
|
||||
nsCOMPtr<nsIFile> gre_dir;
|
||||
nsAutoCString path;
|
||||
if (NS_SUCCEEDED(nsDirectoryService::gService->Get(
|
||||
NS_GRE_DIR, NS_GET_IID(nsIFile), getter_AddRefs(gre_dir)))) {
|
||||
nsAutoCString leaf;
|
||||
nsCOMPtr<nsIFile> parent;
|
||||
while (NS_SUCCEEDED(dir->GetNativeLeafName(leaf)) &&
|
||||
NS_SUCCEEDED(dir->GetParent(getter_AddRefs(parent)))) {
|
||||
if (!parent) {
|
||||
break;
|
||||
}
|
||||
dir = parent;
|
||||
if (path.Length()) {
|
||||
path.Insert('/', 0);
|
||||
}
|
||||
path.Insert(leaf, 0);
|
||||
bool equals;
|
||||
if (NS_SUCCEEDED(dir->Equals(gre_dir, &equals)) && equals) {
|
||||
mURI.Assign(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsZipArchive)
|
||||
NS_IMPL_RELEASE(nsZipArchive)
|
||||
|
||||
nsZipArchive::~nsZipArchive() {
|
||||
CloseArchive();
|
||||
|
||||
if (mUseZipLog) {
|
||||
zipLog.Release();
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ struct PRFileDesc;
|
||||
* 'MT''safe' reading from the zipfile is performed through JARInputStream,
|
||||
* which maintains its own file descriptor, allowing for multiple reads
|
||||
* concurrently from the same zip file.
|
||||
*
|
||||
* nsZipArchives are accessed from multiple threads.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -85,21 +87,15 @@ class nsZipArchive final {
|
||||
public:
|
||||
static const char* sFileCorruptedReason;
|
||||
|
||||
/** constructing does not open the archive. See OpenArchive() */
|
||||
nsZipArchive();
|
||||
|
||||
/**
|
||||
* OpenArchive
|
||||
*
|
||||
* It's an error to call this more than once on the same nsZipArchive
|
||||
* object. If we were allowed to use exceptions this would have been
|
||||
* part of the constructor
|
||||
*
|
||||
* @param aZipHandle The nsZipHandle used to access the zip
|
||||
* @param aFd Optional PRFileDesc for Windows readahead optimization
|
||||
* @return status code
|
||||
*/
|
||||
nsresult OpenArchive(nsZipHandle* aZipHandle, PRFileDesc* aFd = nullptr);
|
||||
static already_AddRefed<nsZipArchive> OpenArchive(nsZipHandle* aZipHandle,
|
||||
PRFileDesc* aFd = nullptr);
|
||||
|
||||
/**
|
||||
* OpenArchive
|
||||
@ -109,7 +105,7 @@ class nsZipArchive final {
|
||||
* @param aFile The file used to access the zip
|
||||
* @return status code
|
||||
*/
|
||||
nsresult OpenArchive(nsIFile* aFile);
|
||||
static already_AddRefed<nsZipArchive> OpenArchive(nsIFile* aFile);
|
||||
|
||||
/**
|
||||
* Test the integrity of items in this archive by running
|
||||
@ -122,11 +118,6 @@ class nsZipArchive final {
|
||||
*/
|
||||
nsresult Test(const char* aEntryName);
|
||||
|
||||
/**
|
||||
* Closes an open archive.
|
||||
*/
|
||||
nsresult CloseArchive();
|
||||
|
||||
/**
|
||||
* GetItem
|
||||
* @param aEntryName Name of file in the archive
|
||||
@ -163,7 +154,7 @@ class nsZipArchive final {
|
||||
/*
|
||||
* Gets an undependent handle to the mapped file.
|
||||
*/
|
||||
nsZipHandle* GetFD();
|
||||
nsZipHandle* GetFD() const;
|
||||
|
||||
/**
|
||||
* Gets the data offset.
|
||||
@ -179,8 +170,6 @@ class nsZipArchive final {
|
||||
*/
|
||||
const uint8_t* GetData(nsZipItem* aItem);
|
||||
|
||||
bool GetComment(nsACString& aComment);
|
||||
|
||||
/**
|
||||
* Gets the amount of memory taken up by the archive's mapping.
|
||||
* @return the size
|
||||
@ -194,30 +183,28 @@ class nsZipArchive final {
|
||||
NS_METHOD_(MozExternalRefCountType) Release(void);
|
||||
|
||||
private:
|
||||
nsZipArchive(nsZipHandle* aZipHandle, PRFileDesc* aFd, nsresult& aRv);
|
||||
|
||||
//--- private members ---
|
||||
mozilla::ThreadSafeAutoRefCnt mRefCnt; /* ref count */
|
||||
NS_DECL_OWNINGTHREAD
|
||||
|
||||
nsZipItem* mFiles[ZIP_TABSIZE];
|
||||
mozilla::ArenaAllocator<1024, sizeof(void*)> mArena;
|
||||
|
||||
const char* mCommentPtr;
|
||||
uint16_t mCommentLen;
|
||||
|
||||
// Whether we synthesized the directory entries
|
||||
bool mBuiltSynthetics;
|
||||
|
||||
// These fields are all effectively const after the constructor
|
||||
// file handle
|
||||
RefPtr<nsZipHandle> mFd;
|
||||
|
||||
const RefPtr<nsZipHandle> mFd;
|
||||
// file URI, for logging
|
||||
nsCString mURI;
|
||||
|
||||
// Is true if we use zipLog to log accesses in jar/zip archives. This helper
|
||||
// variable avoids grabbing zipLog's lock when not necessary.
|
||||
// Effectively const after constructor
|
||||
bool mUseZipLog;
|
||||
|
||||
mozilla::Mutex mLock{"nsZipArchive"};
|
||||
// all of the following members are guarded by mLock:
|
||||
nsZipItem* mFiles[ZIP_TABSIZE];
|
||||
mozilla::ArenaAllocator<1024, sizeof(void*)> mArena;
|
||||
// Whether we synthesized the directory entries
|
||||
bool mBuiltSynthetics;
|
||||
|
||||
private:
|
||||
//--- private methods ---
|
||||
|
@ -15,6 +15,10 @@ function run_test() {
|
||||
);
|
||||
zipreader.open(file);
|
||||
zipreader.close();
|
||||
var entries = zipreader.findEntries("*.*");
|
||||
Assert.ok(!entries.hasMore()); // this shouldn't crash
|
||||
// this should error out and not crash
|
||||
Assert.throws(
|
||||
() => zipreader.findEntries("*.*"),
|
||||
/NS_ERROR_FAILURE/,
|
||||
"Should error out on a closed zipreader"
|
||||
);
|
||||
}
|
||||
|
@ -310,6 +310,12 @@ var AddonTestUtils = {
|
||||
}
|
||||
|
||||
testScope.registerCleanupFunction(() => {
|
||||
// Force a GC to ensure that anything holding a ref to temp file releases it.
|
||||
// XXX This shouldn't be needed here, since cleanupTempXPIs() does a GC if
|
||||
// something fails; see bug 1761255
|
||||
this.info(`Force a GC`);
|
||||
Cu.forceGC();
|
||||
|
||||
this.cleanupTempXPIs();
|
||||
|
||||
let ignoreEntries = new Set();
|
||||
|
@ -151,8 +151,7 @@ nsresult FileLocation::GetData(Data& aData) {
|
||||
}
|
||||
aData.mZip = mBaseZip;
|
||||
if (!aData.mZip) {
|
||||
aData.mZip = new nsZipArchive();
|
||||
aData.mZip->OpenArchive(mBaseFile);
|
||||
aData.mZip = nsZipArchive::OpenArchive(mBaseFile);
|
||||
}
|
||||
aData.mItem = aData.mZip->GetItem(mPath.get());
|
||||
if (aData.mItem) {
|
||||
|
@ -26,11 +26,9 @@ static const char* sProp[2] = {NS_GRE_DIR, NS_XPCOM_CURRENT_PROCESS_DIR};
|
||||
|
||||
void Omnijar::CleanUpOne(Type aType) {
|
||||
if (sReader[aType]) {
|
||||
sReader[aType]->CloseArchive();
|
||||
sReader[aType] = nullptr;
|
||||
}
|
||||
if (sOuterReader[aType]) {
|
||||
sOuterReader[aType]->CloseArchive();
|
||||
sOuterReader[aType] = nullptr;
|
||||
}
|
||||
sPath[aType] = nullptr;
|
||||
@ -77,8 +75,8 @@ void Omnijar::InitOne(nsIFile* aPath, Type aType) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<nsZipArchive> zipReader = new nsZipArchive();
|
||||
if (NS_FAILED(zipReader->OpenArchive(file))) {
|
||||
RefPtr<nsZipArchive> zipReader = nsZipArchive::OpenArchive(file);
|
||||
if (!zipReader) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -87,8 +85,8 @@ void Omnijar::InitOne(nsIFile* aPath, Type aType) {
|
||||
if (NS_SUCCEEDED(nsZipHandle::Init(zipReader, MOZ_STRINGIFY(OMNIJAR_NAME),
|
||||
getter_AddRefs(handle)))) {
|
||||
outerReader = zipReader;
|
||||
zipReader = new nsZipArchive();
|
||||
if (NS_FAILED(zipReader->OpenArchive(handle))) {
|
||||
zipReader = nsZipArchive::OpenArchive(handle);
|
||||
if (!zipReader) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user