CVE-2022-32978: Reachable Assertion (CWE-617)
value: There is an assertion failure in SingleComponentLSScan::ParseMCU in singlecomponentlsscan.cpp in libjpeg before 1.64 via an empty JPEG-LS scan.
CWE description: The product contains an assert() or similar statement that can be triggered by an attacker, which leads to an application exit or other behavior that is more severe than necessary.
CVSS v3 base score: 6.5
Published: 2022-06-10T15:15Z
Repository: https://github.com/thorfdbg/libjpeg
Language: C++
Files changed: README, codestream/sampleinterleavedlsscan.cpp, codestream/singlecomponentlsscan.cpp
Commit date: 2022-06-08 12:58:05 +0200
Commit message: Fixed handling of empty JPEG-LS scans.

Diff: diff --git a/README b/README
index 124c958..3cff2da 100644
--- a/README
+++ b/README
@@ -38,11 +38,11 @@ Example usage:
 
 Standard JPEG compression, with 444 (aka "no") subsampling:
 
 $ jpeg -q <quality> infile.ppm outfile.jpg
 
-Standard JPEG compression, with 422 subsampling:
+Standard JPEG compression, with 420 subsampling:
 
 $ jpeg -q <quality> -s 1x1,2x2,2x2 infile.ppm outfile.jpg
 
 Intermediate dynamic range compression, i.e. compression of images
 of a bit-depth between 8 and 16 bits:
diff --git a/codestream/sampleinterleavedlsscan.cpp b/codestream/sampleinterleavedlsscan.cpp
index e92c309..e3cfe47 100644
--- a/codestream/sampleinterleavedlsscan.cpp
+++ b/codestream/sampleinterleavedlsscan.cpp
@@ -40,11 +40,11 @@
 *************************************************************************/
 /*
 ** A JPEG LS scan interleaving samples of several components,
 ** sample by sample.
 **
-** $Id: sampleinterleavedlsscan.cpp,v 1.15 2014/11/14 15:41:32 thor Exp $
+** $Id: sampleinterleavedlsscan.cpp,v 1.16 2022/06/08 10:54:55 thor Exp $
 **
 */
 
 /// Includes
 #include "codestream/jpeglsscan.hpp"
@@ -110,13 +110,16 @@ bool SampleInterleavedLSScan::ParseMCU(void)
   //
   // A "MCU" in respect to the code organization is eight lines.
   if (lines > 8) {
     lines = 8;
   }
+
+  if (lines == 0)
+    return false;
+  
   if (m_pFrame->HeightOf() > 0)
     m_ulRemaining[0] -= lines;
-  assert(lines > 0);
   assert(m_ucCount < 4);
 
   //
   // Fill the line pointers.
   for(cx = 0;cx < m_ucCount;cx++) {
diff --git a/codestream/singlecomponentlsscan.cpp b/codestream/singlecomponentlsscan.cpp
index 76310d6..cabc82c 100644
--- a/codestream/singlecomponentlsscan.cpp
+++ b/codestream/singlecomponentlsscan.cpp
@@ -39,11 +39,11 @@
 
 *************************************************************************/
 /*
 ** A JPEG LS scan covering only a single component.
 **
-** $Id: singlecomponentlsscan.cpp,v 1.18 2014/11/14 15:41:32 thor Exp $
+** $Id: singlecomponentlsscan.cpp,v 1.19 2022/06/08 10:54:55 thor Exp $
 **
 */
 
 /// Includes
 #include "codestream/jpeglsscan.hpp"
@@ -94,12 +94,13 @@ bool SingleComponentLSScan::ParseMCU(void)
   if (lines > 8) {
     lines = 8;
   }
   if (m_pFrame->HeightOf() > 0)
     m_ulRemaining[0] -= lines;
-  
-  assert(lines > 0);
+
+  if (lines == 0)
+    return false;
 
   // Loop over lines and columns
   do {
     LONG length = m_ulWidth[0];
     LONG *lp    = line->m_pData;

Vulnerable code: Standard JPEG compression, with 422 subsampling:
** $Id: sampleinterleavedlsscan.cpp,v 1.15 2014/11/14 15:41:32 thor Exp $
  assert(lines > 0);
** $Id: singlecomponentlsscan.cpp,v 1.18 2014/11/14 15:41:32 thor Exp $
  
  assert(lines > 0);
Fixed code: Standard JPEG compression, with 420 subsampling:
** $Id: sampleinterleavedlsscan.cpp,v 1.16 2022/06/08 10:54:55 thor Exp $

  if (lines == 0)
    return false;
  
** $Id: singlecomponentlsscan.cpp,v 1.19 2022/06/08 10:54:55 thor Exp $

  if (lines == 0)
    return false;