Bug 1902439 - Checks return of nsIOutputStream::Write() to NS_OK in WriteBitmap() to handle failures better. r=mpohle,nrishel
Differential Revision: https://phabricator.services.mozilla.com/D234318
This commit is contained in:
committed by
nrishel@mozilla.com
parent
961b5b96ff
commit
0e104cbe54
@@ -616,39 +616,55 @@ static nsresult WriteBitmap(nsIFile* aFile, imgIContainer* aImage) {
|
||||
rv = NS_NewLocalFileOutputStream(getter_AddRefs(stream), aFile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
gfx::DataSourceSurface::MappedSurface map;
|
||||
if (!dataSurface->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
|
||||
// (redundant) guard clause to assert stream is initialized
|
||||
if (NS_WARN_IF(!stream)) {
|
||||
MOZ_ASSERT(stream, "rv should have failed when stream is not initialized.");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// write the bitmap headers and rgb pixel data to the file
|
||||
rv = NS_ERROR_FAILURE;
|
||||
if (stream) {
|
||||
gfx::DataSourceSurface::MappedSurface map;
|
||||
if (!dataSurface->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
|
||||
// removal of file created handled later
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// enter only if datasurface mapping succeeded
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// write the bitmap headers and rgb pixel data to the file
|
||||
uint32_t written;
|
||||
stream->Write((const char*)&bf, sizeof(BITMAPFILEHEADER), &written);
|
||||
if (written == sizeof(BITMAPFILEHEADER)) {
|
||||
stream->Write((const char*)&bmi, sizeof(BITMAPINFOHEADER), &written);
|
||||
if (written == sizeof(BITMAPINFOHEADER)) {
|
||||
rv = stream->Write((const char*)&bf, sizeof(BITMAPFILEHEADER), &written);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = stream->Write((const char*)&bmi, sizeof(BITMAPINFOHEADER), &written);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// write out the image data backwards because the desktop won't
|
||||
// show bitmaps with negative heights for top-to-bottom
|
||||
uint32_t i = map.mStride * height;
|
||||
do {
|
||||
i -= map.mStride;
|
||||
stream->Write(((const char*)map.mData) + i, bytesPerRow, &written);
|
||||
if (written == bytesPerRow) {
|
||||
rv = NS_OK;
|
||||
} else {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
rv = stream->Write(((const char*)map.mData) + i, bytesPerRow,
|
||||
&written);
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
}
|
||||
} while (i != 0);
|
||||
}
|
||||
}
|
||||
|
||||
stream->Close();
|
||||
dataSurface->Unmap();
|
||||
}
|
||||
|
||||
dataSurface->Unmap();
|
||||
stream->Close();
|
||||
|
||||
// Obtaining the file output stream results in a newly created file or
|
||||
// truncates the file if it already exists. As such, it is necessary to
|
||||
// remove the file if the write fails for some reason.
|
||||
if (NS_FAILED(rv)) {
|
||||
if (NS_WARN_IF(NS_FAILED(aFile->Remove(PR_FALSE)))) {
|
||||
MOZ_LOG(sLog, LogLevel::Warning,
|
||||
("Failed to remove empty bitmap file : %s",
|
||||
aFile->HumanReadablePath().get()));
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user