diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index 63c70fb6..dffd611d 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -31,6 +31,7 @@ #include "futils.hpp" #include "helper_functions.hpp" #include "enforce.hpp" +#include "safe_op.hpp" #ifdef WIN32 #include @@ -459,6 +460,10 @@ namespace Exiv2 { --search; } else if ( marker == app2_ && memcmp(buf.pData_ + 2, iccId_,11)==0) { + if (size < 2+14) { + rc = 8; + break; + } // ICC profile if ( ! foundIccData ) { foundIccData = true ; @@ -481,14 +486,18 @@ namespace Exiv2 { io_->seek( 14+2, BasicIo::cur); // step header // read in profile // #1286 profile can be padded - DataBuf icc((chunk==1&&chunks==1)?s:size-2-14); - if ( icc.size_ > size-2-14) throw Error(kerInvalidIccProfile); + long icc_size = size-2-14; + if (chunk==1 && chunks==1) { + enforce(s <= static_cast(icc_size), kerInvalidIccProfile); + icc_size = s; + } + DataBuf icc(icc_size); io_->read( icc.pData_,icc.size_); if ( !iccProfileDefined() ) { // first block of profile setIccProfile(icc,chunk==chunks); } else { // extend existing profile - DataBuf profile(iccProfile_.size_+icc.size_); + DataBuf profile(Safe::add(iccProfile_.size_, icc.size_)); if ( iccProfile_.size_ ) { ::memcpy(profile.pData_,iccProfile_.pData_,iccProfile_.size_); } diff --git a/test/data/issue_853_poc.jpg b/test/data/issue_853_poc.jpg new file mode 100644 index 00000000..7dc50d30 Binary files /dev/null and b/test/data/issue_853_poc.jpg differ diff --git a/tests/bugfixes/github/test_issue_853.py b/tests/bugfixes/github/test_issue_853.py new file mode 100644 index 00000000..d7f62a3c --- /dev/null +++ b/tests/bugfixes/github/test_issue_853.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, path + + +class DenialOfServiceInAdjustTimeOverflow(metaclass=CaseMeta): + """ + Regression test for the bug described in: + https://github.com/Exiv2/exiv2/issues/853 + + The date parsing code in XMPUtils::ConvertToDate does not + check that the month and day are in bounds. This can cause a + denial of service in AdjustTimeOverflow because it adjusts + out-of-bounds days in a loop that subtracts one month per + iteration. + """ + url = "https://github.com/Exiv2/exiv2/issues/853" + + filename = path("$data_path/issue_853_poc.jpg") + commands = ["$exiv2 $filename"] + stdout = [""] + stderr = [ + """Exiv2 exception in print action for file $filename: +Not a valid ICC Profile +"""] + retval = [1]