Bug 1028588 - Fix dangerous public destructors in image/ - r=jrmuizel
authorBenoit Jacob <bjacob@mozilla.com>
Mon, 23 Jun 2014 14:49:08 -0400
changeset 190262 4976dc6ee72a17fe1641de59fbd66c52716f8fd9
parent 190261 2c62d4b7b0554e09efe43a7e543fc6e976d6aac0
child 190263 3d6b2a02b254f693dcb968e0a1cbd541fa41e524
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjrmuizel
bugs1028588
milestone33.0a1
Bug 1028588 - Fix dangerous public destructors in image/ - r=jrmuizel
image/decoders/icon/gtk/nsIconChannel.h
image/decoders/icon/nsIconProtocolHandler.h
image/decoders/icon/nsIconURI.h
image/encoders/bmp/nsBMPEncoder.h
image/encoders/ico/nsICOEncoder.h
image/encoders/png/nsPNGEncoder.h
image/src/ClippedImage.h
image/src/FrozenImage.h
image/src/ImageWrapper.h
image/src/OrientedImage.h
image/src/RasterImage.h
image/src/SVGDocumentWrapper.h
image/src/ScriptedNotificationObserver.h
image/src/SurfaceCache.cpp
image/src/VectorImage.cpp
image/src/VectorImage.h
image/src/imgLoader.cpp
image/src/imgLoader.h
image/src/imgRequest.h
image/src/imgRequestProxy.h
image/src/imgTools.h
--- a/image/decoders/icon/gtk/nsIconChannel.h
+++ b/image/decoders/icon/gtk/nsIconChannel.h
@@ -20,27 +20,27 @@
  */
 class nsIconChannel MOZ_FINAL : public nsIChannel {
   public:
     NS_DECL_ISUPPORTS
     NS_FORWARD_NSIREQUEST(mRealChannel->)
     NS_FORWARD_NSICHANNEL(mRealChannel->)
 
     nsIconChannel() {}
-    ~nsIconChannel() {}
 
     static void Shutdown();
 
     /**
      * Called by nsIconProtocolHandler after it creates this channel.
      * Must be called before calling any other function on this object.
      * If this method fails, no other function must be called on this object.
      */
     nsresult Init(nsIURI* aURI);
   private:
+    ~nsIconChannel() {}
     /**
      * The channel to the temp icon file (e.g. to /tmp/2qy9wjqw.html).
      * Will always be non-null after a successful Init.
      */
     nsCOMPtr<nsIChannel> mRealChannel;
 
     /**
      * Called by Init if we need to use the gnomeui library.
--- a/image/decoders/icon/nsIconProtocolHandler.h
+++ b/image/decoders/icon/nsIconProtocolHandler.h
@@ -12,14 +12,14 @@
 class nsIconProtocolHandler : public nsIProtocolHandler, public nsSupportsWeakReference
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIPROTOCOLHANDLER
 
     // nsIconProtocolHandler methods:
     nsIconProtocolHandler();
-    virtual ~nsIconProtocolHandler();
 
 protected:
+    virtual ~nsIconProtocolHandler();
 };
 
 #endif /* nsIconProtocolHandler_h___ */
--- a/image/decoders/icon/nsIconURI.h
+++ b/image/decoders/icon/nsIconURI.h
@@ -23,19 +23,19 @@ class nsMozIconURI : public nsIMozIconUR
 {
 public:    
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIURI
   NS_DECL_NSIMOZICONURI
 
   // nsMozIconURI
   nsMozIconURI();
-  virtual ~nsMozIconURI();
 
 protected:
+  virtual ~nsMozIconURI();
   nsCOMPtr<nsIURL> mIconURL; // a URL that we want the icon for
   uint32_t mSize; // the # of pixels in a row that we want for this image. Typically 16, 32, 128, etc.
   nsCString mContentType; // optional field explicitly specifying the content type
   nsCString mFileName; // for if we don't have an actual file path, we're just given a filename with an extension
   nsCString mStockIcon;
   int32_t mIconSize;     // -1 if not specified, otherwise index into kSizeStrings
   int32_t mIconState;    // -1 if not specified, otherwise index into kStateStrings
 };
--- a/image/encoders/bmp/nsBMPEncoder.h
+++ b/image/encoders/bmp/nsBMPEncoder.h
@@ -26,19 +26,20 @@ class nsBMPEncoder MOZ_FINAL : public im
   typedef mozilla::ReentrantMonitor ReentrantMonitor;
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_IMGIENCODER
   NS_DECL_NSIINPUTSTREAM
   NS_DECL_NSIASYNCINPUTSTREAM
 
   nsBMPEncoder();
+
+protected:
   ~nsBMPEncoder();
 
-protected:
   enum Version {
       VERSION_3 = 3,
       VERSION_5 = 5
   };
 
   // See InitData in the cpp for valid parse options
   nsresult ParseOptions(const nsAString& aOptions, Version* version,
                         uint32_t* bpp);
--- a/image/encoders/ico/nsICOEncoder.h
+++ b/image/encoders/ico/nsICOEncoder.h
@@ -30,31 +30,32 @@ class nsICOEncoder MOZ_FINAL : public im
   typedef mozilla::ReentrantMonitor ReentrantMonitor;
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_IMGIENCODER
   NS_DECL_NSIINPUTSTREAM
   NS_DECL_NSIASYNCINPUTSTREAM
 
   nsICOEncoder();
-  ~nsICOEncoder();
   
   // Obtains the width of the icon directory entry
   uint32_t GetRealWidth() const
   {
     return mICODirEntry.mWidth == 0 ? 256 : mICODirEntry.mWidth; 
   }
 
   // Obtains the height of the icon directory entry
   uint32_t GetRealHeight() const
   {
     return mICODirEntry.mHeight == 0 ? 256 : mICODirEntry.mHeight; 
   }
 
 protected:
+  ~nsICOEncoder();
+
   nsresult ParseOptions(const nsAString& aOptions, uint32_t* bpp, 
                         bool *usePNG);
   void NotifyListener();
 
   // Initializes the icon file header mICOFileHeader
   void InitFileHeader();
   // Initializes the icon directory info header mICODirEntry
   void InitInfoHeader(uint32_t aBPP, uint8_t aWidth, uint8_t aHeight);
--- a/image/encoders/png/nsPNGEncoder.h
+++ b/image/encoders/png/nsPNGEncoder.h
@@ -28,19 +28,19 @@ class nsPNGEncoder MOZ_FINAL : public im
   typedef mozilla::ReentrantMonitor ReentrantMonitor;
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_IMGIENCODER
   NS_DECL_NSIINPUTSTREAM
   NS_DECL_NSIASYNCINPUTSTREAM
 
   nsPNGEncoder();
-  ~nsPNGEncoder();
 
 protected:
+  ~nsPNGEncoder();
   nsresult ParseOptions(const nsAString& aOptions,
                         bool* useTransparency,
                         bool* skipFirstFrame,
                         uint32_t* numAnimatedFrames,
                         uint32_t* numIterations,
                         uint32_t* frameDispose,
                         uint32_t* frameBlend,
                         uint32_t* frameDelay,
--- a/image/src/ClippedImage.h
+++ b/image/src/ClippedImage.h
@@ -26,18 +26,16 @@ class DrawSingleTileCallback;
  */
 class ClippedImage : public ImageWrapper
 {
   typedef mozilla::gfx::SourceSurface SourceSurface;
 
 public:
   NS_DECL_ISUPPORTS
 
-  virtual ~ClippedImage();
-
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
 
   NS_IMETHOD GetWidth(int32_t* aWidth) MOZ_OVERRIDE;
   NS_IMETHOD GetHeight(int32_t* aHeight) MOZ_OVERRIDE;
   NS_IMETHOD GetIntrinsicSize(nsSize* aSize) MOZ_OVERRIDE;
   NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE;
   NS_IMETHOD_(mozilla::TemporaryRef<SourceSurface>)
     GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
@@ -53,16 +51,18 @@ public:
                   uint32_t aWhichFrame,
                   uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD RequestDiscard() MOZ_OVERRIDE;
   NS_IMETHOD_(Orientation) GetOrientation() MOZ_OVERRIDE;
 
 protected:
   ClippedImage(Image* aImage, nsIntRect aClip);
 
+  virtual ~ClippedImage();
+
 private:
   mozilla::TemporaryRef<SourceSurface>
     GetFrameInternal(const nsIntSize& aViewportSize,
                      const SVGImageContext* aSVGContext,
                      uint32_t aWhichFrame,
                      uint32_t aFlags);
   bool ShouldClip();
   bool MustCreateSurface(gfxContext* aContext,
--- a/image/src/FrozenImage.h
+++ b/image/src/FrozenImage.h
@@ -26,18 +26,16 @@ namespace image {
  */
 class FrozenImage : public ImageWrapper
 {
   typedef mozilla::gfx::SourceSurface SourceSurface;
 
 public:
   NS_DECL_ISUPPORTS
 
-  virtual ~FrozenImage() { }
-
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
   virtual void IncrementAnimationConsumers() MOZ_OVERRIDE;
   virtual void DecrementAnimationConsumers() MOZ_OVERRIDE;
 
   NS_IMETHOD GetAnimated(bool* aAnimated) MOZ_OVERRIDE;
   NS_IMETHOD_(TemporaryRef<SourceSurface>)
     GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) FrameIsOpaque(uint32_t aWhichFrame) MOZ_OVERRIDE;
@@ -55,16 +53,17 @@ public:
   NS_IMETHOD_(void) RequestRefresh(const mozilla::TimeStamp& aTime) MOZ_OVERRIDE;
   NS_IMETHOD GetAnimationMode(uint16_t* aAnimationMode) MOZ_OVERRIDE;
   NS_IMETHOD SetAnimationMode(uint16_t aAnimationMode) MOZ_OVERRIDE;
   NS_IMETHOD ResetAnimation() MOZ_OVERRIDE;
   NS_IMETHOD_(float) GetFrameIndex(uint32_t aWhichFrame) MOZ_OVERRIDE;
 
 protected:
   FrozenImage(Image* aImage) : ImageWrapper(aImage) { }
+  virtual ~FrozenImage() { }
 
 private:
   friend class ImageOps;
 };
 
 } // namespace image
 } // namespace mozilla
 
--- a/image/src/ImageWrapper.h
+++ b/image/src/ImageWrapper.h
@@ -16,18 +16,16 @@ namespace image {
  * Abstract superclass for Images that wrap other Images.
  */
 class ImageWrapper : public Image
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGICONTAINER
 
-  virtual ~ImageWrapper() { }
-
   // Inherited methods from Image.
   virtual nsresult Init(const char* aMimeType, uint32_t aFlags) MOZ_OVERRIDE;
 
   virtual already_AddRefed<imgStatusTracker> GetStatusTracker() MOZ_OVERRIDE;
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
 
   virtual uint32_t SizeOfData() MOZ_OVERRIDE;
   virtual size_t HeapSizeOfSourceWithComputedFallback(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
@@ -66,16 +64,18 @@ public:
 
 protected:
   ImageWrapper(Image* aInnerImage)
     : mInnerImage(aInnerImage)
   {
     NS_ABORT_IF_FALSE(aInnerImage, "Cannot wrap a null image");
   }
 
+  virtual ~ImageWrapper() { }
+
   /**
    * Returns a weak reference to the inner image wrapped by this ImageWrapper.
    */
   Image* InnerImage() { return mInnerImage.get(); }
 
 private:
   nsRefPtr<Image> mInnerImage;
 };
--- a/image/src/OrientedImage.h
+++ b/image/src/OrientedImage.h
@@ -23,18 +23,16 @@ namespace image {
  */
 class OrientedImage : public ImageWrapper
 {
   typedef mozilla::gfx::SourceSurface SourceSurface;
 
 public:
   NS_DECL_ISUPPORTS
 
-  virtual ~OrientedImage() { }
-
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
 
   NS_IMETHOD GetWidth(int32_t* aWidth) MOZ_OVERRIDE;
   NS_IMETHOD GetHeight(int32_t* aHeight) MOZ_OVERRIDE;
   NS_IMETHOD GetIntrinsicSize(nsSize* aSize) MOZ_OVERRIDE;
   NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE;
   NS_IMETHOD_(mozilla::TemporaryRef<SourceSurface>)
     GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE;
@@ -51,16 +49,18 @@ public:
                   uint32_t aFlags) MOZ_OVERRIDE;
  
 protected:
   OrientedImage(Image* aImage, Orientation aOrientation)
     : ImageWrapper(aImage)
     , mOrientation(aOrientation)
   { }
 
+  virtual ~OrientedImage() { }
+
   gfxMatrix OrientationMatrix(const nsIntSize& aViewportSize);
 
 private:
   Orientation mOrientation;
 
   friend class ImageOps;
 };
 
--- a/image/src/RasterImage.h
+++ b/image/src/RasterImage.h
@@ -138,28 +138,28 @@ class FrameAnimator;
 
 class RasterImage : public ImageResource
                   , public nsIProperties
                   , public SupportsWeakPtr<RasterImage>
 #ifdef DEBUG
                   , public imgIContainerDebug
 #endif
 {
+  // (no public constructor - use ImageFactory)
+  virtual ~RasterImage();
+
 public:
   MOZ_DECLARE_REFCOUNTED_TYPENAME(RasterImage)
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIPROPERTIES
   NS_DECL_IMGICONTAINER
 #ifdef DEBUG
   NS_DECL_IMGICONTAINERDEBUG
 #endif
 
-  // (no public constructor - use ImageFactory)
-  virtual ~RasterImage();
-
   virtual nsresult StartAnimation();
   virtual nsresult StopAnimation();
 
   // Methods inherited from Image
   nsresult Init(const char* aMimeType,
                 uint32_t aFlags);
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
 
@@ -449,23 +449,22 @@ private:
     /**
      * Returns an event target interface to the thread pool; primarily for
      * OnDataAvailable delivery off main thread.
      *
      * @return An nsIEventTarget interface to mThreadPool.
      */
     already_AddRefed<nsIEventTarget> GetEventTarget();
 
-    virtual ~DecodePool();
-
   private: /* statics */
     static StaticRefPtr<DecodePool> sSingleton;
 
   private: /* methods */
     DecodePool();
+    virtual ~DecodePool();
 
     enum DecodeType {
       DECODE_TYPE_UNTIL_TIME,
       DECODE_TYPE_UNTIL_SIZE,
       DECODE_TYPE_UNTIL_DONE_BYTES
     };
 
     /* Decode some chunks of the given image.  If aDecodeType is UNTIL_SIZE,
--- a/image/src/SVGDocumentWrapper.h
+++ b/image/src/SVGDocumentWrapper.h
@@ -36,17 +36,16 @@ class SVGSVGElement;
 namespace image {
 
 class SVGDocumentWrapper MOZ_FINAL : public nsIStreamListener,
                                      public nsIObserver,
                                      nsSupportsWeakReference
 {
 public:
   SVGDocumentWrapper();
-  ~SVGDocumentWrapper();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSIOBSERVER
 
   enum Dimension {
     eWidth,
@@ -141,16 +140,18 @@ public:
   void TickRefreshDriver();
 
   /**
    * Force a layout flush of the underlying SVG document.
    */
   void FlushLayout();
 
 private:
+  ~SVGDocumentWrapper();
+
   nsresult SetupViewer(nsIRequest *aRequest,
                        nsIContentViewer** aViewer,
                        nsILoadGroup** aLoadGroup);
   void     DestroyViewer();
   void     RegisterForXPCOMShutdown();
   void     UnregisterForXPCOMShutdown();
 
   nsCOMPtr<nsIContentViewer>  mViewer;
--- a/image/src/ScriptedNotificationObserver.h
+++ b/image/src/ScriptedNotificationObserver.h
@@ -15,21 +15,21 @@ class imgIScriptedNotificationObserver;
 
 namespace mozilla {
 namespace image {
 
 class ScriptedNotificationObserver : public imgINotificationObserver
 {
 public:
   ScriptedNotificationObserver(imgIScriptedNotificationObserver* aInner);
-  virtual ~ScriptedNotificationObserver() {}
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_IMGINOTIFICATIONOBSERVER
   NS_DECL_CYCLE_COLLECTION_CLASS(ScriptedNotificationObserver)
 
 private:
+  virtual ~ScriptedNotificationObserver() {}
   nsCOMPtr<imgIScriptedNotificationObserver> mInner;
 };
 
 }}
 
 #endif
--- a/image/src/SurfaceCache.cpp
+++ b/image/src/SurfaceCache.cpp
@@ -218,25 +218,27 @@ public:
     , mMaxCost(aSurfaceCacheSize)
     , mAvailableCost(aSurfaceCacheSize)
   {
     nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     if (os)
       os->AddObserver(mMemoryPressureObserver, "memory-pressure", false);
   }
 
+private:
   virtual ~SurfaceCacheImpl()
   {
     nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     if (os)
       os->RemoveObserver(mMemoryPressureObserver, "memory-pressure");
 
     UnregisterWeakMemoryReporter(this);
   }
 
+public:
   void InitMemoryReporter() {
     RegisterWeakMemoryReporter(this);
   }
 
   void Insert(DrawTarget*       aTarget,
               IntSize           aTargetSize,
               const Cost        aCost,
               const ImageKey    aImageKey,
@@ -412,25 +414,26 @@ private:
   private:
     SurfaceCacheImpl* const mCache;  // Weak pointer to owner.
   };
 
   struct MemoryPressureObserver : public nsIObserver
   {
     NS_DECL_ISUPPORTS
 
-    virtual ~MemoryPressureObserver() { }
-
     NS_IMETHOD Observe(nsISupports*, const char* aTopic, const char16_t*)
     {
       if (sInstance && strcmp(aTopic, "memory-pressure") == 0) {
         sInstance->DiscardAll();
       }
       return NS_OK;
     }
+
+  private:
+    virtual ~MemoryPressureObserver() { }
   };
 
 
   nsTArray<CostEntry>                                       mCosts;
   nsRefPtrHashtable<nsPtrHashKey<Image>, ImageSurfaceCache> mImageCaches;
   SurfaceTracker                                            mExpirationTracker;
   nsRefPtr<MemoryPressureObserver>                          mMemoryPressureObserver;
   const Cost                                                mMaxCost;
--- a/image/src/VectorImage.cpp
+++ b/image/src/VectorImage.cpp
@@ -121,26 +121,28 @@ public:
     , mImage(aImage)
   {
     MOZ_ASSERT(mDocument, "Need an SVG document");
     MOZ_ASSERT(mImage, "Need an image");
 
     mDocument->AddObserver(this);
   }
 
+private:
   ~SVGParseCompleteListener()
   {
     if (mDocument) {
       // The document must have been destroyed before we got our event.
       // Otherwise this can't happen, since documents hold strong references to
       // their observers.
       Cancel();
     }
   }
 
+public:
   void EndLoad(nsIDocument* aDocument) MOZ_OVERRIDE
   {
     MOZ_ASSERT(aDocument == mDocument, "Got EndLoad for wrong document?");
 
     // OnSVGDocumentParsed will release our owner's reference to us, so ensure
     // we stick around long enough to complete our work.
     nsRefPtr<SVGParseCompleteListener> kungFuDeathGroup(this);
 
@@ -175,26 +177,28 @@ public:
     MOZ_ASSERT(mDocument, "Need an SVG document");
     MOZ_ASSERT(mImage, "Need an image");
 
     mDocument->AddEventListener(NS_LITERAL_STRING("MozSVGAsImageDocumentLoad"), this, true, false);
     mDocument->AddEventListener(NS_LITERAL_STRING("SVGAbort"), this, true, false);
     mDocument->AddEventListener(NS_LITERAL_STRING("SVGError"), this, true, false);
   }
 
+private:
   ~SVGLoadEventListener()
   {
     if (mDocument) {
       // The document must have been destroyed before we got our event.
       // Otherwise this can't happen, since documents hold strong references to
       // their observers.
       Cancel();
     }
   }
 
+public:
   NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) MOZ_OVERRIDE
   {
     MOZ_ASSERT(mDocument, "Need an SVG document. Received multiple events?");
 
     // OnSVGDocumentLoaded/OnSVGDocumentError will release our owner's reference
     // to us, so ensure we stick around long enough to complete our work.
     nsRefPtr<SVGLoadEventListener> kungFuDeathGroup(this);
 
--- a/image/src/VectorImage.h
+++ b/image/src/VectorImage.h
@@ -31,17 +31,16 @@ class VectorImage : public ImageResource
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_IMGICONTAINER
 
   // (no public constructor - use ImageFactory)
-  virtual ~VectorImage();
 
   // Methods inherited from Image
   nsresult Init(const char* aMimeType,
                 uint32_t aFlags);
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
 
   virtual size_t HeapSizeOfSourceWithComputedFallback(mozilla::MallocSizeOf aMallocSizeOf) const;
   virtual size_t HeapSizeOfDecodedWithComputedFallback(mozilla::MallocSizeOf aMallocSizeOf) const;
@@ -76,16 +75,17 @@ public:
 
   // Callbacks for SVGLoadEventListener.
   void OnSVGDocumentLoaded();
   void OnSVGDocumentError();
 
 protected:
   VectorImage(imgStatusTracker* aStatusTracker = nullptr,
               ImageURL* aURI = nullptr);
+  virtual ~VectorImage();
 
   virtual nsresult StartAnimation();
   virtual nsresult StopAnimation();
   virtual bool     ShouldAnimate();
 
   void CreateDrawableAndShow(const SVGDrawingParameters& aParams);
   void Show(gfxDrawable* aDrawable, const SVGDrawingParameters& aParams);
 
--- a/image/src/imgLoader.cpp
+++ b/image/src/imgLoader.cpp
@@ -47,16 +47,18 @@
 
 using namespace mozilla;
 using namespace mozilla::image;
 
 MOZ_DEFINE_MALLOC_SIZE_OF(ImagesMallocSizeOf)
 
 class imgMemoryReporter MOZ_FINAL : public nsIMemoryReporter
 {
+  ~imgMemoryReporter() {}
+
 public:
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aHandleReport,
                             nsISupports *aData, bool aAnonymize)
   {
     nsresult rv;
     ImageSizes chrome;
@@ -837,16 +839,18 @@ nsresult imgLoader::CreateNewProxyForReq
   // transfer reference to caller
   *_retval = proxyRequest;
 
   return NS_OK;
 }
 
 class imgCacheObserver MOZ_FINAL : public nsIObserver
 {
+  ~imgCacheObserver() {}
+
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 };
 
 NS_IMPL_ISUPPORTS(imgCacheObserver, nsIObserver)
 
 NS_IMETHODIMP
--- a/image/src/imgLoader.h
+++ b/image/src/imgLoader.h
@@ -206,31 +206,32 @@ private:
 };
 
 class imgLoader : public imgILoader,
                   public nsIContentSniffer,
                   public imgICache,
                   public nsSupportsWeakReference,
                   public nsIObserver
 {
+  virtual ~imgLoader();
+
 public:
   typedef mozilla::image::ImageURL ImageURL;
   typedef nsRefPtrHashtable<nsCStringHashKey, imgCacheEntry> imgCacheTable;
 
   NS_DECL_ISUPPORTS
   NS_DECL_IMGILOADER
   NS_DECL_NSICONTENTSNIFFER
   NS_DECL_IMGICACHE
   NS_DECL_NSIOBSERVER
 
   static imgLoader* Singleton();
   static imgLoader* PBSingleton();
 
   imgLoader();
-  virtual ~imgLoader();
 
   nsresult Init();
 
   static imgLoader* Create()
   {
       // Unfortunately, we rely on XPCOM module init happening
       // before imgLoader creation. For now, it's easier
       // to just call CallCreateInstance() which will init
@@ -394,25 +395,26 @@ private: // data
 #include "nsIStreamListener.h"
 #include "nsIThreadRetargetableStreamListener.h"
 
 class ProxyListener : public nsIStreamListener
                     , public nsIThreadRetargetableStreamListener
 {
 public:
   ProxyListener(nsIStreamListener *dest);
-  virtual ~ProxyListener();
 
   /* additional members */
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
 
 private:
+  virtual ~ProxyListener();
+
   nsCOMPtr<nsIStreamListener> mDestListener;
 };
 
 /**
  * A class that implements nsIProgressEventSink and forwards all calls to it to
  * the original notification callbacks of the channel. Also implements
  * nsIInterfaceRequestor and gives out itself for nsIProgressEventSink calls,
  * and forwards everything else to the channel's notification callbacks.
@@ -450,29 +452,30 @@ class imgCacheValidator : public nsIStre
                           public nsIThreadRetargetableStreamListener,
                           public nsIChannelEventSink,
                           public nsIInterfaceRequestor,
                           public nsIAsyncVerifyRedirectCallback
 {
 public:
   imgCacheValidator(nsProgressNotificationProxy* progress, imgLoader* loader,
                     imgRequest *request, void *aContext, bool forcePrincipalCheckForCacheEntry);
-  virtual ~imgCacheValidator();
 
   void AddProxy(imgRequestProxy *aProxy);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSICHANNELEVENTSINK
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
 
 private:
+  virtual ~imgCacheValidator();
+
   nsCOMPtr<nsIStreamListener> mDestListener;
   nsRefPtr<nsProgressNotificationProxy> mProgressProxy;
   nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
   nsCOMPtr<nsIChannel> mRedirectChannel;
 
   nsRefPtr<imgRequest> mRequest;
   nsCOMArray<imgIRequest> mProxies;
 
--- a/image/src/imgRequest.h
+++ b/image/src/imgRequest.h
@@ -41,20 +41,21 @@ class ImageURL;
 } // namespace mozilla
 
 class imgRequest : public nsIStreamListener,
                    public nsIThreadRetargetableStreamListener,
                    public nsIChannelEventSink,
                    public nsIInterfaceRequestor,
                    public nsIAsyncVerifyRedirectCallback
 {
+  virtual ~imgRequest();
+
 public:
   typedef mozilla::image::ImageURL ImageURL;
   imgRequest(imgLoader* aLoader);
-  virtual ~imgRequest();
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
   nsresult Init(nsIURI *aURI,
                 nsIURI *aCurrentURI,
                 nsIRequest *aRequest,
                 nsIChannel *aChannel,
                 imgCacheEntry *aCacheEntry,
--- a/image/src/imgRequestProxy.h
+++ b/image/src/imgRequestProxy.h
@@ -43,28 +43,30 @@ class ImageURL;
 } // namespace mozilla
 
 class imgRequestProxy : public imgIRequest,
                         public nsISupportsPriority,
                         public nsISecurityInfoProvider,
                         public nsITimedChannel,
                         public mozilla::SupportsWeakPtr<imgRequestProxy>
 {
+protected:
+  virtual ~imgRequestProxy();
+
 public:
   MOZ_DECLARE_REFCOUNTED_TYPENAME(imgRequestProxy)
   typedef mozilla::image::ImageURL ImageURL;
   NS_DECL_ISUPPORTS
   NS_DECL_IMGIREQUEST
   NS_DECL_NSIREQUEST
   NS_DECL_NSISUPPORTSPRIORITY
   NS_DECL_NSISECURITYINFOPROVIDER
   // nsITimedChannel declared below
 
   imgRequestProxy();
-  virtual ~imgRequestProxy();
 
   // Callers to Init or ChangeOwner are required to call NotifyListener after
   // (although not immediately after) doing so.
   nsresult Init(imgRequest* aOwner,
                 nsILoadGroup *aLoadGroup,
                 ImageURL* aURI,
                 imgINotificationObserver *aObserver);
 
--- a/image/src/imgTools.h
+++ b/image/src/imgTools.h
@@ -16,10 +16,12 @@
 
 class imgTools : public imgITools
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGITOOLS
 
   imgTools();
+
+private:
   virtual ~imgTools();
 };