@@ -154,17 +154,43 @@ bool MPOPicture::LoadImageFromMemory(const std::string& mimetype,
154154}
155155
156156bool MPOPicture::Decode (uint8_t * pixels,
157+ size_t pixelBufferSize,
157158 unsigned int width,
158159 unsigned int height,
159160 unsigned int pitch,
160161 ADDON_IMG_FMT format)
161162{
163+ // The copy loop below writes B,G,R and only fills the fourth byte for
164+ // A8R8G8B8, so that is the only format implemented here.
165+ if (format != ADDON_IMG_FMT_A8R8G8B8 )
166+ {
167+ kodi::Log (ADDON_LOG_ERROR , " %s: Unsupported target format (%d)" , __func__,
168+ static_cast <int >(format));
169+ return false ;
170+ }
171+
162172 size_t image = 0 ;
163173 while (image < m_images)
164174 {
165175 mpo_start_decompress (&m_mpoinfo);
166176 JSAMPARRAY buffer;
167177 int row_stride = m_mpoinfo.cinfo .cinfo .output_width * m_mpoinfo.cinfo .cinfo .output_components ;
178+
179+ // Mirrors the destination offset in the loop below exactly - the integer
180+ // division must be applied in the same order or an odd m_width
181+ // underestimates the reach for images after the first.
182+ const size_t tileOffset = image * m_width / 2 * 4 ;
183+ if (m_height == 0 || row_stride <= 0 ||
184+ static_cast <size_t >(m_height - 1 ) * pitch + tileOffset +
185+ static_cast <size_t >(row_stride / 3 ) * 4 >
186+ pixelBufferSize)
187+ {
188+ kodi::Log (ADDON_LOG_ERROR , " %s: Output buffer too small for image %zu of %ux%u at pitch %u" ,
189+ __func__, image, m_width, m_height, pitch);
190+ mpo_finish_decompress (&m_mpoinfo);
191+ return false ;
192+ }
193+
168194 size_t lines = 0 ;
169195 while (lines < m_height)
170196 {
0 commit comments