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 id13811
push usermwu@mozilla.com
push dateTue, 15 Jun 2010 00:56:23 +0000
treeherdermozilla-central@91851c94fb73 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmwu
bugs570488
milestone1.9.3a6pre
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 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");