CVE-2021-23191 (published 2022-03-02T23:15Z)

A security issue was found in htmldoc v1.9.12 and before. A NULL pointer dereference in the function image_load_jpeg() in image.cxx may result in denial of service.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 7.8, HIGH (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-476
cwe_name: NULL Pointer Dereference
description: The product dereferences a pointer that it expects to be valid but is NULL.
extended_description: 
            
            
            
         
         

Fix information:
repo_url: https://github.com/michaelrsweet/htmldoc
commit_details: repo_url: https://github.com/michaelrsweet/htmldoc
author: Michael R Sweet
author_date: 2021-04-01 09:37:58-04:00
msg: Fix JPEG error handling (Issue #415)
repository: repo_url: https://github.com/michaelrsweet/htmldoc
repo_name: michaelrsweet/htmldoc
description: HTML Conversion Software
repo_language: C++
owner: michaelrsweet
file_changes: filename: CHANGES.md
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,7 @@
 # Changes in HTMLDOC v1.9.12
 
 - Fixed a crash bug with "data:" URIs and EPUB output (Issue #410)
+- Fixed JPEG error handling (Issue #415)
 - Fixed crash bugs with bogus table attributes (Issue #416, Issue #417)
 - Fixed a crash bug with malformed URIs (Issue #418)
 - Fixed a crash bug with malformed GIF files (Issue #423)

programming_language: Markdown
filename: file.c
change_type: ModificationType.MODIFY
diff: @@ -1010,8 +1010,15 @@ file_rlookup(const char *filename)	/* I - Filename */
 
 
   for (i = web_files, wc = web_cache; i > 0; i --, wc ++)
+  {
     if (!strcmp(wc->name, filename))
-      return (wc->url);
+    {
+      if (!strncmp(wc->url, "data:", 5))
+        return ("data URL");
+      else
+        return (wc->url);
+    }
+  }
 
   return (filename);
 }

programming_language: C
filename: image.cxx
change_type: ModificationType.MODIFY
diff: @@ -1336,6 +1336,15 @@ image_load_gif(image_t *img,	/* I - Image pointer */
 }
 
 
+typedef struct hd_jpeg_err_s	// JPEG error manager extension
+{
+  struct jpeg_error_mgr	jerr;	// JPEG error manager information
+  jmp_buf	retbuf;		// setjmp() return buffer
+  char		message[JMSG_LENGTH_MAX];
+				// Last error message
+} hd_jpeg_err_t;
+
+
 /*
  * 'image_load_jpeg()' - Load a JPEG image file.
  */
@@ -1347,14 +1356,21 @@ image_load_jpeg(image_t *img,	/* I - Image pointer */
                 int     load_data)/* I - 1 = load image data, 0 = just info */
 {
   struct jpeg_decompress_struct	cinfo;		/* Decompressor info */
-  struct jpeg_error_mgr		jerr;		/* Error handler info */
-  JSAMPROW			row;		/* Sample row pointer */
+  hd_jpeg_err_t			jerr;		// JPEG error handler
+JSAMPROW			row;		/* Sample row pointer */
 
 
-  jpeg_std_error(&jerr);
-  jerr.error_exit = jpeg_error_handler;
+  jpeg_std_error(&jerr.jerr);
+  jerr.jerr.error_exit = jpeg_error_handler;
 
-  cinfo.err = &jerr;
+  if (setjmp(jerr.retbuf))
+  {
+    progress_error(HD_ERROR_BAD_FORMAT, "%s (%s)", jerr.message,  file_rlookup(img->filename));
+    jpeg_destroy_decompress(&cinfo);
+    return (-1);
+  }
+
+  cinfo.err = (struct jpeg_error_mgr *)&jerr;
   jpeg_create_decompress(&cinfo);
   jpeg_stdio_src(&cinfo, fp);
   jpeg_read_header(&cinfo, (boolean)1);
@@ -1797,9 +1813,17 @@ image_unload(image_t *img)	// I - Image
  */
 
 static void
-jpeg_error_handler(j_common_ptr)
+jpeg_error_handler(j_common_ptr p)	// Common JPEG data
 {
-  return;
+  hd_jpeg_err_t	*jerr = (hd_jpeg_err_t *)p->err;
+					// JPEG error handler
+
+
+  // Save the error message in the string buffer...
+  (jerr->jerr.format_message)(p, jerr->message);
+
+  // Return to the point we called setjmp()...
+  longjmp(jerr->retbuf, 1);
 }
 
 

programming_language: C
filename: ps-pdf.cxx
change_type: ModificationType.MODIFY
diff: @@ -1404,6 +1404,8 @@ pspdf_prepare_page(int page)		/* I - Page number */
 
 
   DEBUG_printf(("pspdf_prepare_page(%d)\n", page));
+  if (page < 0 || page >= num_pages)
+    return;
 
  /*
   * Make a page number; use roman numerals for the table of contents
@@ -12285,6 +12287,9 @@ write_trailer(FILE  *out,		/* I - Output file */
 
       for (j = 1; j <= TocDocCount; j ++)
       {
+        if (chapter_starts[j] < 0)
+          continue;
+
         page  = pages + chapter_starts[j];
 	start = chapter_starts[j] - chapter_starts[1] + 1;
 	type  = 'D';

programming_language: C