diff --git a/dom/html/TextTrackManager.cpp b/dom/html/TextTrackManager.cpp
index 4b69675a0d..b68fdb6aca 100644
--- a/dom/html/TextTrackManager.cpp
+++ b/dom/html/TextTrackManager.cpp
@@ -211,6 +211,7 @@ TextTrackManager::AddCues(TextTrack* aTextTrack)
for (uint32_t i = 0; i < cueList->Length(); ++i) {
mNewCues->AddCue(*cueList->IndexedGetter(i, dummy));
}
+ RefPtr kungFuDeathGrip(this);
DispatchTimeMarchesOn();
}
}
@@ -236,6 +237,7 @@ TextTrackManager::RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly)
for (uint32_t i = 0; i < removeCueList->Length(); ++i) {
mNewCues->RemoveCue(*((*removeCueList)[i]));
}
+ RefPtr kungFuDeathGrip(this);
DispatchTimeMarchesOn();
}
}
@@ -305,6 +307,7 @@ TextTrackManager::NotifyCueAdded(TextTrackCue& aCue)
if (mNewCues) {
mNewCues->AddCue(aCue);
}
+ RefPtr kungFuDeathGrip(this);
DispatchTimeMarchesOn();
}
@@ -315,6 +318,7 @@ TextTrackManager::NotifyCueRemoved(TextTrackCue& aCue)
if (mNewCues) {
mNewCues->RemoveCue(aCue);
}
+ RefPtr kungFuDeathGrip(this);
DispatchTimeMarchesOn();
if (aCue.GetActive()) {
// We remove an active cue, need to update the display.
@@ -824,6 +828,7 @@ TextTrackManager::NotifyCueUpdated(TextTrackCue *aCue)
{
// TODO: Add/Reorder the cue to mNewCues if we have some optimization?
WEBVTT_LOG("NotifyCueUpdated");
+ RefPtr kungFuDeathGrip(this);
DispatchTimeMarchesOn();
}
diff --git a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
index 18c15df429..27a9e9bf8c 100644
--- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
@@ -83,7 +83,7 @@ CopyAndPackAudio(AVFrame* aFrame, uint32_t aNumChannels, uint32_t aNumAFrames)
#ifdef MOZ_SAMPLE_TYPE_FLOAT32
// Planar audio data. Pack it into something we can understand.
AudioDataValue* tmp = audio.get();
- AudioDataValue** data = reinterpret_cast(aFrame->data);
+ AudioDataValue** data = reinterpret_cast(aFrame->extended_data);
for (uint32_t frame = 0; frame < aNumAFrames; frame++) {
for (uint32_t channel = 0; channel < aNumChannels; channel++) {
*tmp++ = data[channel][frame];
@@ -121,7 +121,7 @@ CopyAndPackAudio(AVFrame* aFrame, uint32_t aNumChannels, uint32_t aNumAFrames)
// Planar audio data. Convert it from S16 to 32 bits float
// and pack it into something we can understand.
AudioDataValue* tmp = audio.get();
- int16_t** data = reinterpret_cast(aFrame->data);
+ int16_t** data = reinterpret_cast(aFrame->extended_data);
for (uint32_t frame = 0; frame < aNumAFrames; frame++) {
for (uint32_t channel = 0; channel < aNumChannels; channel++) {
*tmp++ = AudioSampleToFloat(data[channel][frame]);
@@ -140,7 +140,7 @@ CopyAndPackAudio(AVFrame* aFrame, uint32_t aNumChannels, uint32_t aNumAFrames)
// Planar audio data. Convert it from S32 to 32 bits float
// and pack it into something we can understand.
AudioDataValue* tmp = audio.get();
- int32_t** data = reinterpret_cast(aFrame->data);
+ int32_t** data = reinterpret_cast(aFrame->extended_data);
for (uint32_t frame = 0; frame < aNumAFrames; frame++) {
for (uint32_t channel = 0; channel < aNumChannels; channel++) {
*tmp++ = AudioSampleToFloat(data[channel][frame]);
diff --git a/gfx/ots/src/cmap.cc b/gfx/ots/src/cmap.cc
index 72c2a20fc4..9cfd0039b6 100644
--- a/gfx/ots/src/cmap.cc
+++ b/gfx/ots/src/cmap.cc
@@ -314,8 +314,9 @@ bool OpenTypeCMAP::Parse31012(const uint8_t *data, size_t length,
return Error("format 12 subtable group endCharCode before startCharCode (0x%4X < 0x%4X)",
groups[i].end_range, groups[i].start_range);
}
+ // Maximum glyph ID must be less than num_glyphs.
if ((groups[i].end_range - groups[i].start_range) +
- groups[i].start_glyph_id > num_glyphs) {
+ groups[i].start_glyph_id >= num_glyphs) {
return Error("bad format 12 subtable group startGlyphID (%d)", groups[i].start_glyph_id);
}
}
diff --git a/gfx/thebes/gfxHarfBuzzShaper.cpp b/gfx/thebes/gfxHarfBuzzShaper.cpp
index 7f05f9011f..23dddb604f 100644
--- a/gfx/thebes/gfxHarfBuzzShaper.cpp
+++ b/gfx/thebes/gfxHarfBuzzShaper.cpp
@@ -554,15 +554,17 @@ gfxHarfBuzzShaper::FindGlyf(hb_codepoint_t aGlyph, bool *aEmptyGlyf) const
uint32_t len;
const char* data = hb_blob_get_data(mLocaTable, &len);
if (mLocaLongOffsets) {
- if ((aGlyph + 1) * sizeof(AutoSwap_PRUint32) > len) {
+ // We read offsets[aGlyph] and offsets[aGlyph + 1], so require aGlyph + 2 entries.
+ if ((aGlyph + 2) * sizeof(AutoSwap_PRUint32) > len) {
return nullptr;
}
const AutoSwap_PRUint32* offsets =
reinterpret_cast(data);
offset = offsets[aGlyph];
- *aEmptyGlyf = (offset == uint16_t(offsets[aGlyph + 1]));
+ *aEmptyGlyf = (offset == uint32_t(offsets[aGlyph + 1]));
} else {
- if ((aGlyph + 1) * sizeof(AutoSwap_PRUint16) > len) {
+ // Ditto aGlyph + 2 entries.
+ if ((aGlyph + 2) * sizeof(AutoSwap_PRUint16) > len) {
return nullptr;
}
const AutoSwap_PRUint16* offsets =
diff --git a/image/ImageWrapper.cpp b/image/ImageWrapper.cpp
index c593521c9e..1e3bd3a2f0 100644
--- a/image/ImageWrapper.cpp
+++ b/image/ImageWrapper.cpp
@@ -252,7 +252,8 @@ ImageWrapper::RequestDiscard()
NS_IMETHODIMP_(void)
ImageWrapper::RequestRefresh(const TimeStamp& aTime)
{
- return mInnerImage->RequestRefresh(aTime);
+ RefPtr inner = mInnerImage;
+ return inner->RequestRefresh(aTime);
}
NS_IMETHODIMP
diff --git a/image/RasterImage.cpp b/image/RasterImage.cpp
index 31a6d7a991..af639f3386 100644
--- a/image/RasterImage.cpp
+++ b/image/RasterImage.cpp
@@ -94,6 +94,8 @@ RasterImage::RasterImage(ImageURL* aURI /* = nullptr */) :
//******************************************************************************
RasterImage::~RasterImage()
{
+ mIsBeingDestroyed = true;
+
// Make sure our SourceBuffer is marked as complete. This will ensure that any
// outstanding decoders terminate.
if (!mSourceBuffer->IsComplete()) {
@@ -429,8 +431,11 @@ RasterImage::OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey)
{
MOZ_ASSERT(mProgressTracker);
- bool animatedFramesDiscarded =
- mAnimationState && aSurfaceKey.Playback() == PlaybackType::eAnimated;
+ if (mIsBeingDestroyed) {
+ return;
+ }
+
+ bool animatedFramesDiscarded = aSurfaceKey.Playback() == PlaybackType::eAnimated;
RefPtr image = this;
NS_DispatchToMainThread(NS_NewRunnableFunction([=]() -> void {
diff --git a/image/RasterImage.h b/image/RasterImage.h
index e1a7cb1506..64596ff924 100644
--- a/image/RasterImage.h
+++ b/image/RasterImage.h
@@ -17,6 +17,7 @@
#ifndef mozilla_image_RasterImage_h
#define mozilla_image_RasterImage_h
+#include "mozilla/Atomics.h"
#include "Image.h"
#include "nsCOMPtr.h"
#include "imgIContainer.h"
@@ -384,10 +385,10 @@ private: // data
/// If this has a value, we're waiting for SetSize() to send the load event.
Maybe