diff --git a/frameworks/innerkitsimpl/utils/src/image_utils.cpp b/frameworks/innerkitsimpl/utils/src/image_utils.cpp index c5f89405a848273f0c64d62837a2f0d78acc4deb..8e6e0fa6e09ef7fb60d6b932ff18bc0c9c34f728 100644 --- a/frameworks/innerkitsimpl/utils/src/image_utils.cpp +++ b/frameworks/innerkitsimpl/utils/src/image_utils.cpp @@ -858,7 +858,7 @@ std::string ImageUtils::GetPixelMapName(PixelMap* pixelMap) uint16_t ImageUtils::BytesToUint16(uint8_t* bytes, uint32_t& offset, uint32_t size, bool isBigEndian) { uint16_t data = 0; - if (bytes == nullptr || offset + NUM_2 >= size) { + if (bytes == nullptr || offset + NUM_2 > size) { return data; } if (isBigEndian) { @@ -874,7 +874,7 @@ uint16_t ImageUtils::BytesToUint16(uint8_t* bytes, uint32_t& offset, uint32_t si uint32_t ImageUtils::BytesToUint32(uint8_t* bytes, uint32_t& offset, uint32_t size, bool isBigEndian) { uint32_t data = 0; - if (bytes == nullptr || offset + NUM_4 >= size) { + if (bytes == nullptr || offset + NUM_4 > size) { return data; } if (isBigEndian) { @@ -892,7 +892,7 @@ uint32_t ImageUtils::BytesToUint32(uint8_t* bytes, uint32_t& offset, uint32_t si int32_t ImageUtils::BytesToInt32(uint8_t* bytes, uint32_t& offset, uint32_t size, bool isBigEndian) { int32_t data = 0; - if (bytes == nullptr || offset + NUM_4 >= size) { + if (bytes == nullptr || offset + NUM_4 > size) { return data; } if (isBigEndian) { diff --git a/plugins/common/libs/image/libextplugin/include/hdr/hdr_helper.h b/plugins/common/libs/image/libextplugin/include/hdr/hdr_helper.h index c8c4c602b278ce04bb9f24a534bfe5fd18eb12d4..bdad0fa6c4f96f9d878a1e2fa59bf0383acf1bb9 100644 --- a/plugins/common/libs/image/libextplugin/include/hdr/hdr_helper.h +++ b/plugins/common/libs/image/libextplugin/include/hdr/hdr_helper.h @@ -18,6 +18,7 @@ #include "box/item_property_display_box.h" #include "include/codec/SkCodec.h" +#include "ext_stream.h" #ifdef USE_M133_SKIA #include "include/core/SkStream.h" #endif @@ -29,6 +30,7 @@ class HdrHelper { public: static Media::ImageHdrType CheckHdrType(SkCodec* codec, uint32_t& offset); static bool GetMetadata(SkCodec* codec, Media::ImageHdrType type, Media::HdrMetadata& metadata); + static bool CheckGainmapOffset(Media::ImageHdrType type, InputDataStream *stream, uint32_t& offset); }; class HdrJpegPackerHelper { diff --git a/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp b/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp index 07e9b4615b97f255ed628760a462eba668c650ff..7b89c7dc5819d5d3b9af5870c6eb19736bdaf881 100644 --- a/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp +++ b/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp @@ -2562,19 +2562,12 @@ ImageHdrType ExtDecoder::CheckHdrType() return hdrType_; } hdrType_ = HdrHelper::CheckHdrType(codec_.get(), gainMapOffset_); - if (hdrType_ > Media::ImageHdrType::SDR && format == SkEncodedImageFormat::kJPEG) { - if (hdrType_ == Media::ImageHdrType::HDR_LOG_DUAL) { - return Media::ImageHdrType::HDR_LOG_DUAL; - } - if (stream_ == nullptr || (gainMapOffset_ + JPEG_MARKER_LENGTH) > stream_->GetStreamSize()) { - IMAGE_LOGE("HDR-IMAGE CheckHdrType gainmap header offset failed : %{public}d", gainMapOffset_); - return Media::ImageHdrType::SDR; - } - uint8_t *outBuffer = stream_->GetDataPtr() + gainMapOffset_; - if (std::memcmp(JPEG_SOI_HEADER, outBuffer, JPEG_MARKER_LENGTH) != 0) { - IMAGE_LOGE("HDR-IMAGE CheckHdrType get gainmap header failed"); - return Media::ImageHdrType::SDR; - } + if (hdrType_ <= Media::ImageHdrType::SDR || format != SkEncodedImageFormat::kJPEG) { + return hdrType_; + } + // Verify the legitimacy of the offset. + if (!HdrHelper::CheckGainmapOffset(hdrType_, stream_, gainMapOffset_)) { + return Media::ImageHdrType::SDR; } return hdrType_; #endif diff --git a/plugins/common/libs/image/libextplugin/src/hdr/hdr_helper.cpp b/plugins/common/libs/image/libextplugin/src/hdr/hdr_helper.cpp index 2ab1a7626fb44a4d182d612ee0dc3118f3451537..780ff478220f43ad771560688f6881b99ea19cda 100644 --- a/plugins/common/libs/image/libextplugin/src/hdr/hdr_helper.cpp +++ b/plugins/common/libs/image/libextplugin/src/hdr/hdr_helper.cpp @@ -87,6 +87,9 @@ constexpr uint16_t EMPTY_META_SIZE = 0; const float SM_COLOR_SCALE = 0.00002f; const float SM_LUM_SCALE = 0.0001f; +constexpr static int JPEG_MARKER_LENGTH = 2; +static constexpr uint8_t JPEG_SOI_HEADER[] = { 0xFF, 0xD8 }; + static constexpr uint8_t ITUT35_TAG[ITUT35_TAG_SIZE] = { 'I', 'T', 'U', 'T', '3', '5', }; @@ -397,6 +400,34 @@ ImageHdrType HdrHelper::CheckHdrType(SkCodec* codec, uint32_t& offset) __attribu return type; } +bool HdrHelper::CheckGainmapOffset(ImageHdrType type, InputDataStream* stream, uint32_t& offset) +{ + if (type == Media::ImageHdrType::HDR_LOG_DUAL) { + return true; + } + if (stream == nullptr) { + return false; + } + + uint32_t streamSize = stream->GetStreamSize(); + if (offset >= streamSize || JPEG_MARKER_LENGTH > (streamSize - offset)) { + IMAGE_LOGE("HDR-IMAGE CheckHdrType invalid offset %{public}d for stream size %{public}d", offset, streamSize); + return false; + } + + uint8_t *outBuffer = stream->GetDataPtr(); + if (outBuffer == nullptr) { + IMAGE_LOGE("HDR-IMAGE CheckHdrTYpe null data pointer"); + return false; + } + + if (std::memcmp(JPEG_SOI_HEADER, outBuffer + offset, JPEG_MARKER_LENGTH) != 0) { + IMAGE_LOGE("HDR-IMAGE CheckHdrType gainmap memcpy SOI error"); + return false; + } + return true; +} + static bool ParseVividJpegStaticMetadata(uint8_t* data, uint32_t& offset, uint32_t size, vector& staticMetaVec) { #if defined(_WIN32) || defined(_APPLE) || defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM) @@ -1058,8 +1089,14 @@ static void PackTransformInfo(vector& bytes, uint32_t& offset, uint8_t } uint16_t transformSize = flag + UINT8_BYTE_COUNT; ImageUtils::Uint16ToBytes(transformSize, bytes, offset); + if (offset + flag > bytes.size()) { + return; + } bytes[offset++] = flag; - if (offset < 0 || offset + flag > bytes.size()) { + size_t remainSpace = bytes.size() - offset; + if (remainSpace < flag) { + offset -= (UINT8_BYTE_COUNT + UINT16_BYTE_COUNT); + ImageUtils::Uint16ToBytes((uint16_t)EMPTY_SIZE, bytes, offset); return; } if (memcpy_s(bytes.data() + offset, flag, mapping.data(), flag) != 0) { diff --git a/test/resource/image/ohos_test.xml b/test/resource/image/ohos_test.xml index 32c0f86d74d597d301676160de7be05ff99e1fc6..890fba923d40a43bdd7511cfe57cd6d89e6cc6dc 100644 --- a/test/resource/image/ohos_test.xml +++ b/test/resource/image/ohos_test.xml @@ -115,6 +115,8 @@ +