Bug 945152 - Part 3-1: New libjar APIs. r=aklotz
authorShian-Yow Wu <swu@mozilla.com>
Fri, 16 May 2014 13:34:43 +0800
changeset 202646 39de1d829277fa68d0c0a8535c02104917c03f84
parent 202645 db356f641d0407496900d816cc8dd8b3f8368750
child 202647 ff88f30654322bf07bb96297f0b99d791d1388e5
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz
bugs945152
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 945152 - Part 3-1: New libjar APIs. r=aklotz
modules/libjar/nsIJARChannel.idl
modules/libjar/nsJARChannel.cpp
modules/libjar/nsZipArchive.cpp
modules/libjar/nsZipArchive.h
netwerk/protocol/app/AppProtocolHandler.cpp
--- a/modules/libjar/nsIJARChannel.idl
+++ b/modules/libjar/nsIJARChannel.idl
@@ -1,23 +1,30 @@
 /* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIChannel.idl"
 
-[scriptable, builtinclass, uuid(6e6cc56d-51eb-4299-a795-dcfd1229ab3d)]
-interface nsIJARChannel : nsIChannel 
+interface nsIFile;
+
+[scriptable, builtinclass, uuid(063e9698-ec67-4fe2-aa19-d21505beaa61)]
+interface nsIJARChannel : nsIChannel
 {
     /**
      * Returns TRUE if the JAR file is not safe (if the content type reported
      * by the server for a remote JAR is not of an expected type).  Scripting,
      * redirects, and plugins should be disabled when loading from this
      * channel.
      */
     [infallible] readonly attribute boolean isUnsafe;
 
     /**
      * Forces the uri to be a app:// uri.
      */
     void setAppURI(in nsIURI uri);
+
+    /**
+     * Returns the JAR file.
+     */
+    readonly attribute nsIFile jarFile;
 };
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -820,16 +820,23 @@ nsJARChannel::SetAppURI(nsIURI *aURI) {
     if (!scheme.EqualsLiteral("app")) {
         return NS_ERROR_INVALID_ARG;
     }
 
     mAppURI = aURI;
     return NS_OK;
 }
 
+NS_IMETHODIMP
+nsJARChannel::GetJarFile(nsIFile **aFile)
+{
+    NS_IF_ADDREF(*aFile = mJarFile);
+    return NS_OK;
+}
+
 //-----------------------------------------------------------------------------
 // nsIDownloadObserver
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsJARChannel::OnDownloadComplete(nsIDownloader *downloader,
                                  nsIRequest    *request,
                                  nsISupports   *context,
--- a/modules/libjar/nsZipArchive.cpp
+++ b/modules/libjar/nsZipArchive.cpp
@@ -758,47 +758,60 @@ MOZ_WIN_MEM_TRY_CATCH(return NS_ERROR_FA
 nsZipHandle* nsZipArchive::GetFD()
 {
   if (!mFd)
     return nullptr;
   return mFd.get();
 }
 
 //---------------------------------------------
-// nsZipArchive::GetData
+// nsZipArchive::GetDataOffset
 //---------------------------------------------
-const uint8_t* nsZipArchive::GetData(nsZipItem* aItem)
+uint32_t nsZipArchive::GetDataOffset(nsZipItem* aItem)
 {
   PR_ASSERT (aItem);
 MOZ_WIN_MEM_TRY_BEGIN
   //-- read local header to get variable length values and calculate
   //-- the real data offset
   uint32_t len = mFd->mLen;
   const uint8_t* data = mFd->mFileData;
   uint32_t offset = aItem->LocalOffset();
   if (offset + ZIPLOCAL_SIZE > len)
-    return nullptr;
+    return 0;
 
   // -- check signature before using the structure, in case the zip file is corrupt
   ZipLocal* Local = (ZipLocal*)(data + offset);
   if ((xtolong(Local->signature) != LOCALSIG))
-    return nullptr;
+    return 0;
 
   //-- NOTE: extralen is different in central header and local header
   //--       for archives created using the Unix "zip" utility. To set
   //--       the offset accurately we need the _local_ extralen.
   offset += ZIPLOCAL_SIZE +
             xtoint(Local->filename_len) +
             xtoint(Local->extrafield_len);
 
+  return offset;
+MOZ_WIN_MEM_TRY_CATCH(return 0)
+}
+
+//---------------------------------------------
+// nsZipArchive::GetData
+//---------------------------------------------
+const uint8_t* nsZipArchive::GetData(nsZipItem* aItem)
+{
+  PR_ASSERT (aItem);
+MOZ_WIN_MEM_TRY_BEGIN
+  uint32_t offset = GetDataOffset(aItem);
+
   // -- check if there is enough source data in the file
-  if (offset + aItem->Size() > len)
+  if (!offset || offset + aItem->Size() > mFd->mLen)
     return nullptr;
 
-  return data + offset;
+  return mFd->mFileData + offset;
 MOZ_WIN_MEM_TRY_CATCH(return nullptr)
 }
 
 // nsZipArchive::GetComment
 bool nsZipArchive::GetComment(nsACString &aComment)
 {
 MOZ_WIN_MEM_TRY_BEGIN
   aComment.Assign(mCommentPtr, mCommentLen);
--- a/modules/libjar/nsZipArchive.h
+++ b/modules/libjar/nsZipArchive.h
@@ -174,16 +174,23 @@ public:
   nsresult FindInit(const char * aPattern, nsZipFind** aFind);
 
   /*
    * Gets an undependent handle to the mapped file.
    */
   nsZipHandle* GetFD();
 
   /**
+   * Gets the data offset.
+   * @param   aItem       Pointer to nsZipItem
+   * returns 0 on failure.
+   */
+  uint32_t GetDataOffset(nsZipItem* aItem);
+
+  /**
    * Get pointer to the data of the item.
    * @param   aItem       Pointer to nsZipItem
    * reutrns null when zip file is corrupt.
    */
   const uint8_t* GetData(nsZipItem* aItem);
 
   bool GetComment(nsACString &aComment);
 
--- a/netwerk/protocol/app/AppProtocolHandler.cpp
+++ b/netwerk/protocol/app/AppProtocolHandler.cpp
@@ -113,16 +113,21 @@ NS_IMETHODIMP DummyChannel::GetIsUnsafe(
   return NS_OK;
 }
 
 NS_IMETHODIMP DummyChannel::SetAppURI(nsIURI *aURI)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
+NS_IMETHODIMP DummyChannel::GetJarFile(nsIFile* *aFile)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
 NS_IMETHODIMP DummyChannel::Run()
 {
   nsresult rv = mListener->OnStartRequest(this, mListenerContext);
   NS_ENSURE_SUCCESS(rv, rv);
   mPending = false;
   rv = mListener->OnStopRequest(this, mListenerContext, NS_ERROR_FILE_NOT_FOUND);
   NS_ENSURE_SUCCESS(rv, rv);
   if (mLoadGroup) {