Bug 570488 - Fix loading of XPTs nested in JARs [2/2] r=mwu
authorBenjamin Smedberg <benjamin@smedbergs.us>
Mon, 14 Jun 2010 16:10:04 -0700
changeset 43620 0def0bbb620d0324a2ddd2f67b8d8ea919b06426
parent 43619 894850aef55c89bb21cfb7496b87210a7c7daefa
child 43621 91851c94fb73f0624357af573f2917e008e106e0
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmwu
bugs570488
milestone1.9.3a6pre
Bug 570488 - Fix loading of XPTs nested in JARs [2/2] r=mwu
modules/libjar/nsJARFactory.cpp
modules/libjar/nsXPTZipLoader.cpp
modules/libjar/nsXPTZipLoader.h
modules/libjar/objs.mk
testing/xpcshell/Makefile.in
xpcom/build/nsXPComInit.cpp
xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
xpcom/tests/Makefile.in
xpcom/tests/xptinfo/Makefile.in
xpcom/tests/xptinfo/xptiITestInterface.idl
xpcom/tests/xptinfo/xptunit/test_jar_xptloading.js
--- a/modules/libjar/nsJARFactory.cpp
+++ b/modules/libjar/nsJARFactory.cpp
@@ -49,37 +49,30 @@
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
 #include "nsCOMPtr.h"
 #include "nsIModule.h"
 #include "nsIGenericFactory.h"
 #include "nsJAR.h"
 #include "nsIJARFactory.h"
 #include "nsRecyclingAllocator.h"
-#include "nsXPTZipLoader.h"
 #include "nsJARProtocolHandler.h"
 #include "nsJARURI.h"
 
 extern nsRecyclingAllocator *gZlibAllocator;
 
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPTZipLoader)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsJAR)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsZipReaderCache)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsJARProtocolHandler,
                                          nsJARProtocolHandler::GetSingleton)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsJARURI)
 
 // The list of components we register
 static const nsModuleComponentInfo components[] = 
 {
-    { "XPT Zip Reader",
-      NS_XPTZIPREADER_CID,
-      NS_XPTLOADER_CONTRACTID_PREFIX "zip",
-      nsXPTZipLoaderConstructor
-    },
     { "Zip Reader", 
        NS_ZIPREADER_CID,
       "@mozilla.org/libjar/zip-reader;1", 
       nsJARConstructor
     },
     { "Zip Reader Cache", 
        NS_ZIPREADERCACHE_CID,
       "@mozilla.org/libjar/zip-reader-cache;1", 
--- a/modules/libjar/nsXPTZipLoader.cpp
+++ b/modules/libjar/nsXPTZipLoader.cpp
@@ -34,25 +34,20 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 
 #include "nsXPTZipLoader.h"
-#include "nsIZipReader.h"
-#include "nsXPIDLString.h"
+#include "nsJAR.h"
 #include "nsString.h"
 #include "nsStringEnumerator.h"
 
-static const char gCacheContractID[] =
-  "@mozilla.org/libjar/zip-reader-cache;1";
-static const PRUint32 gCacheSize = 1;
-
 nsXPTZipLoader::nsXPTZipLoader() {
 }
 
 NS_IMPL_ISUPPORTS1(nsXPTZipLoader, nsIXPTLoader)
 
 nsresult
 nsXPTZipLoader::LoadEntry(nsILocalFile* aFile,
                           const char* aName,
@@ -97,27 +92,20 @@ nsXPTZipLoader::EnumerateEntries(nsILoca
 
         // ignore the result
         aSink->FoundEntry(itemName.get(), index++, stream);
     }
 
     return NS_OK;
 }
 
-nsIZipReader*
+already_AddRefed<nsIZipReader>
 nsXPTZipLoader::GetZipReader(nsILocalFile* file)
 {
     NS_ASSERTION(file, "bad file");
     
-    if(!mCache)
-    {
-        mCache = do_CreateInstance(gCacheContractID);
-        if(!mCache || NS_FAILED(mCache->Init(gCacheSize)))
-            return nsnull;
-    }
+    nsCOMPtr<nsIZipReader> reader = new nsJAR();
+    nsresult rv = reader->Open(file);
+    if (NS_FAILED(rv))
+        return NULL;
 
-    nsIZipReader* reader = nsnull;
-
-    if(NS_FAILED(mCache->GetZip(file, &reader)))
-        return nsnull;
-
-    return reader;
+    return reader.forget();
 }
--- a/modules/libjar/nsXPTZipLoader.h
+++ b/modules/libjar/nsXPTZipLoader.h
@@ -37,28 +37,21 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.h"
 #include "nsIXPTLoader.h"
 
 #include "nsIZipReader.h"
 
-// {0320E073-79C7-4dae-8055-81BED8B8DB96}
-#define NS_XPTZIPREADER_CID \
-  { 0x320e073, 0x79c7, 0x4dae, \
-      { 0x80, 0x55, 0x81, 0xbe, 0xd8, 0xb8, 0xdb, 0x96 } }
-
-
 class nsXPTZipLoader : public nsIXPTLoader
 {
  public:
     nsXPTZipLoader();
     virtual ~nsXPTZipLoader() {}
     
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPTLOADER
 
  private:
-    nsIZipReader* GetZipReader(nsILocalFile* aFile);
-    nsCOMPtr<nsIZipReaderCache> mCache;
+    already_AddRefed<nsIZipReader> GetZipReader(nsILocalFile* aFile);
 };
 
--- a/modules/libjar/objs.mk
+++ b/modules/libjar/objs.mk
@@ -44,16 +44,17 @@ MODULES_LIBJAR_LCPPSRCS = \
 		nsJARProtocolHandler.cpp \
 		nsJARChannel.cpp  \
 		nsJARURI.cpp  \
 		$(NULL)
 
 MODULES_LIBJAR_LEXPORTS = \
 		zipstruct.h \
 		nsZipArchive.h \
+		nsXPTZipLoader.h \
 		$(NULL)
 
 MODULES_LIBJAR_LXPIDLSRCS = \
 		nsIZipReader.idl \
 		nsIJARChannel.idl \
 		nsIJARURI.idl \
 		nsIJARProtocolHandler.idl \
 		$(NULL)
--- a/testing/xpcshell/Makefile.in
+++ b/testing/xpcshell/Makefile.in
@@ -77,16 +77,20 @@ TEST_HARNESS_COMPONENTS := \
   httpd.js \
   $(NULL)
 
 ifdef MOZ_CRASHREPORTER
 #XXX: should find a better way to do this
 TEST_HARNESS_COMPONENTS +=  crashreporter_test.xpt
 endif
 
+ifdef MOZ_ENABLE_LIBXUL
+TEST_HARNESS_COMPONENTS += xpcom_typelib_test.jar
+endif
+
 # Rules for staging the necessary harness bits for a test package
 PKG_STAGE = $(DIST)/test-package-stage
 
 stage-package:
 	$(NSINSTALL) -D $(PKG_STAGE)/xpcshell/tests
 	@(cd $(srcdir) && tar $(TAR_CREATE_FLAGS) - $(TEST_HARNESS_FILES)) | (cd $(PKG_STAGE)/xpcshell && tar -xf -)
 	@(cd $(topsrcdir)/build && tar $(TAR_CREATE_FLAGS) - $(EXTRA_BUILD_FILES)) | (cd $(PKG_STAGE)/xpcshell && tar -xf -)
 	@(cd $(topsrcdir)/build/mobile && tar $(TAR_CREATE_FLAGS) - $(MOBILE_BUILD_FILES)) | (cd $(PKG_STAGE)/xpcshell && tar -xf -)
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -691,28 +691,22 @@ NS_InitXPCOM3(nsIServiceManager* *result
           RegisterFactory(kSimpleUnicharStreamFactoryCID,
                           "nsSimpleUnicharStreamFactory",
                           NS_SIMPLE_UNICHAR_STREAM_FACTORY_CONTRACTID,
                           nsSimpleUnicharStreamFactory::GetInstance());
     }
 
     NS_TIME_FUNCTION_MARK("Next: interface info manager init");
 
-    // Pay the cost at startup time of starting this singleton.
+    // The iimanager constructor searches and registers XPT files.
     nsIInterfaceInfoManager* iim =
         xptiInterfaceInfoManager::GetSingleton();
 
     NS_TIME_FUNCTION_MARK("Next: try to load compreg.dat");
 
-#if 0 // The constructor does this, don't do it twice!
-    // If the component registry is out of date, malformed, or incomplete,
-    // autoregister the default component directories.
-    (void) iim->AutoRegisterInterfaces();
-#endif,
-
     // "Re-register the world" if compreg.dat doesn't exist
     rv = nsComponentManagerImpl::gComponentManager->ReadPersistentRegistry();
     if (NS_FAILED(rv)) {
         NS_TIME_FUNCTION_MARK("Next: try to register all components (compreg.dat not found)");
 
         nsComponentManagerImpl::gComponentManager->AutoRegister(nsnull);
     }
 
--- a/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
@@ -40,16 +40,17 @@
 /* Implementation of xptiInterfaceInfoManager. */
 
 #include "xptiprivate.h"
 #include "nsDependentString.h"
 #include "nsString.h"
 #include "nsISupportsArray.h"
 #include "nsArrayEnumerator.h"
 #include "mozilla/FunctionTimer.h"
+#include "nsXPTZipLoader.h"
 
 #define NS_ZIPLOADER_CONTRACTID NS_XPTLOADER_CONTRACTID_PREFIX "zip"
 
 NS_IMPL_THREADSAFE_ISUPPORTS2(xptiInterfaceInfoManager, 
                               nsIInterfaceInfoManager,
                               nsIInterfaceInfoSuperManager)
 
 static xptiInterfaceInfoManager* gInterfaceInfoManager = nsnull;
@@ -291,24 +292,24 @@ xptiInterfaceInfoManager::RegisterFile(n
     case xptiFileType::XPT: {
         XPTHeader* header = ReadXPTFile(aFile);
         if (!header)
             return;
 
         RegisterXPTHeader(header);
         break;
     }
-        
+
     case xptiFileType::ZIP: {
-        // XXX XPCOM registration ordering issue, use C++!
-        nsCOMPtr<nsIXPTLoader> loader = do_GetService(NS_ZIPLOADER_CONTRACTID);
-        if (!loader)
-            return;
-
+#ifndef MOZ_ENABLE_LIBXUL
+        NS_WARNING("Trying to register XPTs in a JAR in a non-libxul build");
+#else
+        nsCOMPtr<nsIXPTLoader> loader = new nsXPTZipLoader();
         loader->EnumerateEntries(aFile, this);
+#endif
         break;
     }
 
     default:
         NS_ERROR("Unexpected enumeration value");
     }
 }
 
--- a/xpcom/tests/Makefile.in
+++ b/xpcom/tests/Makefile.in
@@ -44,16 +44,21 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE		= xpcom
 
 ifndef MOZ_ENABLE_LIBXUL
 MOZILLA_INTERNAL_API = 1
 endif
 
 DIRS		= dynamic services external
+
+ifdef MOZ_ENABLE_LIBXUL
+DIRS += xptinfo
+endif
+
 ifeq ($(OS_ARCH),WINNT)
 DIRS		+= windows
 endif
 
 ifdef DEHYDRA_PATH
 DIRS += static-checker
 endif
 
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/xptinfo/Makefile.in
@@ -0,0 +1,59 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Firefox.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation <http://www.mozilla.org>
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = xpcom
+XPIDL_MODULE = xpcom_typelib_testxpt
+NO_DIST_INSTALL = 1
+
+XPIDLSRCS = xptiITestInterface.idl
+
+XPCSHELL_TESTS = xptunit
+
+include $(topsrcdir)/config/rules.mk
+
+xpcom_typelib_test.jar:: $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt
+	$(RM) -f $@
+	cd $(XPIDL_GEN_DIR) && $(ZIP) -q ../$(@F) $(^F)
+
+libs:: xpcom_typelib_test.jar
+	$(INSTALL) $^ $(FINAL_TARGET)/components
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/xptinfo/xptiITestInterface.idl
@@ -0,0 +1,47 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Firefox.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation <http://www.mozilla.org>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+/**
+ * This interface is not implemented: it exists only for a test of whether
+ * we load XPTs from JAR files correctly.
+ */
+[scriptable, uuid(13c9fc33-40e6-44dc-81e2-21e0dd41f232)]
+interface xptiITestInterface : nsISupports
+{
+  void testMethod(in unsigned long testArg);
+};
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/xptinfo/xptunit/test_jar_xptloading.js
@@ -0,0 +1,7 @@
+const xptiITestInterface_IID = "{13c9fc33-40e6-44dc-81e2-21e0dd41f232}";
+
+var id = Components.interfaces.xptiITestInterface;
+do_check_true(id, "xptiITestInterface not registered");
+
+var id2 = Components.interfacesById[xptiITestInterface_IID];
+do_check_true(id === id2, "xptiITestInterface info doesn't match");