diff options
author | Pale Moon <git-repo@palemoon.org> | 2018-01-28 21:51:59 +0100 |
---|---|---|
committer | Pale Moon <git-repo@palemoon.org> | 2018-01-28 21:51:59 +0100 |
commit | d3e1e49a9c82a07f25ca990f349f5595f6848b35 (patch) | |
tree | 0999badb5e7d29978280da8243964400cc40da4d /modules/libjar/nsJAR.cpp | |
parent | 0de6888e0098b6073dbf244e82de33d351ee6833 (diff) | |
download | palemoon-gre-d3e1e49a9c82a07f25ca990f349f5595f6848b35.tar.gz |
Avoid potential race condition in nsJAR.
Diffstat (limited to 'modules/libjar/nsJAR.cpp')
-rw-r--r-- | modules/libjar/nsJAR.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/modules/libjar/nsJAR.cpp b/modules/libjar/nsJAR.cpp index c7f5ebc96..aa673ea50 100644 --- a/modules/libjar/nsJAR.cpp +++ b/modules/libjar/nsJAR.cpp @@ -97,11 +97,27 @@ NS_IMPL_QUERY_INTERFACE(nsJAR, nsIZipReader) NS_IMPL_ADDREF(nsJAR) // Custom Release method works with nsZipReaderCache... +// Release might be called from multi-thread, we have to +// take this function carefully to avoid delete-after-use. MozExternalRefCountType nsJAR::Release(void) { nsrefcnt count; NS_PRECONDITION(0 != mRefCnt, "dup release"); - count = --mRefCnt; + + nsRefPtr<nsZipReaderCache> cache; + 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); + cache = mCache; + mCache = nullptr; + } + if (cache) { + nsresult rv = cache->ReleaseZip(this); + MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to release zip file"); + } + + count = --mRefCnt; // don't access any member variable after this line NS_LOG_RELEASE(this, count, "nsJAR"); if (0 == count) { mRefCnt = 1; /* stabilize */ @@ -110,13 +126,7 @@ MozExternalRefCountType nsJAR::Release(void) delete this; return 0; } - else if (1 == count && mCache) { -#ifdef DEBUG - nsresult rv = -#endif - mCache->ReleaseZip(this); - NS_ASSERTION(NS_SUCCEEDED(rv), "failed to release zip file"); - } + return count; } |