Bug 1028588 - Fix dangerous public destructors in js/xpconnect - r=bholley
authorBenoit Jacob <bjacob@mozilla.com>
Mon, 23 Jun 2014 14:49:08 -0400
changeset 190263 3d6b2a02b254f693dcb968e0a1cbd541fa41e524
parent 190262 4976dc6ee72a17fe1641de59fbd66c52716f8fd9
child 190264 477fcc7c9f603649c4b15b90b2ababd40a87b8cc
push id27004
push useremorley@mozilla.com
push dateTue, 24 Jun 2014 15:52:34 +0000
treeherderautoland@7b174d47f3cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1028588
milestone33.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 1028588 - Fix dangerous public destructors in js/xpconnect - r=bholley
js/xpconnect/loader/mozJSComponentLoader.h
js/xpconnect/loader/mozJSSubScriptLoader.cpp
js/xpconnect/loader/mozJSSubScriptLoader.h
js/xpconnect/public/SandboxPrivate.h
js/xpconnect/src/BackstagePass.h
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSID.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCJSWeakReference.h
js/xpconnect/src/xpcprivate.h
js/xpconnect/tests/components/native/xpctest_private.h
--- a/js/xpconnect/loader/mozJSComponentLoader.h
+++ b/js/xpconnect/loader/mozJSComponentLoader.h
@@ -41,29 +41,30 @@ class mozJSComponentLoader : public mozi
 {
     friend class JSCLContextHelper;
  public:
     NS_DECL_ISUPPORTS
     NS_DECL_XPCIJSMODULELOADER
     NS_DECL_NSIOBSERVER
 
     mozJSComponentLoader();
-    virtual ~mozJSComponentLoader();
 
     // ModuleLoader
     const mozilla::Module* LoadModule(mozilla::FileLocation &aFile);
 
     nsresult FindTargetObject(JSContext* aCx,
                               JS::MutableHandleObject aTargetObject);
 
     static mozJSComponentLoader* Get() { return sSelf; }
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
  protected:
+    virtual ~mozJSComponentLoader();
+
     static mozJSComponentLoader* sSelf;
 
     nsresult ReallyInit();
     void UnloadModules();
 
     JSObject* PrepareObjectForLocation(JSCLContextHelper& aCx,
                                        nsIFile* aComponentFile,
                                        nsIURI *aComponent,
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -380,29 +380,29 @@ public:
                       nsIChannel* aChannel)
         : mObserver(aObserver)
         , mPrincipal(aPrincipal)
         , mChannel(aChannel)
         , mScriptBuf(nullptr)
         , mScriptLength(0)
     {}
 
+    static void OffThreadCallback(void *aToken, void *aData);
+
+    /* Sends the "done" notification back. Main thread only. */
+    void SendObserverNotification();
+
+private:
     virtual ~ScriptPrecompiler()
     {
       if (mScriptBuf) {
         js_free(mScriptBuf);
       }
     }
 
-    static void OffThreadCallback(void *aToken, void *aData);
-
-    /* Sends the "done" notification back. Main thread only. */
-    void SendObserverNotification();
-
-private:
     nsRefPtr<nsIObserver> mObserver;
     nsRefPtr<nsIPrincipal> mPrincipal;
     nsRefPtr<nsIChannel> mChannel;
     jschar* mScriptBuf;
     size_t mScriptLength;
 };
 
 NS_IMPL_ISUPPORTS(ScriptPrecompiler, nsIStreamLoaderObserver);
--- a/js/xpconnect/loader/mozJSSubScriptLoader.h
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.h
@@ -20,23 +20,24 @@ class LoadSubScriptOptions;
 }
 
 class nsIIOService;
 
 class mozJSSubScriptLoader : public mozIJSSubScriptLoader
 {
 public:
     mozJSSubScriptLoader();
-    virtual ~mozJSSubScriptLoader();
 
     // all the interface method declarations...
     NS_DECL_ISUPPORTS
     NS_DECL_MOZIJSSUBSCRIPTLOADER
 
 private:
+    virtual ~mozJSSubScriptLoader();
+
     nsresult ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_obj,
                         const nsAString &charset, const char *uriStr,
                         nsIIOService *serv, nsIPrincipal *principal,
                         bool reuseGlobal, JSScript **scriptp,
                         JSFunction **functionp);
 
     nsresult DoLoadSubScriptWithOptions(const nsAString &url,
                                         LoadSubScriptOptions  &options,
--- a/js/xpconnect/public/SandboxPrivate.h
+++ b/js/xpconnect/public/SandboxPrivate.h
@@ -24,17 +24,16 @@ class SandboxPrivate : public nsIGlobalO
                        public nsWrapperCache
 {
 public:
     SandboxPrivate(nsIPrincipal *principal, JSObject *global)
         : mPrincipal(principal)
     {
         SetWrapper(global);
     }
-    virtual ~SandboxPrivate() { }
 
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(SandboxPrivate,
                                                            nsIGlobalObject)
 
     nsIPrincipal *GetPrincipal()
     {
         return mPrincipal;
@@ -44,13 +43,16 @@ public:
     {
         return GetWrapper();
     }
 
     void ForgetGlobalObject()
     {
         ClearWrapper();
     }
+
 private:
+    virtual ~SandboxPrivate() { }
+
     nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 #endif // __SANDBOXPRIVATE_H__
--- a/js/xpconnect/src/BackstagePass.h
+++ b/js/xpconnect/src/BackstagePass.h
@@ -42,19 +42,19 @@ public:
     mGlobal = global;
   }
 
   BackstagePass(nsIPrincipal *prin) :
     mPrincipal(prin)
   {
   }
 
+private:
   virtual ~BackstagePass() { }
 
-private:
   nsCOMPtr<nsIPrincipal> mPrincipal;
   JS::TenuredHeap<JSObject*> mGlobal;
 };
 
 nsresult
 NS_NewBackstagePass(BackstagePass** ret);
 
 #endif // BackstagePass_h__
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -64,19 +64,20 @@ class nsXPCComponents_utils_Sandbox : pu
 public:
     // Aren't macros nice?
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_UTILS_SANDBOX
     NS_DECL_NSIXPCSCRIPTABLE
 
 public:
     nsXPCComponents_utils_Sandbox();
+
+private:
     virtual ~nsXPCComponents_utils_Sandbox();
 
-private:
     static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
                                     JSContext *cx, HandleObject obj,
                                     const CallArgs &args, bool *_retval);
 };
 
 already_AddRefed<nsIXPCComponents_utils_Sandbox>
 xpc::NewSandboxConstructor()
 {
@@ -1762,28 +1763,29 @@ nsXPCComponents_utils_Sandbox::CallOrCon
     *_retval = true;
     return NS_OK;
 }
 
 class ContextHolder : public nsIScriptObjectPrincipal
 {
 public:
     ContextHolder(JSContext *aOuterCx, HandleObject aSandbox, nsIPrincipal *aPrincipal);
-    virtual ~ContextHolder();
 
     JSContext * GetJSContext()
     {
         return mJSContext;
     }
 
     nsIPrincipal * GetPrincipal() { return mPrincipal; }
 
     NS_DECL_ISUPPORTS
 
 private:
+    virtual ~ContextHolder();
+
     JSContext* mJSContext;
     nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 NS_IMPL_ISUPPORTS(ContextHolder, nsIScriptObjectPrincipal)
 
 ContextHolder::ContextHolder(JSContext *aOuterCx,
                              HandleObject aSandbox,
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -103,19 +103,20 @@ public:
     // all the interface method declarations...
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_INTERFACES
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCComponents_Interfaces();
-    virtual ~nsXPCComponents_Interfaces();
 
 private:
+    virtual ~nsXPCComponents_Interfaces();
+
     nsCOMArray<nsIInterfaceInfo> mInterfaces;
 };
 
 /* void getInterfaces (out uint32_t count, [array, size_is (count), retval]
                        out nsIIDPtr array); */
 NS_IMETHODIMP
 nsXPCComponents_Interfaces::GetInterfaces(uint32_t *aCount, nsIID * **aArray)
 {
@@ -353,19 +354,20 @@ public:
     // all the interface method declarations...
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_INTERFACESBYID
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCComponents_InterfacesByID();
-    virtual ~nsXPCComponents_InterfacesByID();
 
 private:
+    virtual ~nsXPCComponents_InterfacesByID();
+
     nsCOMArray<nsIInterfaceInfo> mInterfaces;
 };
 
 /***************************************************************************/
 /* void getInterfaces (out uint32_t count, [array, size_is (count), retval]
                        out nsIIDPtr array); */
 NS_IMETHODIMP
 nsXPCComponents_InterfacesByID::GetInterfaces(uint32_t *aCount, nsIID * **aArray)
@@ -608,16 +610,18 @@ public:
     // all the interface method declarations...
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_CLASSES
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCComponents_Classes();
+
+private:
     virtual ~nsXPCComponents_Classes();
 };
 
 /***************************************************************************/
 /* void getInterfaces (out uint32_t count, [array, size_is (count), retval]
                        out nsIIDPtr array); */
 NS_IMETHODIMP
 nsXPCComponents_Classes::GetInterfaces(uint32_t *aCount, nsIID * **aArray)
@@ -847,16 +851,18 @@ public:
     // all the interface method declarations...
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_CLASSESBYID
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCComponents_ClassesByID();
+
+private:
     virtual ~nsXPCComponents_ClassesByID();
 };
 
 /***************************************************************************/
 /* void getInterfaces (out uint32_t count, [array, size_is (count), retval]
                        out nsIIDPtr array); */
 NS_IMETHODIMP
 nsXPCComponents_ClassesByID::GetInterfaces(uint32_t *aCount, nsIID * **aArray)
@@ -1108,16 +1114,18 @@ public:
     // all the interface method declarations...
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_RESULTS
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCComponents_Results();
+
+private:
     virtual ~nsXPCComponents_Results();
 };
 
 /***************************************************************************/
 /* void getInterfaces (out uint32_t count, [array, size_is (count), retval]
                        out nsIIDPtr array); */
 NS_IMETHODIMP
 nsXPCComponents_Results::GetInterfaces(uint32_t *aCount, nsIID * **aArray)
@@ -1327,19 +1335,19 @@ public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_ID
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 
 public:
     nsXPCComponents_ID();
-    virtual ~nsXPCComponents_ID();
 
 private:
+    virtual ~nsXPCComponents_ID();
     static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
                                     JSContext *cx, HandleObject obj,
                                     const CallArgs &args, bool *_retval);
 };
 
 /***************************************************************************/
 /* void getInterfaces (out uint32_t count, [array, size_is (count), retval]
                        out nsIIDPtr array); */
@@ -1544,19 +1552,19 @@ public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_EXCEPTION
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 
 public:
     nsXPCComponents_Exception();
-    virtual ~nsXPCComponents_Exception();
 
 private:
+    virtual ~nsXPCComponents_Exception();
     static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
                                     JSContext *cx, HandleObject obj,
                                     const CallArgs &args, bool *_retval);
 };
 
 /***************************************************************************/
 /* void getInterfaces (out uint32_t count, [array, size_is (count), retval]
                        out nsIIDPtr array); */
@@ -1930,19 +1938,19 @@ public:
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCConstructor(); // not implemented
     nsXPCConstructor(nsIJSCID* aClassID,
                      nsIJSIID* aInterfaceID,
                      const char* aInitializer);
-    virtual ~nsXPCConstructor();
 
 private:
+    virtual ~nsXPCConstructor();
     nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
                              JSContext *cx, HandleObject obj,
                              const CallArgs &args, bool *_retval);
 private:
     nsRefPtr<nsIJSCID> mClassID;
     nsRefPtr<nsIJSIID> mInterfaceID;
     char*              mInitializer;
 };
@@ -2189,19 +2197,19 @@ public:
     // all the interface method declarations...
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTS_CONSTRUCTOR
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSICLASSINFO
 
 public:
     nsXPCComponents_Constructor();
-    virtual ~nsXPCComponents_Constructor();
 
 private:
+    virtual ~nsXPCComponents_Constructor();
     static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
                                     JSContext *cx, HandleObject obj,
                                     const CallArgs &args, bool *_retval);
 };
 
 /***************************************************************************/
 /* void getInterfaces (out uint32_t count, [array, size_is (count), retval]
                        out nsIIDPtr array); */
@@ -2502,19 +2510,19 @@ class nsXPCComponents_Utils :
 public:
     // all the interface method declarations...
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCSCRIPTABLE
     NS_DECL_NSIXPCCOMPONENTS_UTILS
 
 public:
     nsXPCComponents_Utils() { }
-    virtual ~nsXPCComponents_Utils() { }
 
 private:
+    virtual ~nsXPCComponents_Utils() { }
     nsCOMPtr<nsIXPCComponents_utils_Sandbox> mSandbox;
 };
 
 NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Utils)
   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Utils)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Utils)
 NS_INTERFACE_MAP_END
@@ -3431,19 +3439,21 @@ nsXPCComponents_Utils::GetIncumbentGloba
  * we create a benign holder class instead, which acts as an opaque reference
  * that script can use to keep the XPCWrappedJS alive and in the map.
  */
 
 class WrappedJSHolder : public nsISupports
 {
     NS_DECL_ISUPPORTS
     WrappedJSHolder() {}
-    virtual ~WrappedJSHolder() {}
 
     nsRefPtr<nsXPCWrappedJS> mWrappedJS;
+
+private:
+    virtual ~WrappedJSHolder() {}
 };
 NS_IMPL_ISUPPORTS0(WrappedJSHolder);
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::GenerateXPCWrappedJS(HandleValue aObj, HandleValue aScope,
                                             JSContext *aCx, nsISupports **aOut)
 {
     if (!aObj.isObject())
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -199,16 +199,17 @@ nsJSID::NewID(const nsID& id)
 // needed to be able to indicate to the shared prototypes this single flag:
 // nsIXPCScriptable::DONT_ENUM_STATIC_PROPS. And having a class to do it is
 // the only means we have. Setting this flag on any given instance scriptable
 // helper is not sufficient to convey the information that we don't want
 // static properties enumerated on the shared proto.
 
 class SharedScriptableHelperForJSIID MOZ_FINAL : public nsIXPCScriptable
 {
+    ~SharedScriptableHelperForJSIID() {}
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCSCRIPTABLE
     SharedScriptableHelperForJSIID() {}
 };
 
 NS_INTERFACE_MAP_BEGIN(SharedScriptableHelperForJSIID)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1169,25 +1169,30 @@ class WatchdogManager : public nsIObserv
         mTimestamps[TimestampRuntimeStateChange] = PR_Now();
 
         // Enable the watchdog, if appropriate.
         RefreshWatchdog();
 
         // Register ourselves as an observer to get updates on the pref.
         mozilla::Preferences::AddStrongObserver(this, "dom.use_watchdog");
     }
+
+  protected:
+
     virtual ~WatchdogManager()
     {
         // Shutting down the watchdog requires context-switching to the watchdog
         // thread, which isn't great to do in a destructor. So we require
         // consumers to shut it down manually before releasing it.
         MOZ_ASSERT(!mWatchdog);
         mozilla::Preferences::RemoveObserver(this, "dom.use_watchdog");
     }
 
+  public:
+
     NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
                        const char16_t* aData)
     {
         RefreshWatchdog();
         return NS_OK;
     }
 
     // Runtime statistics. These live on the watchdog manager, are written
@@ -1781,16 +1786,18 @@ static int64_t
 JSMainRuntimeCompartmentsUserDistinguishedAmount()
 {
     JSRuntime *rt = nsXPConnect::GetRuntimeInstance()->Runtime();
     return JS::UserCompartmentCount(rt);
 }
 
 class JSMainRuntimeTemporaryPeakReporter MOZ_FINAL : public nsIMemoryReporter
 {
+    ~JSMainRuntimeTemporaryPeakReporter() {}
+
   public:
     NS_DECL_ISUPPORTS
 
     NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
                               nsISupports* aData, bool aAnonymize)
     {
         return MOZ_COLLECT_REPORT("js-main-runtime-temporary-peak",
             KIND_OTHER, UNITS_BYTES,
@@ -2548,16 +2555,19 @@ ReportJSRuntimeExplicitTreeStats(const J
                                             cb, closure, anonymize, rtTotalOut);
 }
 
 
 } // namespace xpc
 
 class JSMainRuntimeCompartmentsReporter MOZ_FINAL : public nsIMemoryReporter
 {
+
+    ~JSMainRuntimeCompartmentsReporter() {}
+
   public:
     NS_DECL_ISUPPORTS
 
     struct Data {
         int anonymizeID;
         js::Vector<nsCString, 0, js::SystemAllocPolicy> paths;
     };
 
--- a/js/xpconnect/src/XPCJSWeakReference.h
+++ b/js/xpconnect/src/XPCJSWeakReference.h
@@ -8,16 +8,18 @@
 #define xpcjsweakreference_h___
 
 #include "xpcIJSWeakReference.h"
 #include "nsIWeakReference.h"
 #include "mozilla/Attributes.h"
 
 class xpcJSWeakReference MOZ_FINAL : public xpcIJSWeakReference
 {
+    ~xpcJSWeakReference() {}
+
 public:
     xpcJSWeakReference();
     nsresult Init(JSContext* cx, const JS::Value& object);
 
     NS_DECL_ISUPPORTS
     NS_DECL_XPCIJSWEAKREFERENCE
 
 private:
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -289,18 +289,16 @@ public:
     // NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR
     static nsXPConnect* GetSingleton();
 
     // Called by module code in dll startup
     static void InitStatics();
     // Called by module code on dll shutdown.
     static void ReleaseXPConnectSingleton();
 
-    virtual ~nsXPConnect();
-
     bool IsShuttingDown() const {return mShuttingDown;}
 
     nsresult GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info);
     nsresult GetInfoForName(const char * name, nsIInterfaceInfo** info);
 
     virtual nsIPrincipal* GetPrincipal(JSObject* obj,
                                        bool allowShortCircuit) const;
 
@@ -313,16 +311,18 @@ public:
     static bool ReportAllJSExceptions()
     {
       return gReportAllJSExceptions > 0;
     }
 
     static void CheckForDebugMode(JSRuntime *rt);
 
 protected:
+    virtual ~nsXPConnect();
+
     nsXPConnect();
 
 private:
     // Singleton instance
     static nsXPConnect*             gSelf;
     static bool                     gOnceAliveNowDead;
 
     XPCJSRuntime*                   mRuntime;
@@ -2273,23 +2273,23 @@ public:
                                             JSObject* aJSObj,
                                             nsISimpleEnumerator** aEnumerate);
 
     static nsresult GetNamedPropertyAsVariant(XPCCallContext& ccx,
                                               JSObject* aJSObj,
                                               const nsAString& aName,
                                               nsIVariant** aResult);
 
-    virtual ~nsXPCWrappedJSClass();
-
     static nsresult CheckForException(XPCCallContext & ccx,
                                       const char * aPropertyName,
                                       const char * anInterfaceName,
                                       bool aForceReport);
 private:
+    virtual ~nsXPCWrappedJSClass();
+
     nsXPCWrappedJSClass();   // not implemented
     nsXPCWrappedJSClass(JSContext* cx, REFNSIID aIID,
                         nsIInterfaceInfo* aInfo);
 
     bool IsReflectable(uint16_t i) const
         {return (bool)(mDescriptors[i/32] & (1 << (i%32)));}
     void SetReflectable(uint16_t i, bool b)
         {if (b) mDescriptors[i/32] |= (1 << (i%32));
@@ -2442,22 +2442,22 @@ public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
 
     // non-interface implementation
 
 public:
     static XPCJSObjectHolder* newHolder(JSObject* obj);
 
-    virtual ~XPCJSObjectHolder();
-
     void TraceJS(JSTracer *trc);
     static void GetTraceName(JSTracer* trc, char *buf, size_t bufsize);
 
 private:
+    virtual ~XPCJSObjectHolder();
+
     XPCJSObjectHolder(JSObject* obj);
     XPCJSObjectHolder(); // not implemented
 
     JS::Heap<JSObject*> mJSObj;
 };
 
 /***************************************************************************
 ****************************************************************************
@@ -2469,19 +2469,20 @@ private:
 
 class xpcProperty : public nsIProperty
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPROPERTY
 
   xpcProperty(const char16_t* aName, uint32_t aNameLen, nsIVariant* aValue);
-  virtual ~xpcProperty() {}
 
 private:
+    virtual ~xpcProperty() {}
+
     nsString             mName;
     nsCOMPtr<nsIVariant> mValue;
 };
 
 /***************************************************************************/
 // class here just for static methods
 class XPCConvert
 {
@@ -2670,28 +2671,35 @@ public:
     const nsID& ID() const {return mID;}
     bool IsValid() const {return !mID.Equals(GetInvalidIID());}
 
     static already_AddRefed<nsJSID> NewID(const char* str);
     static already_AddRefed<nsJSID> NewID(const nsID& id);
 
     nsJSID();
     virtual ~nsJSID();
-protected:
 
     void Reset();
     const nsID& GetInvalidIID() const;
 
 protected:
     static char gNoString[];
     nsID    mID;
     char*   mNumber;
     char*   mName;
 };
 
+namespace mozilla {
+template<>
+struct HasDangerousPublicDestructor<nsJSID>
+{
+  static const bool value = true;
+};
+}
+
 // nsJSIID
 
 class nsJSIID : public nsIJSIID,
                 public nsIXPCScriptable
 {
 public:
     NS_DECL_ISUPPORTS
 
@@ -2701,19 +2709,20 @@ public:
     // we implement the rest...
     NS_DECL_NSIJSIID
     NS_DECL_NSIXPCSCRIPTABLE
 
     static already_AddRefed<nsJSIID> NewID(nsIInterfaceInfo* aInfo);
 
     nsJSIID(nsIInterfaceInfo* aInfo);
     nsJSIID(); // not implemented
-    virtual ~nsJSIID();
 
 private:
+    virtual ~nsJSIID();
+
     nsCOMPtr<nsIInterfaceInfo> mInfo;
 };
 
 // nsJSCID
 
 class nsJSCID : public nsIJSCID, public nsIXPCScriptable
 {
 public:
@@ -2724,19 +2733,20 @@ public:
 
     // we implement the rest...
     NS_DECL_NSIJSCID
     NS_DECL_NSIXPCSCRIPTABLE
 
     static already_AddRefed<nsJSCID> NewID(const char* str);
 
     nsJSCID();
-    virtual ~nsJSCID();
 
 private:
+    virtual ~nsJSCID();
+
     void ResolveName();
 
 private:
     nsJSID mDetails;
 };
 
 
 /***************************************************************************/
@@ -2817,21 +2827,22 @@ private:
 class nsXPCComponentsBase : public nsIXPCComponentsBase
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIXPCCOMPONENTSBASE
 
 public:
     void SystemIsBeingShutDown() { ClearMembers(); }
-    virtual ~nsXPCComponentsBase();
 
     XPCWrappedNativeScope *GetScope() { return mScope; }
 
 protected:
+    virtual ~nsXPCComponentsBase();
+
     nsXPCComponentsBase(XPCWrappedNativeScope* aScope);
     virtual void ClearMembers();
 
     XPCWrappedNativeScope*                   mScope;
 
     // Unprivileged members from nsIXPCComponentsBase.
     nsRefPtr<nsXPCComponents_Interfaces>     mInterfaces;
     nsRefPtr<nsXPCComponents_InterfacesByID> mInterfacesByID;
@@ -2899,25 +2910,25 @@ xpc_InstallJSDebuggerKeywordHandler(JSRu
 /***************************************************************************/
 
 // Definition of nsScriptError, defined here because we lack a place to put
 // XPCOM objects associated with the JavaScript engine.
 class nsScriptError : public nsIScriptError {
 public:
     nsScriptError();
 
-    virtual ~nsScriptError();
-
   // TODO - do something reasonable on getting null from these babies.
 
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSICONSOLEMESSAGE
     NS_DECL_NSISCRIPTERROR
 
 private:
+    virtual ~nsScriptError();
+
     nsString mMessage;
     nsString mSourceName;
     uint32_t mLineNumber;
     nsString mSourceLine;
     uint32_t mColumnNumber;
     uint32_t mFlags;
     nsCString mCategory;
     uint64_t mOuterWindowID;
--- a/js/xpconnect/tests/components/native/xpctest_private.h
+++ b/js/xpconnect/tests/components/native/xpctest_private.h
@@ -18,33 +18,36 @@
 
 class xpcTestObjectReadOnly MOZ_FINAL : public nsIXPCTestObjectReadOnly {
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIXPCTESTOBJECTREADONLY
   xpcTestObjectReadOnly();
 
  private:
+    ~xpcTestObjectReadOnly() {}
+
     bool    boolProperty;
     int16_t shortProperty;
     int32_t longProperty;
     float   floatProperty;
     char    charProperty;
     PRTime  timeProperty;
 };
 
 class xpcTestObjectReadWrite MOZ_FINAL : public nsIXPCTestObjectReadWrite {
   public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIXPCTESTOBJECTREADWRITE
 
   xpcTestObjectReadWrite();
-  ~xpcTestObjectReadWrite();
 
  private:
+     ~xpcTestObjectReadWrite();
+
      bool boolProperty;
      int16_t shortProperty;
      int32_t longProperty;
      float floatProperty;
      char charProperty;
      char *stringProperty;
      PRTime timeProperty;
 };