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 id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbholley
bugs1028588
milestone33.0a1
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;
 };