Fix overly-strong ASSERT in WeightTable::SetStartEnd() A zero-length range at zero represented by [0, -1] will be fine so long as we don't actually try to reference the range. Stop short of switching over to the simpler [0, 0) representation. Note that `weight_count` is bounded by earlier size checks and fits in an int. -- Add another ASSERT to earlier tests. Bug: chromium:1219974 Change-Id: I26b077d11e54465b861070e887b3efde8f2178da Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/82155 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxge/dib/cstretchengine.cpp b/core/fxge/dib/cstretchengine.cpp index 69cb8db..5b2ff3b 100644 --- a/core/fxge/dib/cstretchengine.cpp +++ b/core/fxge/dib/cstretchengine.cpp
@@ -35,6 +35,9 @@ // static size_t CStretchEngine::PixelWeight::TotalBytesForWeightCount( size_t weight_count) { + // Always room for one weight even for empty ranges due to declaration + // of m_Weights[1] in the header. Don't shrink below this since + // CalculateWeights() relies on this later. const size_t extra_weights = weight_count > 0 ? weight_count - 1 : 0; FX_SAFE_SIZE_T total_bytes = extra_weights; total_bytes *= sizeof(m_Weights[0]); @@ -95,7 +98,8 @@ src_start = std::max(src_start, src_min); src_end = std::min(src_end, src_max - 1); pixel_weights.SetStartEnd(src_start, src_end, weight_count); - if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { + if (pixel_weights.m_SrcStart >= pixel_weights.m_SrcEnd) { + // Always room for one weight per size calculation. pixel_weights.m_Weights[0] = kFixedPointOne; } else { pixel_weights.m_Weights[1] = FixedFromFloat(
diff --git a/core/fxge/dib/cstretchengine.h b/core/fxge/dib/cstretchengine.h index 5ebebb4..eef7fd0 100644 --- a/core/fxge/dib/cstretchengine.h +++ b/core/fxge/dib/cstretchengine.h
@@ -38,7 +38,7 @@ static size_t TotalBytesForWeightCount(size_t weight_count); void SetStartEnd(int src_start, int src_end, size_t weight_count) { - CHECK_LT(static_cast<size_t>(src_end - src_start), weight_count); + CHECK_LT(src_end - src_start, static_cast<int>(weight_count)); m_SrcStart = src_start; m_SrcEnd = src_end; } @@ -61,7 +61,7 @@ } int m_SrcStart; - int m_SrcEnd; // Note: inclusive. + int m_SrcEnd; // Note: inclusive, [0, -1] for empty range at 0. uint32_t m_Weights[1]; // Not really 1, variable size. };
diff --git a/core/fxge/dib/cstretchengine_unittest.cpp b/core/fxge/dib/cstretchengine_unittest.cpp index 202db9f..a64024d 100644 --- a/core/fxge/dib/cstretchengine_unittest.cpp +++ b/core/fxge/dib/cstretchengine_unittest.cpp
@@ -29,8 +29,8 @@ const FXDIB_ResampleOptions& options) { constexpr uint32_t kExpectedSum = CStretchEngine::kFixedPointOne; CStretchEngine::WeightTable table; - table.CalculateWeights(dest_width, 0, dest_width, src_width, 0, src_width, - options); + ASSERT_TRUE(table.CalculateWeights(dest_width, 0, dest_width, src_width, 0, + src_width, options)); for (uint32_t i = 0; i < dest_width; ++i) { EXPECT_EQ(kExpectedSum, PixelWeightSum(table.GetPixelWeight(i))) << "for { " << src_width << ", " << dest_width << " } at " << i; @@ -92,3 +92,31 @@ options.bInterpolateBilinear = true; ExecuteStretchTests(options); } + +TEST(CStretchEngine, ZeroLengthSrc) { + FXDIB_ResampleOptions options; + CStretchEngine::WeightTable table; + ASSERT_TRUE(table.CalculateWeights(100, 0, 100, 0, 0, 0, options)); +} + +TEST(CStretchEngine, ZeroLengthSrcNoSmoothing) { + FXDIB_ResampleOptions options; + options.bNoSmoothing = true; + CStretchEngine::WeightTable table; + ASSERT_TRUE(table.CalculateWeights(100, 0, 100, 0, 0, 0, options)); +} + +TEST(CStretchEngine, ZeroLengthSrcBilinear) { + FXDIB_ResampleOptions options; + options.bInterpolateBilinear = true; + CStretchEngine::WeightTable table; + ASSERT_TRUE(table.CalculateWeights(100, 0, 100, 0, 0, 0, options)); +} + +TEST(CStretchEngine, ZeroLengthSrcNoSmoothingBilinear) { + FXDIB_ResampleOptions options; + options.bNoSmoothing = true; + options.bInterpolateBilinear = true; + CStretchEngine::WeightTable table; + ASSERT_TRUE(table.CalculateWeights(100, 0, 100, 0, 0, 0, options)); +}