diff options
author | Ram Mohan <ram.mohan@ittiam.com> | 2023-06-02 17:44:45 +0530 |
---|---|---|
committer | Dichen Zhang <dichenzhang@google.com> | 2023-06-06 01:09:23 +0000 |
commit | e69d9d2e7fde9dff70ba36dbc46b60bdd000cebb (patch) | |
tree | 394882c9c9d8c666e68a68c576cd809124a3086b | |
parent | 05ff67be11fb137d986299ce8f8ed3abc5655e4d (diff) | |
download | native-e69d9d2e7fde9dff70ba36dbc46b60bdd000cebb.tar.gz |
ultrahdr: release memory if encode/decode fails
If calls to encode/decode failed, release the allocated memory
before returning the control to caller
Bug: 285546217
Test: ./ultrahdr_dec_fuzzer
Test: ./ultrahdr_enc_fuzzer
Change-Id: I276c31cc56656aa41845a16f5d28783bc3adc772
-rw-r--r-- | libs/ultrahdr/icc.cpp | 18 | ||||
-rw-r--r-- | libs/ultrahdr/jpegdecoderhelper.cpp | 20 | ||||
-rw-r--r-- | libs/ultrahdr/jpegencoderhelper.cpp | 11 | ||||
-rw-r--r-- | libs/ultrahdr/multipictureformat.cpp | 2 |
4 files changed, 28 insertions, 23 deletions
diff --git a/libs/ultrahdr/icc.cpp b/libs/ultrahdr/icc.cpp index c807705528..32d08aa525 100644 --- a/libs/ultrahdr/icc.cpp +++ b/libs/ultrahdr/icc.cpp @@ -180,7 +180,7 @@ sp<DataStruct> IccHelper::write_text_tag(const char* text) { uint32_t total_length = text_length * 2 + sizeof(header); total_length = (((total_length + 2) >> 2) << 2); // 4 aligned - sp<DataStruct> dataStruct = new DataStruct(total_length); + sp<DataStruct> dataStruct = sp<DataStruct>::make(total_length); if (!dataStruct->write(header, sizeof(header))) { ALOGE("write_text_tag(): error in writing data"); @@ -204,7 +204,7 @@ sp<DataStruct> IccHelper::write_xyz_tag(float x, float y, float z) { static_cast<uint32_t>(Endian_SwapBE32(float_round_to_fixed(y))), static_cast<uint32_t>(Endian_SwapBE32(float_round_to_fixed(z))), }; - sp<DataStruct> dataStruct = new DataStruct(sizeof(data)); + sp<DataStruct> dataStruct = sp<DataStruct>::make(sizeof(data)); dataStruct->write(&data, sizeof(data)); return dataStruct; } @@ -212,7 +212,7 @@ sp<DataStruct> IccHelper::write_xyz_tag(float x, float y, float z) { sp<DataStruct> IccHelper::write_trc_tag(const int table_entries, const void* table_16) { int total_length = 4 + 4 + 4 + table_entries * 2; total_length = (((total_length + 2) >> 2) << 2); // 4 aligned - sp<DataStruct> dataStruct = new DataStruct(total_length); + sp<DataStruct> dataStruct = sp<DataStruct>::make(total_length); dataStruct->write32(Endian_SwapBE32(kTAG_CurveType)); // Type dataStruct->write32(0); // Reserved dataStruct->write32(Endian_SwapBE32(table_entries)); // Value count @@ -225,7 +225,7 @@ sp<DataStruct> IccHelper::write_trc_tag(const int table_entries, const void* tab sp<DataStruct> IccHelper::write_trc_tag_for_linear() { int total_length = 16; - sp<DataStruct> dataStruct = new DataStruct(total_length); + sp<DataStruct> dataStruct = sp<DataStruct>::make(total_length); dataStruct->write32(Endian_SwapBE32(kTAG_ParaCurveType)); // Type dataStruct->write32(0); // Reserved dataStruct->write32(Endian_SwapBE16(kExponential_ParaCurveType)); @@ -263,7 +263,7 @@ float IccHelper::compute_tone_map_gain(const ultrahdr_transfer_function tf, floa sp<DataStruct> IccHelper::write_cicp_tag(uint32_t color_primaries, uint32_t transfer_characteristics) { int total_length = 12; // 4 + 4 + 1 + 1 + 1 + 1 - sp<DataStruct> dataStruct = new DataStruct(total_length); + sp<DataStruct> dataStruct = sp<DataStruct>::make(total_length); dataStruct->write32(Endian_SwapBE32(kTAG_cicp)); // Type signature dataStruct->write32(0); // Reserved dataStruct->write8(color_primaries); // Color primaries @@ -314,7 +314,7 @@ sp<DataStruct> IccHelper::write_clut(const uint8_t* grid_points, const uint8_t* int total_length = 20 + 2 * value_count; total_length = (((total_length + 2) >> 2) << 2); // 4 aligned - sp<DataStruct> dataStruct = new DataStruct(total_length); + sp<DataStruct> dataStruct = sp<DataStruct>::make(total_length); for (size_t i = 0; i < 16; ++i) { dataStruct->write8(i < kNumChannels ? grid_points[i] : 0); // Grid size @@ -372,7 +372,7 @@ sp<DataStruct> IccHelper::write_mAB_or_mBA_tag(uint32_t type, total_length += a_curves_data[i]->getLength(); } } - sp<DataStruct> dataStruct = new DataStruct(total_length); + sp<DataStruct> dataStruct = sp<DataStruct>::make(total_length); dataStruct->write32(Endian_SwapBE32(type)); // Type signature dataStruct->write32(0); // Reserved dataStruct->write8(kNumChannels); // Input channels @@ -421,7 +421,7 @@ sp<DataStruct> IccHelper::writeIccProfile(ultrahdr_transfer_function tf, break; default: // Should not fall here. - return new DataStruct(0); + return nullptr; } // Compute primaries. @@ -546,7 +546,7 @@ sp<DataStruct> IccHelper::writeIccProfile(ultrahdr_transfer_function tf, header.size = Endian_SwapBE32(profile_size); header.tag_count = Endian_SwapBE32(tags.size()); - sp<DataStruct> dataStruct = new DataStruct(profile_size); + sp<DataStruct> dataStruct = sp<DataStruct>::make(profile_size); if (!dataStruct->write(&header, sizeof(header))) { ALOGE("writeIccProfile(): error in header"); return dataStruct; diff --git a/libs/ultrahdr/jpegdecoderhelper.cpp b/libs/ultrahdr/jpegdecoderhelper.cpp index 2a9bc9ac1e..0bad4a4de0 100644 --- a/libs/ultrahdr/jpegdecoderhelper.cpp +++ b/libs/ultrahdr/jpegdecoderhelper.cpp @@ -150,6 +150,7 @@ bool JpegDecoderHelper::decode(const void* image, int length, bool decodeToRGBA) jpeg_decompress_struct cinfo; jpegr_source_mgr mgr(static_cast<const uint8_t*>(image), length); jpegrerror_mgr myerr; + bool status = true; cinfo.err = jpeg_std_error(&myerr.pub); myerr.pub.error_exit = jpegrerror_exit; @@ -216,7 +217,8 @@ bool JpegDecoderHelper::decode(const void* image, int length, bool decodeToRGBA) if (cinfo.image_width > kMaxWidth || cinfo.image_height > kMaxHeight) { // constraint on max width and max height is only due to alloc constraints // tune these values basing on the target device - return false; + status = false; + goto CleanUp; } mWidth = cinfo.image_width; @@ -225,7 +227,8 @@ bool JpegDecoderHelper::decode(const void* image, int length, bool decodeToRGBA) if (decodeToRGBA) { if (cinfo.jpeg_color_space == JCS_GRAYSCALE) { // We don't intend to support decoding grayscale to RGBA - return false; + status = false; + goto CleanUp; } // 4 bytes per pixel mResultBuffer.resize(cinfo.image_width * cinfo.image_height * 4); @@ -238,7 +241,8 @@ bool JpegDecoderHelper::decode(const void* image, int length, bool decodeToRGBA) cinfo.comp_info[0].v_samp_factor != 2 || cinfo.comp_info[1].v_samp_factor != 1 || cinfo.comp_info[2].v_samp_factor != 1) { - return false; + status = false; + goto CleanUp; } mResultBuffer.resize(cinfo.image_width * cinfo.image_height * 3 / 2, 0); } else if (cinfo.jpeg_color_space == JCS_GRAYSCALE) { @@ -254,13 +258,15 @@ bool JpegDecoderHelper::decode(const void* image, int length, bool decodeToRGBA) if (!decompress(&cinfo, static_cast<const uint8_t*>(mResultBuffer.data()), cinfo.jpeg_color_space == JCS_GRAYSCALE)) { - return false; + status = false; + goto CleanUp; } +CleanUp: jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); - return true; + return status; } bool JpegDecoderHelper::decompress(jpeg_decompress_struct* cinfo, const uint8_t* dest, @@ -367,7 +373,7 @@ bool JpegDecoderHelper::decompressYUV(jpeg_decompress_struct* cinfo, const uint8 uint8_t* y_plane = const_cast<uint8_t*>(dest); uint8_t* u_plane = const_cast<uint8_t*>(dest + y_plane_size); uint8_t* v_plane = const_cast<uint8_t*>(dest + y_plane_size + uv_plane_size); - std::unique_ptr<uint8_t[]> empty(new uint8_t[cinfo->image_width]); + std::unique_ptr<uint8_t[]> empty = std::make_unique<uint8_t[]>(cinfo->image_width); memset(empty.get(), 0, cinfo->image_width); const int aligned_width = ALIGNM(cinfo->image_width, kCompressBatchSize); @@ -441,7 +447,7 @@ bool JpegDecoderHelper::decompressSingleChannel(jpeg_decompress_struct* cinfo, c JSAMPARRAY planes[1] {y}; uint8_t* y_plane = const_cast<uint8_t*>(dest); - std::unique_ptr<uint8_t[]> empty(new uint8_t[cinfo->image_width]); + std::unique_ptr<uint8_t[]> empty = std::make_unique<uint8_t[]>(cinfo->image_width); memset(empty.get(), 0, cinfo->image_width); int aligned_width = ALIGNM(cinfo->image_width, kCompressBatchSize); diff --git a/libs/ultrahdr/jpegencoderhelper.cpp b/libs/ultrahdr/jpegencoderhelper.cpp index ab2f8c7b5a..a03547b538 100644 --- a/libs/ultrahdr/jpegencoderhelper.cpp +++ b/libs/ultrahdr/jpegencoderhelper.cpp @@ -107,12 +107,11 @@ bool JpegEncoderHelper::encode(const void* image, int width, int height, int jpe jpeg_write_marker(&cinfo, JPEG_APP0 + 2, static_cast<const JOCTET*>(iccBuffer), iccSize); } - if (!compress(&cinfo, static_cast<const uint8_t*>(image), isSingleChannel)) { - return false; - } + bool status = compress(&cinfo, static_cast<const uint8_t*>(image), isSingleChannel); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); - return true; + + return status; } void JpegEncoderHelper::setJpegDestination(jpeg_compress_struct* cinfo) { @@ -174,7 +173,7 @@ bool JpegEncoderHelper::compressYuv(jpeg_compress_struct* cinfo, const uint8_t* uint8_t* y_plane = const_cast<uint8_t*>(yuv); uint8_t* u_plane = const_cast<uint8_t*>(yuv + y_plane_size); uint8_t* v_plane = const_cast<uint8_t*>(yuv + y_plane_size + uv_plane_size); - std::unique_ptr<uint8_t[]> empty(new uint8_t[cinfo->image_width]); + std::unique_ptr<uint8_t[]> empty = std::make_unique<uint8_t[]>(cinfo->image_width); memset(empty.get(), 0, cinfo->image_width); const int aligned_width = ALIGNM(cinfo->image_width, kCompressBatchSize); @@ -250,7 +249,7 @@ bool JpegEncoderHelper::compressSingleChannel(jpeg_compress_struct* cinfo, const JSAMPARRAY planes[1] {y}; uint8_t* y_plane = const_cast<uint8_t*>(image); - std::unique_ptr<uint8_t[]> empty(new uint8_t[cinfo->image_width]); + std::unique_ptr<uint8_t[]> empty = std::make_unique<uint8_t[]>(cinfo->image_width); memset(empty.get(), 0, cinfo->image_width); const int aligned_width = ALIGNM(cinfo->image_width, kCompressBatchSize); diff --git a/libs/ultrahdr/multipictureformat.cpp b/libs/ultrahdr/multipictureformat.cpp index 7a265c61b7..f1679ef1b3 100644 --- a/libs/ultrahdr/multipictureformat.cpp +++ b/libs/ultrahdr/multipictureformat.cpp @@ -30,7 +30,7 @@ size_t calculateMpfSize() { sp<DataStruct> generateMpf(int primary_image_size, int primary_image_offset, int secondary_image_size, int secondary_image_offset) { size_t mpf_size = calculateMpfSize(); - sp<DataStruct> dataStruct = new DataStruct(mpf_size); + sp<DataStruct> dataStruct = sp<DataStruct>::make(mpf_size); dataStruct->write(static_cast<const void*>(kMpfSig), sizeof(kMpfSig)); #if USE_BIG_ENDIAN |