From 7695dd0f9f5a5a91a0fdfc723edfe706a39c87f4 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Mon, 2 Jul 2018 21:20:23 +0000 Subject: Check for more integer overflows in CJBig2_TRDProc. BUG=chromium:859284 Change-Id: I41ce5de4cca0a863dc6e60b64fd69d36c2672a64 Reviewed-on: https://pdfium-review.googlesource.com/36790 Reviewed-by: Tom Sepez Commit-Queue: Lei Zhang --- core/fxcodec/jbig2/JBig2_TrdProc.cpp | 69 ++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 18 deletions(-) (limited to 'core/fxcodec/jbig2/JBig2_TrdProc.cpp') diff --git a/core/fxcodec/jbig2/JBig2_TrdProc.cpp b/core/fxcodec/jbig2/JBig2_TrdProc.cpp index 5c93ced616..4790f6657c 100644 --- a/core/fxcodec/jbig2/JBig2_TrdProc.cpp +++ b/core/fxcodec/jbig2/JBig2_TrdProc.cpp @@ -14,8 +14,31 @@ #include "core/fxcodec/jbig2/JBig2_HuffmanDecoder.h" #include "core/fxcrt/fx_safe_types.h" #include "core/fxcrt/maybe_owned.h" +#include "third_party/base/optional.h" #include "third_party/base/ptr_util.h" +namespace { + +Optional CheckTRDDimension(uint32_t dimension, int32_t delta) { + FX_SAFE_UINT32 result = dimension; + result += delta; + if (!result.IsValid()) + return {}; + return {result.ValueOrDie()}; +} + +Optional CheckTRDReferenceDimension(uint32_t dimension, + uint32_t divisor, + int32_t offset) { + FX_SAFE_INT32 result = offset; + result += dimension / divisor; + if (!result.IsValid()) + return {}; + return {result.ValueOrDie()}; +} + +} // namespace + CJBig2_TRDProc::CJBig2_TRDProc() {} CJBig2_TRDProc::~CJBig2_TRDProc() {} @@ -133,20 +156,25 @@ std::unique_ptr CJBig2_TRDProc::DecodeHuffman( if (!IBOI) return nullptr; - uint32_t WOI = IBOI->width(); - uint32_t HOI = IBOI->height(); - if (static_cast(WOI + RDWI) < 0 || - static_cast(HOI + RDHI) < 0) { + Optional WOI = CheckTRDDimension(IBOI->width(), RDWI); + Optional HOI = CheckTRDDimension(IBOI->height(), RDHI); + if (!WOI || !HOI) + return nullptr; + + Optional GRREFERENCEDX = + CheckTRDReferenceDimension(RDWI, 4, RDXI); + Optional GRREFERENCEDY = + CheckTRDReferenceDimension(RDHI, 4, RDYI); + if (!GRREFERENCEDX || !GRREFERENCEDY) return nullptr; - } auto pGRRD = pdfium::MakeUnique(); - pGRRD->GRW = WOI + RDWI; - pGRRD->GRH = HOI + RDHI; + pGRRD->GRW = WOI.value(); + pGRRD->GRH = HOI.value(); pGRRD->GRTEMPLATE = SBRTEMPLATE; pGRRD->GRREFERENCE = IBOI; - pGRRD->GRREFERENCEDX = (RDWI >> 2) + RDXI; - pGRRD->GRREFERENCEDY = (RDHI >> 2) + RDYI; + pGRRD->GRREFERENCEDX = GRREFERENCEDX.value(); + pGRRD->GRREFERENCEDY = GRREFERENCEDY.value(); pGRRD->TPGRON = 0; pGRRD->GRAT[0] = SBRAT[0]; pGRRD->GRAT[1] = SBRAT[1]; @@ -308,20 +336,25 @@ std::unique_ptr CJBig2_TRDProc::DecodeArith( if (!IBOI) return nullptr; - uint32_t WOI = IBOI->width(); - uint32_t HOI = IBOI->height(); - if (static_cast(WOI + RDWI) < 0 || - static_cast(HOI + RDHI) < 0) { + Optional WOI = CheckTRDDimension(IBOI->width(), RDWI); + Optional HOI = CheckTRDDimension(IBOI->height(), RDHI); + if (!WOI || !HOI) + return nullptr; + + Optional GRREFERENCEDX = + CheckTRDReferenceDimension(RDWI, 2, RDXI); + Optional GRREFERENCEDY = + CheckTRDReferenceDimension(RDHI, 2, RDYI); + if (!GRREFERENCEDX || !GRREFERENCEDY) return nullptr; - } auto pGRRD = pdfium::MakeUnique(); - pGRRD->GRW = WOI + RDWI; - pGRRD->GRH = HOI + RDHI; + pGRRD->GRW = WOI.value(); + pGRRD->GRH = HOI.value(); pGRRD->GRTEMPLATE = SBRTEMPLATE; pGRRD->GRREFERENCE = IBOI; - pGRRD->GRREFERENCEDX = (RDWI >> 1) + RDXI; - pGRRD->GRREFERENCEDY = (RDHI >> 1) + RDYI; + pGRRD->GRREFERENCEDX = GRREFERENCEDX.value(); + pGRRD->GRREFERENCEDY = GRREFERENCEDY.value(); pGRRD->TPGRON = 0; pGRRD->GRAT[0] = SBRAT[0]; pGRRD->GRAT[1] = SBRAT[1]; -- cgit v1.2.3