Skip to content

Commit

Permalink
Fix issues reported by OpenScanHub (#79)
Browse files Browse the repository at this point in the history
Open source static analyzer OpenScanHub found several issues regarding
resource leaks, security, buffer overflows etc., which this PR aims to
address.

libcupsfilters passes sanity testing with the changes.
  • Loading branch information
zdohnal authored Feb 11, 2025
1 parent 0158844 commit d21dd1c
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 29 deletions.
25 changes: 17 additions & 8 deletions cupsfilters/bannertopdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,12 @@ banner_free(banner_t *banner)
{
if (banner)
{
free(banner->template_file);
free(banner->header);
free(banner->footer);
if (banner->template_file)
free(banner->template_file);
if (banner->header)
free(banner->header);
if (banner->footer)
free(banner->footer);
free(banner);
}
}
Expand Down Expand Up @@ -224,7 +227,12 @@ banner_new_from_file(const char *filename,
break;
}

banner = calloc(1, sizeof *banner);
if ((banner = calloc(1, sizeof *banner)) == NULL)
{
if (log)
log(ld, CF_LOGLEVEL_ERROR, "cfFilterBannerToPDF: Not enough memory");
goto out;
}

while (getline(&line, &len, f) != -1)
{
Expand All @@ -248,12 +256,12 @@ banner_new_from_file(const char *filename,
while (*key == '%')
key ++;

if (!strcasecmp(key, "template"))
if (!banner->template_file && !strcasecmp(key, "template"))
banner->template_file = template_path(value, datadir);
else if (!strcasecmp(key, "header"))
banner->header = strdup(value);
else if (!strcasecmp(key, "footer"))
else if (!banner->header && !strcasecmp(key, "header"))
banner->header = strdup(value);
else if (!banner->footer && !strcasecmp(key, "footer"))
banner->footer = strdup(value);
else if (!strcasecmp(key, "font"))
*num_options = cupsAddOption("banner-font",
strdup(value), *num_options, options);
Expand Down Expand Up @@ -1003,6 +1011,7 @@ cfFilterBannerToPDF(int inputfd, // I - File descriptor input stream
banner_free(banner);
if (options) cupsFreeOptions(num_options, options);
unlink(tempfile);
fclose(inputfp);

return (ret);
}
8 changes: 7 additions & 1 deletion cupsfilters/fontembed/sfnt-subset.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,13 @@ _cfFontEmbedOTFSubSet(_cf_fontembed_otf_file_t *otf,
if (glyphs[b] & c)
{
const int len = _cfFontEmbedOTFGetGlyph(otf, iA);
DEBUG_assert(len >= 0);
if (len < 0)
{
fprintf(stderr, "Cannot get the glyph.\n");
free(new_loca);
free(new_glyf);
return (-1);
}
memcpy(new_glyf + offset, otf->gly, len);
offset += len;
}
Expand Down
2 changes: 1 addition & 1 deletion cupsfilters/ghostscript.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ cfFilterGhostscript(int inputfd, // I - File descriptor input
{
cf_filter_out_format_t outformat;
char buf[BUFSIZ];
char *filename;
char *filename = NULL;
char *icc_profile = NULL;
char *tmp;
char tmpstr[1024],
Expand Down
22 changes: 20 additions & 2 deletions cupsfilters/image-jpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,26 @@ _cfImageReadJPEG(

cfImageSetMaxTiles(img, 0);

in = malloc(img->xsize * cinfo.output_components);
out = malloc(img->xsize * cfImageGetDepth(img));
if ((in = (cf_ib_t*)calloc(img->xsize * cinfo.output_components, sizeof(cf_ib_t))) == NULL)
{
DEBUG_printf("DEBUG: Not enough memory.");

jpeg_destroy_decompress(&cinfo);

fclose(fp);
return (1);
}

if ((out = (cf_ib_t*)calloc(img->xsize * cfImageGetDepth(img), sizeof(cf_ib_t))) == NULL)
{
DEBUG_printf("DEBUG: Not enough memory.");

jpeg_destroy_decompress(&cinfo);

free(in);
fclose(fp);
return (1);
}

jpeg_start_decompress(&cinfo);

Expand Down
2 changes: 1 addition & 1 deletion cupsfilters/image-png.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ _cfImageReadPNG(
}

bpp = cfImageGetDepth(img);
out = malloc(img->xsize * bpp);
out = (cf_ib_t*)calloc(img->xsize * bpp, sizeof(cf_ib_t));

if (!in || !out)
{
Expand Down
34 changes: 30 additions & 4 deletions cupsfilters/image-tiff.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,21 @@ _cfImageReadTIFF(
else
pstep = xdir;

in = malloc(img->xsize * 3 + 3);
out = malloc(img->xsize * bpp);
if ((in = (cf_ib_t*)calloc(img->xsize * 3 + 3, sizeof(cf_ib_t))) == NULL)
{
DEBUG_puts("DEBUG: No enough memory.\n");
TIFFClose(tif);
fclose(fp);
return (1);
}
if ((out = (cf_ib_t*)calloc(img->xsize * bpp, sizeof(cf_ib_t))) == NULL)
{
DEBUG_puts("DEBUG: No enough memory.\n");
free(in);
TIFFClose(tif);
fclose(fp);
return (1);
}
}
else
{
Expand All @@ -326,8 +339,21 @@ _cfImageReadTIFF(
else
pstep = ydir;

in = malloc(img->ysize * 3 + 3);
out = malloc(img->ysize * bpp);
if ((in = (cf_ib_t*)calloc(img->ysize * 3 + 3, sizeof(cf_ib_t))) == NULL)
{
DEBUG_puts("DEBUG: No enough memory.\n");
TIFFClose(tif);
fclose(fp);
return (1);
}
if ((out = (cf_ib_t*)calloc(img->ysize * bpp, sizeof(cf_ib_t))) == NULL)
{
DEBUG_puts("DEBUG: No enough memory.\n");
free(in);
TIFFClose(tif);
fclose(fp);
return (1);
}
}

//
Expand Down
5 changes: 5 additions & 0 deletions cupsfilters/imagetopdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@ cfFilterImageToPDF(int inputfd, // I - File descriptor input stream
doc.pageObjects = NULL;
doc.gammaval = 1.0;
doc.brightness = 1.0;
doc.row = NULL;

//
// Open the input data stream specified by the inputfd ...
Expand Down Expand Up @@ -1871,6 +1872,8 @@ cfFilterImageToPDF(int inputfd, // I - File descriptor input stream
//

cfImageClose(doc.img);
free(doc.row);
free(doc.pageObjects);
fclose(doc.outputfp);
close(outputfd);
return (0);
Expand All @@ -1881,6 +1884,8 @@ cfFilterImageToPDF(int inputfd, // I - File descriptor input stream
"cfFilterImageToPDF: Cannot allocate any more memory.");
free_all_obj(&doc);
cfImageClose(doc.img);
free(doc.row);
free(doc.pageObjects);
fclose(doc.outputfp);
close(outputfd);
return (2);
Expand Down
2 changes: 1 addition & 1 deletion cupsfilters/imagetoraster.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ cfFilterImageToRaster(int inputfd, // I - File descriptor input stream
customBottom = 0.0,
customRight = 0.0,
customTop = 0.0;
char defSize[41];
char defSize[64];
cf_filter_out_format_t outformat;

//
Expand Down
20 changes: 17 additions & 3 deletions cupsfilters/pdftopdf/pdftopdf.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -859,8 +859,8 @@ cfFilterPDFToPDF(int inputfd, // I - File descriptor input stream
{
pdftopdf_doc_t doc; // Document information
char *final_content_type = data->final_content_type;
FILE *inputfp,
*outputfp;
FILE *inputfp = NULL,
*outputfp = NULL;
const char *t;
int streaming = 0;
size_t bytes;
Expand Down Expand Up @@ -953,7 +953,10 @@ cfFilterPDFToPDF(int inputfd, // I - File descriptor input stream

// Process the PDF input data
if (!_cfProcessPDFToPDF(*proc, param, &doc))
{
fclose(inputfp);
return (2);
}

// Pass information to subsequent filters via PDF comments
std::vector<std::string> output;
Expand All @@ -978,7 +981,10 @@ cfFilterPDFToPDF(int inputfd, // I - File descriptor input stream

outputfp = fdopen(outputfd, "w");
if (outputfp == NULL)
{
fclose(inputfp);
return (1);
}

if (!streaming)
{
Expand All @@ -994,22 +1000,30 @@ cfFilterPDFToPDF(int inputfd, // I - File descriptor input stream
while ((bytes = fread(buf, 1, sizeof(buf), inputfp)) > 0)
if (fwrite(buf, 1, bytes, outputfp) != bytes)
break;
fclose(inputfp);
}

fclose(inputfp);
fclose(outputfp);
}
catch (std::exception &e)
{
// TODO? exception type
if (log) log(ld, CF_LOGLEVEL_ERROR,
"cfFilterPDFToPDF: Exception: %s", e.what());
if (inputfp)
fclose(inputfp);
if (outputfp)
fclose(outputfp);
return (5);
}
catch (...)
{
if (log) log(ld, CF_LOGLEVEL_ERROR,
"cfFilterPDFToPDF: Unknown exception caught. Exiting.");
if (inputfp)
fclose(inputfp);
if (outputfp)
fclose(outputfp);
return (6);
}

Expand Down
24 changes: 18 additions & 6 deletions cupsfilters/pwgtopdf.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1536,6 +1536,7 @@ cfFilterPWGToPDF(int inputfd, // I - File descriptor input stream
int total_attrs;
char buf[1024];
const char *kw;
int ret = -1; // Return value


(void)inputseekable;
Expand Down Expand Up @@ -1602,6 +1603,7 @@ cfFilterPWGToPDF(int inputfd, // I - File descriptor input stream
{
if (log) log(ld, CF_LOGLEVEL_ERROR,
"cfFilterPWGToPDF: PCLm output: No printer IPP attributes are supplied, PCLm output not possible.");
fclose(outputfp);
return (1);
}

Expand Down Expand Up @@ -1703,7 +1705,8 @@ cfFilterPWGToPDF(int inputfd, // I - File descriptor input stream
{
if (log) log(ld, CF_LOGLEVEL_ERROR,
"cfFilterPWGToPDF: PCLm output: Printer IPP attributes do not contain printer resolution information for PCLm.");
return (1);
ret = 1;
goto error;
}

attr_name = (char *)"pclm-compression-method-preferred";
Expand Down Expand Up @@ -1759,7 +1762,8 @@ cfFilterPWGToPDF(int inputfd, // I - File descriptor input stream
{
if (log) log(ld, CF_LOGLEVEL_ERROR,
"cfFilterPWGToPDF: Unable to create PDF file");
return (1);
ret = 1;
goto error;
}
}

Expand Down Expand Up @@ -1795,7 +1799,8 @@ cfFilterPWGToPDF(int inputfd, // I - File descriptor input stream
{
if (log) log(ld, CF_LOGLEVEL_ERROR,
"cfFilterPWGToPDF: Unable to start new PDF page");
return (1);
ret = 1;
goto error;
}

// Write the bit map into the PDF file
Expand All @@ -1805,16 +1810,17 @@ cfFilterPWGToPDF(int inputfd, // I - File descriptor input stream
{
if (log) log(ld, CF_LOGLEVEL_ERROR,
"cfFilterPWGToPDF: Failed to convert page bitmap");
return (1);
ret = 1;
goto error;
}
}

if (empty)
{
if (log) log(ld, CF_LOGLEVEL_DEBUG,
"cfFilterPWGToPDF: Input is empty, outputting empty file.");
cupsRasterClose(ras);
return (0);
ret = 0;
goto error;
}

close_pdf_file(&pdf, &doc); // output to outputfp
Expand All @@ -1826,4 +1832,10 @@ cfFilterPWGToPDF(int inputfd, // I - File descriptor input stream
fclose(outputfp);

return (Page == 0);

error:
cupsRasterClose(ras);
fclose(outputfp);

return (ret);
}
2 changes: 1 addition & 1 deletion cupsfilters/raster.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ cfRasterSetColorSpace(cups_page_header_t *h, // I - Raster header
int cspace_fallback = 0; // 0: originally requested color space
// 1: sRGB for color, sGray for mono
// 2: sRGB for mono
const char *p, *q;
const char *p, *q = NULL;

// Range-check
if (!h || !available || !cspace)
Expand Down
1 change: 1 addition & 0 deletions cupsfilters/testfilters.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ test_wrapper(
strerror(errno));
fprintf(stderr, "ERROR: Unable to open Write file\n");
}
close(inputfd);

return (1);
}
Expand Down
14 changes: 13 additions & 1 deletion cupsfilters/texttopdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,9 @@ cfFilterTextToPDF(int inputfd, // I - File descriptor input stream
doc.PageTop = 756.0f; // Top margin
doc.PageWidth = 612.0f; // Total page width
doc.PageLength = 792.0f; // Total page length
doc.pdf = NULL;
doc.pdf = NULL; // PDF file contents
doc.Date = NULL; // Date string
doc.Title = NULL; // Title string

if (parameters)
doc.env_vars = *((cf_filter_texttopdf_parameter_t *)parameters);
Expand Down Expand Up @@ -1512,6 +1514,15 @@ cfFilterTextToPDF(int inputfd, // I - File descriptor input stream
free(doc.Page);
}

if (doc.PrettyPrint)
{
free(doc.Date);
free(doc.Title);
}

if (doc.pdf)
free(doc.pdf);

return (ret);
}

Expand Down Expand Up @@ -1766,6 +1777,7 @@ write_epilogue(texttopdf_doc_t *doc)
_cfPDFOutFinishPDF(doc->pdf);

_cfPDFOutFree(doc->pdf);
doc->pdf = NULL;
}


Expand Down

0 comments on commit d21dd1c

Please sign in to comment.