From c6c0d72614f4a9f627131b6003cc7f8add4e6774 Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Sun, 26 Jul 2026 15:10:34 -0700 Subject: [PATCH] fix(pnm): use 64-bit scanline math to avoid integer overflow Also hoisted an invariant computation of the number of bytes read per scanline out of the loop. Signed-off-by: Larry Gritz --- src/pnm.imageio/pnminput.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/pnm.imageio/pnminput.cpp b/src/pnm.imageio/pnminput.cpp index 959d3a749e..89adacdcfa 100644 --- a/src/pnm.imageio/pnminput.cpp +++ b/src/pnm.imageio/pnminput.cpp @@ -278,8 +278,16 @@ PNMInput::read_file_scanline(void* data, int y) } std::vector buf; - int nsamples = m_spec.width * m_spec.nchannels; - bool good = true; + imagesize_t width(m_spec.width); // 64 bit to avoid overflow + imagesize_t nsamples = width * m_spec.nchannels; + imagesize_t numbytes; + if (m_pnm_type == P4) + numbytes = (width + 7) / 8; + else if (m_pnm_type == PF || m_pnm_type == Pf) + numbytes = nsamples * 4; + else + numbytes = m_spec.scanline_bytes(); + bool good = true; // If y is farther ahead, skip scanlines to get to it for (; good && m_y_next <= y; ++m_y_next) { // PFM files are bottom-to-top, so we need to seek to the right spot @@ -293,19 +301,11 @@ PNMInput::read_file_scanline(void* data, int y) if ((m_pnm_type >= P4 && m_pnm_type <= P6) || m_pnm_type == PF || m_pnm_type == Pf) { - int numbytes; - if (m_pnm_type == P4) - numbytes = (m_spec.width + 7) / 8; - else if (m_pnm_type == PF || m_pnm_type == Pf) - numbytes = m_spec.nchannels * 4 * m_spec.width; - else - numbytes = m_spec.scanline_bytes(); if (size_t(numbytes) > m_remaining.size()) { errorfmt("Premature end of file"); return false; } buf.assign(m_remaining.begin(), m_remaining.begin() + numbytes); - m_remaining.remove_prefix(numbytes); }