Bug 1872536 - Use MakeUniqueFallible for large buffers in image decoders/encoders. r=gfx-reviewers,lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D197461
This commit is contained in:
Andrew Osmond 2023-12-31 22:16:46 +00:00
parent 35c465dca0
commit 0d3eae78e5
7 changed files with 50 additions and 13 deletions

View File

@ -28,6 +28,7 @@
#include "nsContentSecurityManager.h"
#include "nsNetUtil.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtrExtensions.h"
#include <Cocoa/Cocoa.h>
@ -318,7 +319,11 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval,
// - 1 byte for the image height, as u8
// - the raw image data as BGRA, width * height * 4 bytes.
size_t bufferCapacity = 4 + width * height * 4;
UniquePtr<uint8_t[]> fileBuf = MakeUnique<uint8_t[]>(bufferCapacity);
UniquePtr<uint8_t[]> fileBuf = MakeUniqueFallible<uint8_t[]>(bufferCapacity);
if (NS_WARN_IF(!fileBuf)) {
return NS_ERROR_OUT_OF_MEMORY;
}
fileBuf[0] = uint8_t(width);
fileBuf[1] = uint8_t(height);
fileBuf[2] = uint8_t(mozilla::gfx::SurfaceFormat::B8G8R8A8);

View File

@ -19,6 +19,7 @@
#include "mozilla/Telemetry.h"
#include "mozilla/TelemetryComms.h"
#include "mozilla/UniquePtrExtensions.h"
using namespace mozilla::gfx;
@ -685,7 +686,7 @@ bool OwnedAOMImage::CloneFrom(aom_image_t* aImage, bool aIsAlpha) {
// If aImage is alpha plane. The data is located in Y channel.
if (aIsAlpha) {
mBuffer = MakeUnique<uint8_t[]>(yBufSize);
mBuffer = MakeUniqueFallible<uint8_t[]>(yBufSize);
if (!mBuffer) {
return false;
}
@ -707,7 +708,7 @@ bool OwnedAOMImage::CloneFrom(aom_image_t* aImage, bool aIsAlpha) {
int crHeight = aom_img_plane_height(aImage, AOM_PLANE_V);
size_t crBufSize = crStride * crHeight;
mBuffer = MakeUnique<uint8_t[]>(yBufSize + cbBufSize + crBufSize);
mBuffer = MakeUniqueFallible<uint8_t[]>(yBufSize + cbBufSize + crBufSize);
if (!mBuffer) {
return false;
}
@ -1733,9 +1734,8 @@ nsAVIFDecoder::DecodeResult nsAVIFDecoder::DoDecodeInternal(
return AsVariant(NonDecoderResult::SizeOverflow);
}
UniquePtr<uint8_t[]> rgbBuf = MakeUnique<uint8_t[]>(rgbBufLength.value());
const uint8_t* endOfRgbBuf = {rgbBuf.get() + rgbBufLength.value()};
UniquePtr<uint8_t[]> rgbBuf =
MakeUniqueFallible<uint8_t[]>(rgbBufLength.value());
if (!rgbBuf) {
MOZ_LOG(sAVIFLog, LogLevel::Debug,
("[this=%p] allocation of %u-byte rgbBuf failed", this,
@ -1797,6 +1797,7 @@ nsAVIFDecoder::DecodeResult nsAVIFDecoder::DoDecodeInternal(
}
MOZ_LOG(sAVIFLog, LogLevel::Debug, ("[this=%p] writing to surface", this));
const uint8_t* endOfRgbBuf = {rgbBuf.get() + rgbBufLength.value()};
WriteState writeBufferResult = WriteState::NEED_MORE_DATA;
for (uint8_t* rowPtr = rgbBuf.get(); rowPtr < endOfRgbBuf;
rowPtr += rgbStride.value()) {

View File

@ -100,6 +100,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/EndianUtils.h"
#include "mozilla/Likely.h"
#include "mozilla/UniquePtrExtensions.h"
#include "RasterImage.h"
#include "SurfacePipeFactory.h"
@ -716,7 +717,10 @@ LexerTransition<nsBMPDecoder::State> nsBMPDecoder::ReadBitfields(
// Always allocate and zero 256 entries, even though mNumColors might be
// smaller, because the file might erroneously index past mNumColors.
mColors = MakeUnique<ColorTableEntry[]>(256);
mColors = MakeUniqueFallible<ColorTableEntry[]>(256);
if (NS_WARN_IF(!mColors)) {
return Transition::TerminateFailure();
}
memset(mColors.get(), 0, 256 * sizeof(ColorTableEntry));
// OS/2 Bitmaps have no padding byte.

View File

@ -15,6 +15,7 @@
#include "RasterImage.h"
#include "mozilla/EndianUtils.h"
#include "mozilla/gfx/Swizzle.h"
#include "mozilla/UniquePtrExtensions.h"
using namespace mozilla::gfx;
@ -490,7 +491,11 @@ LexerTransition<ICOState> nsICODecoder::PrepareForMask() {
MOZ_ASSERT(bmpDecoder->GetImageDataLength() ==
mDownscaler->TargetSize().width *
mDownscaler->TargetSize().height * sizeof(uint32_t));
mMaskBuffer = MakeUnique<uint8_t[]>(bmpDecoder->GetImageDataLength());
mMaskBuffer =
MakeUniqueFallible<uint8_t[]>(bmpDecoder->GetImageDataLength());
if (NS_WARN_IF(!mMaskBuffer)) {
return Transition::TerminateFailure();
}
nsresult rv = mDownscaler->BeginFrame(mDirEntry->mSize.ToUnknownSize(),
Nothing(), mMaskBuffer.get(),
/* aHasAlpha = */ true,

View File

@ -9,6 +9,7 @@
#include "nsStreamUtils.h"
#include "gfxColor.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/UniquePtrExtensions.h"
extern "C" {
#include "jpeglib.h"
@ -148,6 +149,15 @@ nsJPEGEncoder::InitFromData(const uint8_t* aData,
}
}
UniquePtr<uint8_t[]> rowptr;
if (aInputFormat == INPUT_FORMAT_RGBA ||
aInputFormat == INPUT_FORMAT_HOSTARGB) {
rowptr = MakeUniqueFallible<uint8_t[]>(aWidth * 3);
if (NS_WARN_IF(!rowptr)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
jpeg_compress_struct cinfo;
// We set up the normal JPEG error routines, then override error_exit.
@ -196,14 +206,14 @@ nsJPEGEncoder::InitFromData(const uint8_t* aData,
jpeg_write_scanlines(&cinfo, const_cast<uint8_t**>(&row), 1);
}
} else if (aInputFormat == INPUT_FORMAT_RGBA) {
UniquePtr<uint8_t[]> rowptr = MakeUnique<uint8_t[]>(aWidth * 3);
MOZ_ASSERT(rowptr);
uint8_t* row = rowptr.get();
while (cinfo.next_scanline < cinfo.image_height) {
ConvertRGBARow(&aData[cinfo.next_scanline * aStride], row, aWidth);
jpeg_write_scanlines(&cinfo, &row, 1);
}
} else if (aInputFormat == INPUT_FORMAT_HOSTARGB) {
UniquePtr<uint8_t[]> rowptr = MakeUnique<uint8_t[]>(aWidth * 3);
MOZ_ASSERT(rowptr);
uint8_t* row = rowptr.get();
while (cinfo.next_scanline < cinfo.image_height) {
ConvertHostARGBRow(&aData[cinfo.next_scanline * aStride], row, aWidth);

View File

@ -10,6 +10,7 @@
#include "nsString.h"
#include "prprf.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/UniquePtrExtensions.h"
using namespace mozilla;
@ -278,7 +279,10 @@ nsPNGEncoder::AddImageFrame(const uint8_t* aData,
if (aInputFormat == INPUT_FORMAT_HOSTARGB) {
// PNG requires RGBA with post-multiplied alpha, so we need to
// convert
UniquePtr<uint8_t[]> row = MakeUnique<uint8_t[]>(aWidth * 4);
UniquePtr<uint8_t[]> row = MakeUniqueFallible<uint8_t[]>(aWidth * 4);
if (NS_WARN_IF(!row)) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t y = 0; y < aHeight; y++) {
ConvertHostARGBRow(&aData[y * aStride], row.get(), aWidth,
useTransparency);
@ -286,7 +290,10 @@ nsPNGEncoder::AddImageFrame(const uint8_t* aData,
}
} else if (aInputFormat == INPUT_FORMAT_RGBA && !useTransparency) {
// RBGA, but we need to strip the alpha
UniquePtr<uint8_t[]> row = MakeUnique<uint8_t[]>(aWidth * 4);
UniquePtr<uint8_t[]> row = MakeUniqueFallible<uint8_t[]>(aWidth * 4);
if (NS_WARN_IF(!row)) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t y = 0; y < aHeight; y++) {
StripAlpha(&aData[y * aStride], row.get(), aWidth);
png_write_row(mPNG, row.get());

View File

@ -10,6 +10,7 @@
#include "nsString.h"
#include "prprf.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/UniquePtrExtensions.h"
using namespace mozilla;
@ -124,7 +125,11 @@ nsWebPEncoder::InitFromData(const uint8_t* aData,
: WebPEncodeRGBA(aData, width.value(), height.value(),
stride.value(), quality, &mImageBuffer);
} else if (aInputFormat == INPUT_FORMAT_HOSTARGB) {
UniquePtr<uint8_t[]> aDest = MakeUnique<uint8_t[]>(aStride * aHeight);
UniquePtr<uint8_t[]> aDest =
MakeUniqueFallible<uint8_t[]>(aStride * aHeight);
if (NS_WARN_IF(!aDest)) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t y = 0; y < aHeight; y++) {
for (uint32_t x = 0; x < aWidth; x++) {