diff options
Diffstat (limited to 'gnu/packages/patches/icecat-CVE-2016-1952-pt01.patch')
-rw-r--r-- | gnu/packages/patches/icecat-CVE-2016-1952-pt01.patch | 356 |
1 files changed, 0 insertions, 356 deletions
diff --git a/gnu/packages/patches/icecat-CVE-2016-1952-pt01.patch b/gnu/packages/patches/icecat-CVE-2016-1952-pt01.patch deleted file mode 100644 index 2b711b1761..0000000000 --- a/gnu/packages/patches/icecat-CVE-2016-1952-pt01.patch +++ /dev/null @@ -1,356 +0,0 @@ -Copied from upstream: -https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/c1d67bd4c993 - -# HG changeset patch -# User Timothy Nikkel <tnikkel@gmail.com> -# Date 1454023801 21600 -# Node ID c1d67bd4c993b9e344c68954e6f0392c82b81e38 -# Parent 530559abe159d3c23f078d673d30ff03d9c244e2 -Bug 1224979 - Check if we compute usable filters for the downscaler, and if not put the downscaler in error state so it's not used. r=edwin, a=al - -diff --git a/image/Downscaler.cpp b/image/Downscaler.cpp -new file mode 100644 ---- /dev/null -+++ b/image/Downscaler.cpp -@@ -0,0 +1,340 @@ -+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+ * -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+#include "Downscaler.h" -+ -+#include <algorithm> -+#include <ctime> -+#include "gfxPrefs.h" -+#include "image_operations.h" -+#include "mozilla/SSE.h" -+#include "convolver.h" -+#include "skia/include/core/SkTypes.h" -+ -+using std::max; -+using std::swap; -+ -+namespace mozilla { -+namespace image { -+ -+Downscaler::Downscaler(const nsIntSize& aTargetSize) -+ : mTargetSize(aTargetSize) -+ , mOutputBuffer(nullptr) -+ , mXFilter(MakeUnique<skia::ConvolutionFilter1D>()) -+ , mYFilter(MakeUnique<skia::ConvolutionFilter1D>()) -+ , mWindowCapacity(0) -+ , mHasAlpha(true) -+ , mFlipVertically(false) -+{ -+ MOZ_ASSERT(gfxPrefs::ImageDownscaleDuringDecodeEnabled(), -+ "Downscaling even though downscale-during-decode is disabled?"); -+ MOZ_ASSERT(mTargetSize.width > 0 && mTargetSize.height > 0, -+ "Invalid target size"); -+} -+ -+Downscaler::~Downscaler() -+{ -+ ReleaseWindow(); -+} -+ -+void -+Downscaler::ReleaseWindow() -+{ -+ if (!mWindow) { -+ return; -+ } -+ -+ for (int32_t i = 0; i < mWindowCapacity; ++i) { -+ delete[] mWindow[i]; -+ } -+ -+ mWindow = nullptr; -+ mWindowCapacity = 0; -+} -+ -+nsresult -+Downscaler::BeginFrame(const nsIntSize& aOriginalSize, -+ const Maybe<nsIntRect>& aFrameRect, -+ uint8_t* aOutputBuffer, -+ bool aHasAlpha, -+ bool aFlipVertically /* = false */) -+{ -+ MOZ_ASSERT(aOutputBuffer); -+ MOZ_ASSERT(mTargetSize != aOriginalSize, -+ "Created a downscaler, but not downscaling?"); -+ MOZ_ASSERT(mTargetSize.width <= aOriginalSize.width, -+ "Created a downscaler, but width is larger"); -+ MOZ_ASSERT(mTargetSize.height <= aOriginalSize.height, -+ "Created a downscaler, but height is larger"); -+ MOZ_ASSERT(aOriginalSize.width > 0 && aOriginalSize.height > 0, -+ "Invalid original size"); -+ -+ mFrameRect = aFrameRect.valueOr(nsIntRect(nsIntPoint(), aOriginalSize)); -+ MOZ_ASSERT(mFrameRect.x >= 0 && mFrameRect.y >= 0 && -+ mFrameRect.width >= 0 && mFrameRect.height >= 0, -+ "Frame rect must have non-negative components"); -+ MOZ_ASSERT(nsIntRect(0, 0, aOriginalSize.width, aOriginalSize.height) -+ .Contains(mFrameRect), -+ "Frame rect must fit inside image"); -+ MOZ_ASSERT_IF(!nsIntRect(0, 0, aOriginalSize.width, aOriginalSize.height) -+ .IsEqualEdges(mFrameRect), -+ aHasAlpha); -+ -+ mOriginalSize = aOriginalSize; -+ mScale = gfxSize(double(mOriginalSize.width) / mTargetSize.width, -+ double(mOriginalSize.height) / mTargetSize.height); -+ mOutputBuffer = aOutputBuffer; -+ mHasAlpha = aHasAlpha; -+ mFlipVertically = aFlipVertically; -+ -+ ReleaseWindow(); -+ -+ auto resizeMethod = skia::ImageOperations::RESIZE_LANCZOS3; -+ -+ skia::resize::ComputeFilters(resizeMethod, -+ mOriginalSize.width, mTargetSize.width, -+ 0, mTargetSize.width, -+ mXFilter.get()); -+ -+ if (mXFilter->max_filter() <= 0 || mXFilter->num_values() != mTargetSize.width) { -+ NS_WARNING("Failed to compute filters for image downscaling"); -+ return NS_ERROR_OUT_OF_MEMORY; -+ } -+ -+ skia::resize::ComputeFilters(resizeMethod, -+ mOriginalSize.height, mTargetSize.height, -+ 0, mTargetSize.height, -+ mYFilter.get()); -+ -+ if (mYFilter->max_filter() <= 0 || mYFilter->num_values() != mTargetSize.height) { -+ NS_WARNING("Failed to compute filters for image downscaling"); -+ return NS_ERROR_OUT_OF_MEMORY; -+ } -+ -+ // Allocate the buffer, which contains scanlines of the original image. -+ // pad by 15 to handle overreads by the simd code -+ size_t bufferLen = mOriginalSize.width * sizeof(uint32_t) + 15; -+ mRowBuffer.reset(new (fallible) uint8_t[bufferLen]); -+ if (MOZ_UNLIKELY(!mRowBuffer)) { -+ return NS_ERROR_OUT_OF_MEMORY; -+ } -+ -+ // Zero buffer to keep valgrind happy. -+ memset(mRowBuffer.get(), 0, bufferLen); -+ -+ // Allocate the window, which contains horizontally downscaled scanlines. (We -+ // can store scanlines which are already downscale because our downscaling -+ // filter is separable.) -+ mWindowCapacity = mYFilter->max_filter(); -+ mWindow.reset(new (fallible) uint8_t*[mWindowCapacity]); -+ if (MOZ_UNLIKELY(!mWindow)) { -+ return NS_ERROR_OUT_OF_MEMORY; -+ } -+ -+ bool anyAllocationFailed = false; -+ // pad by 15 to handle overreads by the simd code -+ const int rowSize = mTargetSize.width * sizeof(uint32_t) + 15; -+ for (int32_t i = 0; i < mWindowCapacity; ++i) { -+ mWindow[i] = new (fallible) uint8_t[rowSize]; -+ anyAllocationFailed = anyAllocationFailed || mWindow[i] == nullptr; -+ } -+ -+ if (MOZ_UNLIKELY(anyAllocationFailed)) { -+ // We intentionally iterate through the entire array even if an allocation -+ // fails, to ensure that all the pointers in it are either valid or nullptr. -+ // That in turn ensures that ReleaseWindow() can clean up correctly. -+ return NS_ERROR_OUT_OF_MEMORY; -+ } -+ -+ ResetForNextProgressivePass(); -+ -+ return NS_OK; -+} -+ -+void -+Downscaler::SkipToRow(int32_t aRow) -+{ -+ if (mCurrentInLine < aRow) { -+ ClearRow(); -+ do { -+ CommitRow(); -+ } while (mCurrentInLine < aRow); -+ } -+} -+ -+void -+Downscaler::ResetForNextProgressivePass() -+{ -+ mPrevInvalidatedLine = 0; -+ mCurrentOutLine = 0; -+ mCurrentInLine = 0; -+ mLinesInBuffer = 0; -+ -+ if (mFrameRect.IsEmpty()) { -+ // Our frame rect is zero size; commit rows until the end of the image. -+ SkipToRow(mOriginalSize.height - 1); -+ } else { -+ // If we have a vertical offset, commit rows to shift us past it. -+ SkipToRow(mFrameRect.y); -+ } -+} -+ -+static void -+GetFilterOffsetAndLength(UniquePtr<skia::ConvolutionFilter1D>& aFilter, -+ int32_t aOutputImagePosition, -+ int32_t* aFilterOffsetOut, -+ int32_t* aFilterLengthOut) -+{ -+ MOZ_ASSERT(aOutputImagePosition < aFilter->num_values()); -+ aFilter->FilterForValue(aOutputImagePosition, -+ aFilterOffsetOut, -+ aFilterLengthOut); -+} -+ -+void -+Downscaler::ClearRow(uint32_t aStartingAtCol) -+{ -+ MOZ_ASSERT(int64_t(mOriginalSize.width) > int64_t(aStartingAtCol)); -+ uint32_t bytesToClear = (mOriginalSize.width - aStartingAtCol) -+ * sizeof(uint32_t); -+ memset(mRowBuffer.get() + (aStartingAtCol * sizeof(uint32_t)), -+ 0, bytesToClear); -+} -+ -+void -+Downscaler::CommitRow() -+{ -+ MOZ_ASSERT(mOutputBuffer, "Should have a current frame"); -+ MOZ_ASSERT(mCurrentInLine < mOriginalSize.height, "Past end of input"); -+ -+ if (mCurrentOutLine < mTargetSize.height) { -+ int32_t filterOffset = 0; -+ int32_t filterLength = 0; -+ GetFilterOffsetAndLength(mYFilter, mCurrentOutLine, -+ &filterOffset, &filterLength); -+ -+ int32_t inLineToRead = filterOffset + mLinesInBuffer; -+ MOZ_ASSERT(mCurrentInLine <= inLineToRead, "Reading past end of input"); -+ if (mCurrentInLine == inLineToRead) { -+ skia::ConvolveHorizontally(mRowBuffer.get(), *mXFilter, -+ mWindow[mLinesInBuffer++], mHasAlpha, -+ supports_sse2()); -+ } -+ -+ MOZ_ASSERT(mCurrentOutLine < mTargetSize.height, -+ "Writing past end of output"); -+ -+ while (mLinesInBuffer == filterLength) { -+ DownscaleInputLine(); -+ -+ if (mCurrentOutLine == mTargetSize.height) { -+ break; // We're done. -+ } -+ -+ GetFilterOffsetAndLength(mYFilter, mCurrentOutLine, -+ &filterOffset, &filterLength); -+ } -+ } -+ -+ mCurrentInLine += 1; -+ -+ // If we're at the end of the part of the original image that has data, commit -+ // rows to shift us to the end. -+ if (mCurrentInLine == (mFrameRect.y + mFrameRect.height)) { -+ SkipToRow(mOriginalSize.height - 1); -+ } -+} -+ -+bool -+Downscaler::HasInvalidation() const -+{ -+ return mCurrentOutLine > mPrevInvalidatedLine; -+} -+ -+DownscalerInvalidRect -+Downscaler::TakeInvalidRect() -+{ -+ if (MOZ_UNLIKELY(!HasInvalidation())) { -+ return DownscalerInvalidRect(); -+ } -+ -+ DownscalerInvalidRect invalidRect; -+ -+ // Compute the target size invalid rect. -+ if (mFlipVertically) { -+ // We need to flip it. This will implicitly flip the original size invalid -+ // rect, since we compute it by scaling this rect. -+ invalidRect.mTargetSizeRect = -+ IntRect(0, mTargetSize.height - mCurrentOutLine, -+ mTargetSize.width, mCurrentOutLine - mPrevInvalidatedLine); -+ } else { -+ invalidRect.mTargetSizeRect = -+ IntRect(0, mPrevInvalidatedLine, -+ mTargetSize.width, mCurrentOutLine - mPrevInvalidatedLine); -+ } -+ -+ mPrevInvalidatedLine = mCurrentOutLine; -+ -+ // Compute the original size invalid rect. -+ invalidRect.mOriginalSizeRect = invalidRect.mTargetSizeRect; -+ invalidRect.mOriginalSizeRect.ScaleRoundOut(mScale.width, mScale.height); -+ -+ return invalidRect; -+} -+ -+void -+Downscaler::DownscaleInputLine() -+{ -+ typedef skia::ConvolutionFilter1D::Fixed FilterValue; -+ -+ MOZ_ASSERT(mOutputBuffer); -+ MOZ_ASSERT(mCurrentOutLine < mTargetSize.height, -+ "Writing past end of output"); -+ -+ int32_t filterOffset = 0; -+ int32_t filterLength = 0; -+ MOZ_ASSERT(mCurrentOutLine < mYFilter->num_values()); -+ auto filterValues = -+ mYFilter->FilterForValue(mCurrentOutLine, &filterOffset, &filterLength); -+ -+ int32_t currentOutLine = mFlipVertically -+ ? mTargetSize.height - (mCurrentOutLine + 1) -+ : mCurrentOutLine; -+ MOZ_ASSERT(currentOutLine >= 0); -+ -+ uint8_t* outputLine = -+ &mOutputBuffer[currentOutLine * mTargetSize.width * sizeof(uint32_t)]; -+ skia::ConvolveVertically(static_cast<const FilterValue*>(filterValues), -+ filterLength, mWindow.get(), mXFilter->num_values(), -+ outputLine, mHasAlpha, supports_sse2()); -+ -+ mCurrentOutLine += 1; -+ -+ if (mCurrentOutLine == mTargetSize.height) { -+ // We're done. -+ return; -+ } -+ -+ int32_t newFilterOffset = 0; -+ int32_t newFilterLength = 0; -+ GetFilterOffsetAndLength(mYFilter, mCurrentOutLine, -+ &newFilterOffset, &newFilterLength); -+ -+ int diff = newFilterOffset - filterOffset; -+ MOZ_ASSERT(diff >= 0, "Moving backwards in the filter?"); -+ -+ // Shift the buffer. We're just moving pointers here, so this is cheap. -+ mLinesInBuffer -= diff; -+ mLinesInBuffer = max(mLinesInBuffer, 0); -+ for (int32_t i = 0; i < mLinesInBuffer; ++i) { -+ swap(mWindow[i], mWindow[filterLength - mLinesInBuffer + i]); -+ } -+} -+ -+ -+ -+} // namespace image -+} // namespace mozilla - |