michael@0: /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsJAR_h_ michael@0: #define nsJAR_h_ michael@0: michael@0: #include "nscore.h" michael@0: #include "prio.h" michael@0: #include "plstr.h" michael@0: #include "prlog.h" michael@0: #include "prinrval.h" michael@0: michael@0: #include "mozilla/Mutex.h" michael@0: #include "nsIComponentManager.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsClassHashtable.h" michael@0: #include "nsString.h" michael@0: #include "nsIFile.h" michael@0: #include "nsStringEnumerator.h" michael@0: #include "nsHashKeys.h" michael@0: #include "nsRefPtrHashtable.h" michael@0: #include "nsTHashtable.h" michael@0: #include "nsIZipReader.h" michael@0: #include "nsZipArchive.h" michael@0: #include "nsICertificatePrincipal.h" michael@0: #include "nsISignatureVerifier.h" michael@0: #include "nsIObserverService.h" michael@0: #include "nsWeakReference.h" michael@0: #include "nsIObserver.h" michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: class nsIInputStream; michael@0: class nsJARManifestItem; michael@0: class nsZipReaderCache; michael@0: michael@0: /* For mManifestStatus */ michael@0: typedef enum michael@0: { michael@0: JAR_MANIFEST_NOT_PARSED = 0, michael@0: JAR_VALID_MANIFEST = 1, michael@0: JAR_INVALID_SIG = 2, michael@0: JAR_INVALID_UNKNOWN_CA = 3, michael@0: JAR_INVALID_MANIFEST = 4, michael@0: JAR_INVALID_ENTRY = 5, michael@0: JAR_NO_MANIFEST = 6, michael@0: JAR_NOT_SIGNED = 7 michael@0: } JARManifestStatusType; michael@0: michael@0: /*------------------------------------------------------------------------- michael@0: * Class nsJAR declaration. michael@0: * nsJAR serves as an XPCOM wrapper for nsZipArchive with the addition of michael@0: * JAR manifest file parsing. michael@0: *------------------------------------------------------------------------*/ michael@0: class nsJAR : public nsIZipReader michael@0: { michael@0: // Allows nsJARInputStream to call the verification functions michael@0: friend class nsJARInputStream; michael@0: // Allows nsZipReaderCache to access mOuterZipEntry michael@0: friend class nsZipReaderCache; michael@0: michael@0: public: michael@0: michael@0: nsJAR(); michael@0: virtual ~nsJAR(); michael@0: michael@0: NS_DEFINE_STATIC_CID_ACCESSOR( NS_ZIPREADER_CID ) michael@0: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: michael@0: NS_DECL_NSIZIPREADER michael@0: michael@0: nsresult GetJarPath(nsACString& aResult); michael@0: michael@0: PRIntervalTime GetReleaseTime() { michael@0: return mReleaseTime; michael@0: } michael@0: michael@0: bool IsReleased() { michael@0: return mReleaseTime != PR_INTERVAL_NO_TIMEOUT; michael@0: } michael@0: michael@0: void SetReleaseTime() { michael@0: mReleaseTime = PR_IntervalNow(); michael@0: } michael@0: michael@0: void ClearReleaseTime() { michael@0: mReleaseTime = PR_INTERVAL_NO_TIMEOUT; michael@0: } michael@0: michael@0: void SetZipReaderCache(nsZipReaderCache* cache) { michael@0: mCache = cache; michael@0: } michael@0: michael@0: protected: michael@0: typedef nsClassHashtable ManifestDataHashtable; michael@0: michael@0: //-- Private data members michael@0: nsCOMPtr mZipFile; // The zip/jar file on disk michael@0: nsCString mOuterZipEntry; // The entry in the zip this zip is reading from michael@0: nsRefPtr mZip; // The underlying zip archive michael@0: ManifestDataHashtable mManifestData; // Stores metadata for each entry michael@0: bool mParsedManifest; // True if manifest has been parsed michael@0: nsCOMPtr mPrincipal; // The entity which signed this file michael@0: int16_t mGlobalStatus; // Global signature verification status michael@0: PRIntervalTime mReleaseTime; // used by nsZipReaderCache for flushing entries michael@0: nsZipReaderCache* mCache; // if cached, this points to the cache it's contained in michael@0: mozilla::Mutex mLock; michael@0: int64_t mMtime; michael@0: int32_t mTotalItemsInManifest; michael@0: bool mOpened; michael@0: michael@0: nsresult ParseManifest(); michael@0: void ReportError(const nsACString &aFilename, int16_t errorCode); michael@0: nsresult LoadEntry(const nsACString &aFilename, char** aBuf, michael@0: uint32_t* aBufLen = nullptr); michael@0: int32_t ReadLine(const char** src); michael@0: nsresult ParseOneFile(const char* filebuf, int16_t aFileType); michael@0: nsresult VerifyEntry(nsJARManifestItem* aEntry, const char* aEntryData, michael@0: uint32_t aLen); michael@0: michael@0: nsresult CalculateDigest(const char* aInBuf, uint32_t aInBufLen, michael@0: nsCString& digest); michael@0: }; michael@0: michael@0: /** michael@0: * nsJARItem michael@0: * michael@0: * An individual JAR entry. A set of nsJARItems matching a michael@0: * supplied pattern are returned in a nsJAREnumerator. michael@0: */ michael@0: class nsJARItem : public nsIZipEntry michael@0: { michael@0: public: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_NSIZIPENTRY michael@0: michael@0: nsJARItem(nsZipItem* aZipItem); michael@0: virtual ~nsJARItem() {} michael@0: michael@0: private: michael@0: uint32_t mSize; /* size in original file */ michael@0: uint32_t mRealsize; /* inflated size */ michael@0: uint32_t mCrc32; michael@0: PRTime mLastModTime; michael@0: uint16_t mCompression; michael@0: uint32_t mPermissions; michael@0: bool mIsDirectory; michael@0: bool mIsSynthetic; michael@0: }; michael@0: michael@0: /** michael@0: * nsJAREnumerator michael@0: * michael@0: * Enumerates a list of files in a zip archive michael@0: * (based on a pattern match in its member nsZipFind). michael@0: */ michael@0: class nsJAREnumerator MOZ_FINAL : public nsIUTF8StringEnumerator michael@0: { michael@0: public: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_NSIUTF8STRINGENUMERATOR michael@0: michael@0: nsJAREnumerator(nsZipFind *aFind) : mFind(aFind), mName(nullptr) { michael@0: NS_ASSERTION(mFind, "nsJAREnumerator: Missing zipFind."); michael@0: } michael@0: michael@0: private: michael@0: nsZipFind *mFind; michael@0: const char* mName; // pointer to an name owned by mArchive -- DON'T delete michael@0: uint16_t mNameLen; michael@0: michael@0: ~nsJAREnumerator() { delete mFind; } michael@0: }; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: #if defined(DEBUG_warren) || defined(DEBUG_jband) michael@0: #define ZIP_CACHE_HIT_RATE michael@0: #endif michael@0: michael@0: class nsZipReaderCache : public nsIZipReaderCache, public nsIObserver, michael@0: public nsSupportsWeakReference michael@0: { michael@0: public: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_NSIZIPREADERCACHE michael@0: NS_DECL_NSIOBSERVER michael@0: michael@0: nsZipReaderCache(); michael@0: virtual ~nsZipReaderCache(); michael@0: michael@0: nsresult ReleaseZip(nsJAR* reader); michael@0: michael@0: typedef nsRefPtrHashtable ZipsHashtable; michael@0: michael@0: protected: michael@0: michael@0: mozilla::Mutex mLock; michael@0: uint32_t mCacheSize; michael@0: ZipsHashtable mZips; michael@0: michael@0: #ifdef ZIP_CACHE_HIT_RATE michael@0: uint32_t mZipCacheLookups; michael@0: uint32_t mZipCacheHits; michael@0: uint32_t mZipCacheFlushes; michael@0: uint32_t mZipSyncMisses; michael@0: #endif michael@0: michael@0: }; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: #endif /* nsJAR_h_ */