diff --git a/src/add-ons/translators/gif/GIFLoad.cpp b/src/add-ons/translators/gif/GIFLoad.cpp index d7f0c7d223..0b074b8347 100644 --- a/src/add-ons/translators/gif/GIFLoad.cpp +++ b/src/add-ons/translators/gif/GIFLoad.cpp @@ -22,6 +22,8 @@ #include #include +#include + #include #include #include @@ -139,7 +141,10 @@ GIFLoad::ReadGIFHeader() fWidth = header[6] + (header[7] << 8); fHeight = header[8] + (header[9] << 8); - fPalette = new LoadPalette(); + fPalette = new(std::nothrow) LoadPalette(); + if (fPalette == NULL) + return false; + // Global palette if (header[10] & GIF_LOCALCOLORMAP) { fPalette->size_in_bits = (header[10] & 0x07) + 1; diff --git a/src/add-ons/translators/gif/GIFSave.cpp b/src/add-ons/translators/gif/GIFSave.cpp index 7d14502590..cb189c69c1 100644 --- a/src/add-ons/translators/gif/GIFSave.cpp +++ b/src/add-ons/translators/gif/GIFSave.cpp @@ -24,6 +24,8 @@ #include #include +#include + #include "GIFPrivate.h" @@ -58,13 +60,21 @@ GIFSave::GIFSave(BBitmap* bitmap, BPositionIO* output, } fatalerror = false; - if (fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE) == OPTIMAL_PALETTE) - palette = new SavePalette(bitmap, + if (fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE) == OPTIMAL_PALETTE) { + palette = new(std::nothrow) SavePalette(bitmap, fSettings->SetGetInt32(GIF_SETTING_PALETTE_SIZE)); - else - palette = new SavePalette( + } else { + palette = new(std::nothrow) SavePalette( fSettings->SetGetInt32(GIF_SETTING_PALETTE_MODE)); + } + + if (palette == NULL) { + fatalerror = true; + return; + } + if (!palette->IsValid()) { + delete palette; fatalerror = true; return; } @@ -80,13 +90,33 @@ GIFSave::GIFSave(BBitmap* bitmap, BPositionIO* output, if (debug) syslog(LOG_INFO, "GIFSave::GIFSave() - Using dithering\n"); - red_error = new int32[width + 2]; + red_error = new(std::nothrow) int32[width + 2]; + if (red_error == NULL) { + delete palette; + fatalerror = true; + return; + } red_error = &red_error[1]; // Allow index of -1 too - green_error = new int32[width + 2]; + + green_error = new(std::nothrow) int32[width + 2]; + if (green_error == NULL) { + delete palette; + delete[] red_error; + fatalerror = true; + return; + } green_error = &green_error[1]; // Allow index of -1 too - blue_error = new int32[width + 2]; + + blue_error = new(std::nothrow) int32[width + 2]; + if (blue_error == NULL) { + delete palette; + delete[] red_error; + delete[] green_error; + fatalerror = true; + return; + } blue_error = &blue_error[1]; // Allow index of -1 too @@ -151,11 +181,29 @@ GIFSave::GIFSave(BBitmap* bitmap, BPositionIO* output, this->output = output; this->bitmap = bitmap; - WriteGIFHeader(); + + if (WriteGIFHeader() != B_OK) { + delete palette; + delete[] red_error; + delete[] green_error; + delete[] blue_error; + fatalerror = true; + return; + } + if (debug) syslog(LOG_INFO, "GIFSave::GIFSave() - Wrote gif header\n"); - hash = new SFHash(1 << 16); + hash = new(std::nothrow) SFHash(1 << 16); + if (hash == NULL) { + delete palette; + delete[] red_error; + delete[] green_error; + delete[] blue_error; + fatalerror = true; + return; + } + WriteGIFControlBlock(); if (debug) syslog(LOG_INFO, "GIFSave::GIFSave() - Wrote gif control block\n"); @@ -188,7 +236,7 @@ GIFSave::~GIFSave() } -void +status_t GIFSave::WriteGIFHeader() { // Standard header @@ -200,19 +248,28 @@ GIFSave::WriteGIFHeader() header[9] = (height & 0xff00) >> 8; header[10] = 0xf0 | (palette->SizeInBits() - 1); header[11] = palette->BackgroundIndex(); - output->Write(header, 13); + if (output->Write(header, 13) < 0) + return B_IO_ERROR; // global palette int size = (1 << palette->SizeInBits()) * 3; - uint8* buffer = new uint8[size]; // can't be bigger than this + uint8* buffer = new(std::nothrow) uint8[size]; + if (buffer == NULL) + return B_NO_MEMORY; + palette->GetColors(buffer, size); - output->Write(buffer, size); + if (output->Write(buffer, size) < 0) { + delete[] buffer; + return B_IO_ERROR; + } delete[] buffer; + + return B_OK; } -void +status_t GIFSave::WriteGIFControlBlock() { unsigned char b[8] = { @@ -223,11 +280,11 @@ GIFSave::WriteGIFControlBlock() b[3] = b[3] | 1; b[6] = palette->TransparentIndex(); } - output->Write(b, 8); + return output->Write(b, 8) < 0 ? B_IO_ERROR : B_OK; } -void +status_t GIFSave::WriteGIFImageHeader() { unsigned char header[10]; @@ -245,21 +302,55 @@ GIFSave::WriteGIFImageHeader() else header[9] = BLOCK_TERMINATOR; - output->Write(header, 10); + return output->Write(header, 10) < 0 ? B_IO_ERROR : B_OK; } -void +status_t GIFSave::WriteGIFImageData() { InitFrame(); + + status_t result = B_OK; + code_value = (short*)malloc(HASHSIZE * 2); + if (code_value == NULL) + return B_NO_MEMORY; + prefix_code = (short*)malloc(HASHSIZE * 2); + if (prefix_code == NULL) { + free(code_value); + + return B_NO_MEMORY; + } + append_char = (unsigned char*)malloc(HASHSIZE); + if (append_char == NULL) { + free(code_value); + free(prefix_code); + + return B_NO_MEMORY; + } + ResetHashtable(); - output->Write(&code_size, 1); - OutputCode(clear_code, BITS); + if (output->Write(&code_size, 1) < 0) { + free(code_value); + free(prefix_code); + free(append_char); + + return B_IO_ERROR; + } + + result = OutputCode(clear_code, BITS); + if (result != B_OK) { + free(code_value); + free(prefix_code); + free(append_char); + + return B_IO_ERROR; + } + string_code = NextPixel(0); int area = height * width; @@ -270,12 +361,27 @@ GIFSave::WriteGIFImageData() string_code = y; else { AddToHashtable(string_code, character); - OutputCode(string_code, BITS); + result = OutputCode(string_code, BITS); + if (result != B_OK) { + free(code_value); + free(prefix_code); + free(append_char); + + return B_IO_ERROR; + } if (next_code > max_code) { BITS++; if (BITS > LZ_MAX_BITS) { - OutputCode(clear_code, LZ_MAX_BITS); + result = OutputCode(clear_code, LZ_MAX_BITS); + if (result != B_OK) { + free(code_value); + free(prefix_code); + free(append_char); + + return B_IO_ERROR; + } + BITS = code_size + 1; ResetHashtable(); next_code = clear_code + 1; @@ -288,22 +394,55 @@ GIFSave::WriteGIFImageData() } } - OutputCode(string_code, BITS); - OutputCode(end_code, BITS); - OutputCode(0, BITS, true); + result = OutputCode(string_code, BITS); + if (result != B_OK) { + free(code_value); + free(prefix_code); + free(append_char); + + return B_IO_ERROR; + } + + result = OutputCode(end_code, BITS); + if (result != B_OK) { + free(code_value); + free(prefix_code); + free(append_char); + + return B_IO_ERROR; + } + + result = OutputCode(0, BITS, true); + if (result != B_OK) { + free(code_value); + free(prefix_code); + free(append_char); + + return B_IO_ERROR; + } + char t = BLOCK_TERMINATOR; - output->Write(&t, 1); + if (output->Write(&t, 1) < 0) { + free(code_value); + free(prefix_code); + free(append_char); + + return B_IO_ERROR; + } + free(code_value); free(prefix_code); free(append_char); + + return result; } -void +status_t GIFSave::OutputCode(short code, int BITS, bool flush) { if (!flush) { - bit_buffer |= (unsigned int) code << bit_count; + bit_buffer |= (unsigned int)code << bit_count; bit_count += BITS; while (bit_count >= 8) { byte_buffer[byte_count + 1] = (unsigned char)(bit_buffer & 0xff); @@ -313,7 +452,9 @@ GIFSave::OutputCode(short code, int BITS, bool flush) } if (byte_count >= 255) { byte_buffer[0] = 255; - output->Write(byte_buffer, 256); + if (output->Write(byte_buffer, 256) < 0) + return B_IO_ERROR; + if (byte_count == 256) { byte_buffer[1] = byte_buffer[256]; byte_count = 1; @@ -331,9 +472,12 @@ GIFSave::OutputCode(short code, int BITS, bool flush) } if (byte_count > 0) { byte_buffer[0] = (unsigned char)byte_count; - output->Write(byte_buffer, byte_count + 1); + if (output->Write(byte_buffer, byte_count + 1) < 0) + return B_IO_ERROR; } } + + return B_OK; } diff --git a/src/add-ons/translators/gif/GIFSave.h b/src/add-ons/translators/gif/GIFSave.h index f4e4bed724..73ba0ce462 100644 --- a/src/add-ons/translators/gif/GIFSave.h +++ b/src/add-ons/translators/gif/GIFSave.h @@ -44,11 +44,11 @@ public: bool fatalerror; private: - void WriteGIFHeader(); - void WriteGIFControlBlock(); - void WriteGIFImageHeader(); - void WriteGIFImageData(); - void OutputCode(short code, int BITS, + status_t WriteGIFHeader(); + status_t WriteGIFControlBlock(); + status_t WriteGIFImageHeader(); + status_t WriteGIFImageData(); + status_t OutputCode(short code, int BITS, bool flush = false); unsigned char NextPixel(int pixel); diff --git a/src/add-ons/translators/gif/GIFTranslator.cpp b/src/add-ons/translators/gif/GIFTranslator.cpp index 9eb639ef1f..363d15f723 100644 --- a/src/add-ons/translators/gif/GIFTranslator.cpp +++ b/src/add-ons/translators/gif/GIFTranslator.cpp @@ -265,7 +265,13 @@ GIFTranslator::DerivedTranslate(BPositionIO* inSource, if (result != B_OK) return result; - GIFSave* gifSave = new GIFSave(bitmap, outDestination, fSettings); + GIFSave* gifSave = new(std::nothrow) GIFSave(bitmap, outDestination, + fSettings); + if (gifSave == NULL) { + delete bitmap; + return B_NO_MEMORY; + } + if (gifSave->fatalerror) { delete gifSave; delete bitmap; @@ -275,7 +281,10 @@ GIFTranslator::DerivedTranslate(BPositionIO* inSource, delete bitmap; } else { // GIF to BBitmap - GIFLoad* gifLoad = new GIFLoad(inSource, outDestination); + GIFLoad* gifLoad = new(std::nothrow) GIFLoad(inSource, outDestination); + if (gifLoad == NULL) + return B_NO_MEMORY; + if (gifLoad->fatalerror) { delete gifLoad; return B_NO_MEMORY; @@ -296,7 +305,7 @@ BTranslator* make_nth_translator(int32 n, image_id you, uint32 flags, ...) { if (n == 0) - return new GIFTranslator(); + return new(std::nothrow) GIFTranslator(); return NULL; } @@ -324,7 +333,7 @@ GIFTranslator::~GIFTranslator() BView* GIFTranslator::NewConfigView(TranslatorSettings* settings) { - return new GIFView(settings); + return new(std::nothrow) GIFView(settings); } @@ -332,7 +341,7 @@ int main() { BApplication app("application/x-vnd.Haiku-GIFTranslator"); - status_t result = LaunchTranslatorWindow(new GIFTranslator, + status_t result = LaunchTranslatorWindow(new(std::nothrow) GIFTranslator, B_TRANSLATE("GIF Settings"), kRectView); if (result == B_OK) { app.Run();