diff --git a/common/include/dscreen_constants.h b/common/include/dscreen_constants.h index 086cf4f8b61773e22b55f3bd6fd3e9f8f5ec9ce3..5afa2ae6d678b158426d9c5e4a2efab4c25f96ff 100644 --- a/common/include/dscreen_constants.h +++ b/common/include/dscreen_constants.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2022-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -210,6 +210,8 @@ constexpr float DEFAULT_DENSITY = 2.0; constexpr int32_t DEFAULT_SCREEN_FLAGS = 0; constexpr double DEFAULT_FPS = 60.0; constexpr int32_t DIRTY_MAX_SIZE = 10; +constexpr uint32_t DIRTY_MAX_BUF_SIZE = 4096; +constexpr uint32_t DIRTY_MAX_IMAGE_DATA_SIZE = 780000; constexpr uint8_t DEFAULT_CODECTYPE = VIDEO_CODEC_TYPE_VIDEO_H264; constexpr uint8_t DEFAULT_VIDEO_FORMAT = VIDEO_DATA_FORMAT_NV12; constexpr int32_t DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID = 4807; diff --git a/services/common/databuffer/include/data_buffer.h b/services/common/databuffer/include/data_buffer.h index 6ce71242d14f17069c10f47ec8b3c64cbcecb236..baad098be8616cf7abfcf94e9d6044d761f0a50f 100644 --- a/services/common/databuffer/include/data_buffer.h +++ b/services/common/databuffer/include/data_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2022-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -25,11 +25,11 @@ namespace OHOS { namespace DistributedHardware { struct DirtyRect { - int32_t xPos; - int32_t yPos; - int32_t width; - int32_t height; - int32_t dirtySize; + uint32_t xPos; + uint32_t yPos; + uint32_t width; + uint32_t height; + uint32_t dirtySize; }; class DataBuffer { public: diff --git a/services/common/imageJpeg/include/jpeg_image_processor.h b/services/common/imageJpeg/include/jpeg_image_processor.h index aa6c3badf3e6b6a54d8a03c2d979cf58e47d6042..6027a64adbfead63d05783c4ee8dcfb785204480 100644 --- a/services/common/imageJpeg/include/jpeg_image_processor.h +++ b/services/common/imageJpeg/include/jpeg_image_processor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -43,7 +43,7 @@ public: private: uint32_t CompressRgbaToJpeg(const OHOS::Rect &damage, uint8_t *inputData, uint32_t inputDataSize, std::shared_ptr &data); - void DecompressJpegToNV12(size_t jpegSize, uint8_t *inputData, uint8_t *outputData); + void DecompressJpegToNV12(size_t jpegSize, uint8_t *inputData, uint8_t *outputData, const uint32_t &outputDataSize); static const constexpr char *DSCREEN_LOG_TAG = "JpegImageProcessor"; sptr imageSurface_; diff --git a/services/common/imageJpeg/src/jpeg_image_processor.cpp b/services/common/imageJpeg/src/jpeg_image_processor.cpp index bf3080365c62dc9046a9a54880ecaef682361cb9..17de81145cffe7c3c1720507466377fdc9cc9a42 100644 --- a/services/common/imageJpeg/src/jpeg_image_processor.cpp +++ b/services/common/imageJpeg/src/jpeg_image_processor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -145,14 +145,18 @@ int32_t JpegImageProcessor::DecodeDamageData(const std::shared_ptr & DHLOGI("%{public}s: DecodeDamageData.", DSCREEN_LOG_TAG); std::vector dirtyRectVec = data->GetDirtyRectVec(); int32_t offset = 0; - int32_t screenWidth = static_cast(configParam_.GetScreenWidth()); - int32_t screenHeight = static_cast(configParam_.GetScreenHeight()); + uint32_t screenWidth = configParam_.GetScreenWidth(); + uint32_t screenHeight = configParam_.GetScreenHeight(); for (auto item : dirtyRectVec) { if (item.xPos > screenWidth || item.yPos > screenHeight || item.width > screenWidth - item.xPos || item.height > screenHeight - item.yPos) { DHLOGE("%{public}s: Dirty rect invalid.", DSCREEN_LOG_TAG); return ERR_DH_SCREEN_INPUT_PARAM_INVALID; } + if (item.dirtySize > DIRTY_MAX_BUF_SIZE) { + DHLOGE("%{public}s: Dirty rect invalid, dirtySize = %{public}" PRIu32, DSCREEN_LOG_TAG, item.dirtySize); + return ERR_DH_SCREEN_INPUT_PARAM_INVALID; + } uint8_t *jpegData = new uint8_t[item.dirtySize] {0}; int32_t ret = data->GetData(offset, item.dirtySize, jpegData); if (ret != DH_SUCCESS) { @@ -160,9 +164,16 @@ int32_t JpegImageProcessor::DecodeDamageData(const std::shared_ptr & return ret; } offset += item.dirtySize; - uint8_t *dirtyImageData = new uint8_t[item.width * item.height * RGB_CHROMA] {0}; + uint32_t dirtyImageDataSize = item.width * item.height * RGB_CHROMA; + if (dirtyImageDataSize > DIRTY_MAX_IMAGE_DATA_SIZE) { + DHLOGE("%{public}s: The dirtyImageDataSize is out of range. Expected max: %{public}" PRIu32 + ", actual: %{public}" PRIu32, DSCREEN_LOG_TAG, DIRTY_MAX_IMAGE_DATA_SIZE, dirtyImageDataSize); + delete[] jpegData; + return ERR_DH_SCREEN_INPUT_PARAM_INVALID; + } + uint8_t *dirtyImageData = new uint8_t[dirtyImageDataSize] {0}; DHLOGI("%{public}s: DecompressJpegToNV12.", DSCREEN_LOG_TAG); - DecompressJpegToNV12(item.dirtySize, jpegData, dirtyImageData); + DecompressJpegToNV12(item.dirtySize, jpegData, dirtyImageData, dirtyImageDataSize); DHLOGI("%{public}s: DecompressJpegToNV12 success.", DSCREEN_LOG_TAG); ret = ReplaceDamage2LastFrame(lastFrame, dirtyImageData, item); if (ret != DH_SUCCESS) { @@ -182,30 +193,30 @@ int32_t JpegImageProcessor::ReplaceDamage2LastFrame(uint8_t *lastFrame, uint8_t { DHLOGI("%{public}s: ReplaceDamage2LastFrame.", DSCREEN_LOG_TAG); uint8_t *lastFrameIdx = lastFrame; - uint8_t *yData = lastFrameIdx + static_cast(configParam_.GetScreenWidth() * rect.yPos + rect.xPos); + uint8_t *yData = lastFrameIdx + configParam_.GetScreenWidth() * rect.yPos + rect.xPos; uint8_t *uData = lastFrameIdx + configParam_.GetScreenWidth() * configParam_.GetScreenHeight() + - static_cast(configParam_.GetScreenWidth() * (rect.yPos / TWO) + rect.xPos); + configParam_.GetScreenWidth() * rect.yPos / TWO + rect.xPos; uint8_t *yDirtyData = dirtyImageData; uint8_t *uDirtyData = dirtyImageData + rect.width * rect.height; uint8_t *yTempData = nullptr; uint8_t *uTempData = nullptr; - for (int32_t i = 0 ; i < rect.height ; i++) { - yTempData = yData + static_cast(i) * configParam_.GetScreenWidth(); + for (uint32_t i = 0 ; i < rect.height ; i++) { + yTempData = yData + i * configParam_.GetScreenWidth(); int32_t ret = memcpy_s(yTempData, rect.width, yDirtyData, rect.width); if (ret != EOK) { DHLOGE("%{public}s: memcpy yData failed.", DSCREEN_LOG_TAG); return ret; } - yDirtyData += static_cast(rect.width); + yDirtyData += rect.width; if (i % TWO) { - uTempData = uData + configParam_.GetScreenWidth() * (static_cast(i) / TWO); + uTempData = uData + configParam_.GetScreenWidth() * i / TWO; ret = memcpy_s(uTempData, rect.width, uDirtyData, rect.width); if (ret != EOK) { DHLOGE("%{public}s: memcpy uData failed.", DSCREEN_LOG_TAG); return ret; } - uDirtyData += static_cast(rect.width); - } + uDirtyData += rect.width; + } } DHLOGI("%{public}s: ReplaceDamage2LastFrame success.", DSCREEN_LOG_TAG); return DH_SUCCESS; @@ -262,7 +273,8 @@ uint32_t JpegImageProcessor::CompressRgbaToJpeg(const OHOS::Rect &damage, return (uint32_t)outSize; } -void JpegImageProcessor::DecompressJpegToNV12(size_t jpegSize, uint8_t *inputData, uint8_t *outputData) +void JpegImageProcessor::DecompressJpegToNV12( + size_t jpegSize, uint8_t *inputData, uint8_t *outputData, const uint32_t &outputDataSize) { jpeg_decompress_struct cinfo; jpeg_error_mgr jerr; @@ -271,8 +283,25 @@ void JpegImageProcessor::DecompressJpegToNV12(size_t jpegSize, uint8_t *inputDat jpeg_mem_src(&cinfo, inputData, jpegSize); (void)jpeg_read_header(&cinfo, TRUE); (void)jpeg_start_decompress(&cinfo); - int32_t row_stride = static_cast(cinfo.output_width) * cinfo.output_components; + if ((cinfo.output_width > DSCREEN_MAX_LEN) || (cinfo.output_height > DSCREEN_MAX_LEN)) { + DHLOGE("%{public}s: JPEG image dimensions exceed DSCREEN_MAX_LEN: width = %{public}" PRIu32 + ", height = %{public}" PRIu32, DSCREEN_LOG_TAG, cinfo.output_width, cinfo.output_height); + jpeg_destroy_decompress(&cinfo); + return; + } + if (cinfo.output_components != RGB_CHROMA) { + DHLOGE("%{public}s: color components is not RGB, color components = %{public}" PRIu32, + DSCREEN_LOG_TAG, cinfo.output_components); + jpeg_destroy_decompress(&cinfo); + return; + } + uint32_t row_stride = static_cast(cinfo.output_width) * static_cast(cinfo.output_components); JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1); + if (buffer == nullptr) { + DHLOGE("%{public}s: buffer is nullptr.", DSCREEN_LOG_TAG); + jpeg_destroy_decompress(&cinfo); + return; + } uint32_t uvIndex = cinfo.output_width * cinfo.output_height; int32_t i = 0; int32_t yIndex = 0; @@ -286,7 +315,7 @@ void JpegImageProcessor::DecompressJpegToNV12(size_t jpegSize, uint8_t *inputDat int32_t v = ((UB_PARAM * buffer[0][j * RGB_CHROMA] - VG_PARAM * buffer[0][j * RGB_CHROMA + 1] - VB_PARAM * buffer[0][j * RGB_CHROMA + TWO] + UA_PARAM) >> MOVEBITS) + UA_PARAM; outputData[yIndex++] = static_cast((y < 0) ? 0 : (y > YUV_PARAM) ? YUV_PARAM : y); - if ((i % TWO == 0) && (j % TWO == 0)) { + if ((i % TWO == 0) && (j % TWO == 0) && (uvIndex < outputDataSize)) { outputData[uvIndex++] = static_cast((u < 0) ? 0 : (u > YUV_PARAM) ? YUV_PARAM : u); outputData[uvIndex++] = static_cast((v < 0) ? 0 : (v > YUV_PARAM) ? YUV_PARAM : v); } diff --git a/services/screenservice/sourceservice/BUILD.gn b/services/screenservice/sourceservice/BUILD.gn index 4061c4fb4728bfc06f3b1983729ac6cce82de5c2..620421fd9c253213d10e8c2b8e682e559989c401 100644 --- a/services/screenservice/sourceservice/BUILD.gn +++ b/services/screenservice/sourceservice/BUILD.gn @@ -88,6 +88,7 @@ ohos_shared_library("distributed_screen_source") { "distributed_hardware_fwk:distributed_av_sender", "distributed_hardware_fwk:distributedhardwareutils", "distributed_hardware_fwk:libdhfwk_sdk", + "eventhandler:libeventhandler", "graphic_2d:2d_graphics", "graphic_2d:libcomposer", "graphic_2d:librender_service_base", diff --git a/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp b/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp index 535eb8df25ec9ec9d5b7dedfe2faa00e21f4ab55..c2c5151ad7eca8596c665ea5422ae3fab868cf68 100644 --- a/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp +++ b/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2022-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -372,7 +372,7 @@ void ScreenDataChannelImpl::JsonToDirtyJson(nlohmann::json &rectJson, std::share if (!IsInt32(rectJson, "dirtySize") || !IsInt32(rectJson, "dataType")) { return; } - int32_t dirtySize = rectJson["dirtySize"].get(); + int32_t dirtySize = rectJson["dirtySize"].get(); int32_t dataType = rectJson["dataType"].get(); int32_t num = 0; if (dirtySize >= DIRTY_MAX_SIZE) { @@ -389,11 +389,11 @@ void ScreenDataChannelImpl::JsonToDirtyJson(nlohmann::json &rectJson, std::share DHLOGE("%{public}s: JsonToDirtyJson rectJson not contain int32", DSCREEN_LOG_TAG); return; } - int32_t X = rectJson[item][KEY_POINT_DIRTY_X].get(); - int32_t Y = rectJson[item][KEY_POINT_DIRTY_Y].get(); - int32_t W = rectJson[item][KEY_POINT_DIRTY_W].get(); - int32_t H = rectJson[item][KEY_POINT_DIRTY_H].get(); - int32_t Size = rectJson[item][KEY_POINT_DIRTY_SIZE].get(); + uint32_t X = rectJson[item][KEY_POINT_DIRTY_X].get(); + uint32_t Y = rectJson[item][KEY_POINT_DIRTY_Y].get(); + uint32_t W = rectJson[item][KEY_POINT_DIRTY_W].get(); + uint32_t H = rectJson[item][KEY_POINT_DIRTY_H].get(); + uint32_t Size = rectJson[item][KEY_POINT_DIRTY_SIZE].get(); DirtyRect rect = {X, Y, W, H, Size}; screenData->AddDirtyRect(rect); num++;