Move surface data checking to a separate function to make it less "totally nuts"

This commit is contained in:
wolfbeast 2018-09-11 12:47:26 +02:00 committed by Roy Tam
commit 918ef0183a
2 changed files with 47 additions and 12 deletions

View file

@ -7596,6 +7596,23 @@ nsContentUtils::IsFileImage(nsIFile* aFile, nsACString& aType)
return StringBeginsWith(aType, NS_LITERAL_CSTRING("image/"));
}
nsresult
nsContentUtils::CalculateBufferSizeForImage(const uint32_t& aStride,
const IntSize& aImageSize,
const SurfaceFormat& aFormat,
size_t* aMaxBufferSize,
size_t* aUsedBufferSize)
{
CheckedInt32 requiredBytes =
CheckedInt32(aStride) * CheckedInt32(aImageSize.height);
if (!requiredBytes.isValid()) {
return NS_ERROR_FAILURE;
}
*aMaxBufferSize = requiredBytes.value();
*aUsedBufferSize = *aMaxBufferSize - aStride + (aImageSize.width * BytesPerPixel(aFormat));
return NS_OK;
}
nsresult
nsContentUtils::DataTransferItemToImage(const IPCDataTransferItem& aItem,
imgIContainer** aContainer)
@ -7611,6 +7628,21 @@ nsContentUtils::DataTransferItemToImage(const IPCDataTransferItem& aItem,
Shmem data = aItem.data().get_Shmem();
// Validate shared memory buffer size
size_t imageBufLen = 0;
size_t maxBufLen = 0;
nsresult rv = CalculateBufferSizeForImage(imageDetails.stride(),
size,
imageDetails.format(),
&maxBufLen,
&imageBufLen);
if (NS_FAILED(rv)) {
return rv;
}
if (imageBufLen > data.Size<uint8_t>()) {
return NS_ERROR_FAILURE;
}
RefPtr<DataSourceSurface> image =
CreateDataSourceSurfaceFromData(size,
static_cast<SurfaceFormat>(imageDetails.format()),
@ -7950,20 +7982,17 @@ GetSurfaceDataImpl(mozilla::gfx::DataSourceSurface* aSurface,
return GetSurfaceDataContext::NullValue();
}
mozilla::gfx::IntSize size = aSurface->GetSize();
mozilla::CheckedInt32 requiredBytes =
mozilla::CheckedInt32(map.mStride) * mozilla::CheckedInt32(size.height);
if (!requiredBytes.isValid()) {
size_t bufLen = 0;
size_t maxBufLen = 0;
nsresult rv = nsContentUtils::CalculateBufferSizeForImage(map.mStride,
aSurface->GetSize(),
aSurface->GetFormat(),
&maxBufLen,
&bufLen);
if (NS_FAILED(rv)) {
return GetSurfaceDataContext::NullValue();
}
size_t maxBufLen = requiredBytes.value();
mozilla::gfx::SurfaceFormat format = aSurface->GetFormat();
// Surface data handling is totally nuts. This is the magic one needs to
// know to access the data.
size_t bufLen = maxBufLen - map.mStride + (size.width * BytesPerPixel(format));
// nsDependentCString wants null-terminated string.
typename GetSurfaceDataContext::ReturnType surfaceData = aContext.Allocate(maxBufLen + 1);
if (GetSurfaceDataContext::GetBuffer(surfaceData)) {