From f9df8ba19a92d5c97532c8d52c034beabe957cf7 Mon Sep 17 00:00:00 2001 From: mayeut Date: Thu, 24 Sep 2015 23:32:03 +0200 Subject: [PATCH 1/4] Fix some resource leaks --- src/bin/jp2/convert.c | 71 ++++++++++++++++++++++++++++---------- src/bin/jp2/convertbmp.c | 1 + src/bin/jp2/opj_compress.c | 15 +++++++- 3 files changed, 68 insertions(+), 19 deletions(-) diff --git a/src/bin/jp2/convert.c b/src/bin/jp2/convert.c index 1ccb34f8..1fd64ee7 100644 --- a/src/bin/jp2/convert.c +++ b/src/bin/jp2/convert.c @@ -734,12 +734,16 @@ opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters) { return 0; } - if (!tga_readheader(f, &pixel_bit_depth, &image_width, &image_height, &flip_image)) + if (!tga_readheader(f, &pixel_bit_depth, &image_width, &image_height, &flip_image)) { + fclose(f); return NULL; + } /* We currently only support 24 & 32 bit tga's ... */ - if (!((pixel_bit_depth == 24) || (pixel_bit_depth == 32))) + if (!((pixel_bit_depth == 24) || (pixel_bit_depth == 32))) { + fclose(f); return NULL; + } /* initialize image components */ memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t)); @@ -772,8 +776,11 @@ opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters) { /* create the image */ image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space); - if (!image) + if (!image) { + fclose(f); return NULL; + } + /* set image offset and reference grid */ image->x0 = (OPJ_UINT32)parameters->image_offset_x0; @@ -801,18 +808,21 @@ opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters) { { fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); opj_image_destroy(image); + fclose(f); return NULL; } if ( !fread(&g, 1, 1, f) ) { fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); opj_image_destroy(image); + fclose(f); return NULL; } if ( !fread(&r, 1, 1, f) ) { fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); opj_image_destroy(image); + fclose(f); return NULL; } @@ -831,24 +841,28 @@ opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters) { { fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); opj_image_destroy(image); + fclose(f); return NULL; } if ( !fread(&g, 1, 1, f) ) { fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); opj_image_destroy(image); + fclose(f); return NULL; } if ( !fread(&r, 1, 1, f) ) { fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); opj_image_destroy(image); + fclose(f); return NULL; } if ( !fread(&a, 1, 1, f) ) { fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); opj_image_destroy(image); + fclose(f); return NULL; } @@ -863,6 +877,7 @@ opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters) { fprintf(stderr, "Currently unsupported bit depth : %s\n", filename); } } + fclose(f); return image; } @@ -889,6 +904,7 @@ int imagetotga(opj_image_t * image, const char *outfile) { if ((image->comps[0].dx != image->comps[i+1].dx) ||(image->comps[0].dy != image->comps[i+1].dy) ||(image->comps[0].prec != image->comps[i+1].prec)) { + fclose(fdest); fprintf(stderr, "Unable to create a tga file with such J2K image charateristics."); return 1; } @@ -1081,6 +1097,7 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) { fseek(f, 0, SEEK_SET); if( fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h) != 9){ + fclose(f); fprintf(stderr, "ERROR: Failed to read the right number of element from the fscanf() function!\n"); return NULL; } @@ -1098,6 +1115,7 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) { } else if (endian2=='M' && endian1=='L') { bigendian = 0; } else { + fclose(f); fprintf(stderr, "Bad pgx header, please check input file\n"); return NULL; } @@ -1212,7 +1230,7 @@ int imagetopgx(opj_image_t * image, const char *outfile) FILE *fdest = NULL; for (compno = 0; compno < image->numcomps; compno++) - { + { opj_image_comp_t *comp = &image->comps[compno]; char bname[256]; /* buffer for name */ char *name = bname; /* pointer */ @@ -1223,25 +1241,30 @@ int imagetopgx(opj_image_t * image, const char *outfile) const size_t total = dotpos + 1 + 1 + 4; /* '-' + '[1-3]' + '.pgx' */ if( outfile[dotpos] != '.' ) - { + { /* `pgx` was recognized but there is no dot at expected position */ fprintf(stderr, "ERROR -> Impossible happen." ); goto fin; - } + } if( total > 256 ) - { + { name = (char*)malloc(total+1); - } + if (name == NULL) { + goto fin; + } + } strncpy(name, outfile, dotpos); sprintf(name+dotpos, "_%d.pgx", compno); fdest = fopen(name, "wb"); /* dont need name anymore */ - if( total > 256 ) free(name); + if (!fdest) - { + { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", name); + if( total > 256 ) free(name); goto fin; - } + } w = (int)image->comps[compno].w; h = (int)image->comps[compno].h; @@ -1257,26 +1280,28 @@ int imagetopgx(opj_image_t * image, const char *outfile) nbytes = 4; for (i = 0; i < w * h; i++) - { + { /* FIXME: clamp func is being called within a loop */ const int val = clamp(image->comps[compno].data[i], (int)comp->prec, (int)comp->sgnd); for (j = nbytes - 1; j >= 0; j--) - { + { int v = (int)(val >> (j * 8)); unsigned char byte = (unsigned char)v; res = fwrite(&byte, 1, 1, fdest); if( res < 1 ) - { + { fprintf(stderr, "failed to write 1 byte for %s\n", name); + if( total > 256 ) free(name); goto fin; - } - } - } + } + } + } + if( total > 256 ) free(name); fclose(fdest); fdest = NULL; - } + } fails = 0; fin: if(fdest) fclose(fdest); @@ -1650,6 +1675,7 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) { { fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); opj_image_destroy(image); + fclose(fp); return NULL; } if(one) @@ -2003,6 +2029,7 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p if (!cmptparm) { fprintf(stderr, "Failed to allocate image components parameters !!\n"); fprintf(stderr,"Aborting\n"); + fclose(f); return NULL; } /* initialize image components */ @@ -2036,6 +2063,8 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p for (i = 0; i < nloop; i++) { if (!fread(&value, 1, 1, f)) { fprintf(stderr,"Error reading raw file. End of file probably reached.\n"); + opj_image_destroy(image); + fclose(f); return NULL; } image->comps[compno].data[i] = raw_cp->rawSigned?(char)value:value; @@ -2052,10 +2081,14 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p unsigned char temp2; if (!fread(&temp1, 1, 1, f)) { fprintf(stderr,"Error reading raw file. End of file probably reached.\n"); + opj_image_destroy(image); + fclose(f); return NULL; } if (!fread(&temp2, 1, 1, f)) { fprintf(stderr,"Error reading raw file. End of file probably reached.\n"); + opj_image_destroy(image); + fclose(f); return NULL; } if( big_endian ) @@ -2072,6 +2105,8 @@ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *p } else { fprintf(stderr,"OpenJPEG cannot encode raw components with bit depth higher than 16 bits.\n"); + opj_image_destroy(image); + fclose(f); return NULL; } diff --git a/src/bin/jp2/convertbmp.c b/src/bin/jp2/convertbmp.c index 0678d9d3..78ca4af5 100644 --- a/src/bin/jp2/convertbmp.c +++ b/src/bin/jp2/convertbmp.c @@ -729,6 +729,7 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) image = opj_image_create(numcmpts, &cmptparm[0], (numcmpts == 1U) ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB); if(!image) { fclose(IN); + free(pData); return NULL; } if (numcmpts == 4U) { diff --git a/src/bin/jp2/opj_compress.c b/src/bin/jp2/opj_compress.c index ee473ce3..d3dc62ff 100644 --- a/src/bin/jp2/opj_compress.c +++ b/src/bin/jp2/opj_compress.c @@ -391,6 +391,7 @@ static unsigned int get_num_images(char *imgdirpath){ continue; num_images++; } + closedir(dir); return num_images; } @@ -416,6 +417,7 @@ static int load_images(dircnt_t *dirptr, char *imgdirpath){ strcpy(dirptr->filename[i],content->d_name); i++; } + closedir(dir); return 0; } @@ -1058,9 +1060,16 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param lStrLen = (size_t)ftell(lFile); fseek(lFile,0,SEEK_SET); lMatrix = (char *) malloc(lStrLen + 1); + if (lMatrix == NULL) { + fclose(lFile); + return 1; + } lStrFread = fread(lMatrix, 1, lStrLen, lFile); fclose(lFile); - if( lStrLen != lStrFread ) return 1; + if( lStrLen != lStrFread ) { + free(lMatrix); + return 1; + } lMatrix[lStrLen] = 0; lCurrentPtr = lMatrix; @@ -1080,6 +1089,10 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param lMctComp = lNbComp * lNbComp; lTotalComp = lMctComp + lNbComp; lSpace = (float *) malloc((size_t)lTotalComp * sizeof(float)); + if(lSpace == NULL) { + free(lMatrix); + return 1; + } lCurrentDoublePtr = lSpace; for (i2=0;i2 Date: Fri, 25 Sep 2015 00:08:34 +0200 Subject: [PATCH 2/4] Fix resource leaks & unchecked resource allocations --- src/bin/jp2/convertbmp.c | 4 ++++ src/bin/jp2/convertpng.c | 2 +- src/bin/jp2/opj_compress.c | 9 ++++++--- src/bin/jp2/opj_decompress.c | 2 +- src/bin/jp2/opj_dump.c | 2 ++ 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/bin/jp2/convertbmp.c b/src/bin/jp2/convertbmp.c index 78ca4af5..910574b8 100644 --- a/src/bin/jp2/convertbmp.c +++ b/src/bin/jp2/convertbmp.c @@ -903,6 +903,10 @@ int imagetobmp(opj_image_t * image, const char *outfile) { <<-- <<-- <<-- <<-- */ fdest = fopen(outfile, "wb"); + if (!fdest) { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); + return 1; + } w = (int)image->comps[0].w; h = (int)image->comps[0].h; diff --git a/src/bin/jp2/convertpng.c b/src/bin/jp2/convertpng.c index 5a72d9fe..0999edbf 100644 --- a/src/bin/jp2/convertpng.c +++ b/src/bin/jp2/convertpng.c @@ -486,7 +486,7 @@ fin: } fclose(writer); - if(fails) remove(write_idf); + if(fails) (void)remove(write_idf); /* ignore return value */ return fails; }/* imagetopng() */ diff --git a/src/bin/jp2/opj_compress.c b/src/bin/jp2/opj_compress.c index d3dc62ff..e5f98532 100644 --- a/src/bin/jp2/opj_compress.c +++ b/src/bin/jp2/opj_compress.c @@ -456,7 +456,7 @@ static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_c if (parameters->decod_format == -1) return 1; sprintf(infilename,"%s/%s",img_fol->imgdirpath,image_filename); - strncpy(parameters->infile, infilename, sizeof(infilename)); + strncpy(parameters->infile, infilename, sizeof(infilename) - 1U); /*Set output file*/ strcpy(temp_ofname,get_file_name(image_filename)); @@ -466,7 +466,7 @@ static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_c } if(img_fol->set_out_format==1){ sprintf(outfilename,"%s/%s.%s",img_fol->imgdirpath,temp_ofname,img_fol->out_format); - strncpy(parameters->outfile, outfilename, sizeof(outfilename)); + strncpy(parameters->outfile, outfilename, sizeof(outfilename) - 1U); } return 0; } @@ -612,6 +612,9 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param substr2++; /* skip '@' character */ } substr1 = (char*) malloc((len+1)*sizeof(char)); + if (substr1 == NULL) { + return 1; + } memcpy(substr1,opj_optarg,len); substr1[len] = '\0'; if (sscanf(substr1, "%d,%d,%d,%d,%c", &width, &height, &ncomp, &bitdepth, &signo) == 5) { @@ -663,7 +666,7 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param } } } - if (substr1) free(substr1); + free(substr1); if (wrong) { fprintf(stderr,"\nError: invalid raw image parameters\n"); fprintf(stderr,"Please use the Format option -F:\n"); diff --git a/src/bin/jp2/opj_decompress.c b/src/bin/jp2/opj_decompress.c index da566ac2..bd755c82 100644 --- a/src/bin/jp2/opj_decompress.c +++ b/src/bin/jp2/opj_decompress.c @@ -1550,7 +1550,7 @@ int main(int argc, char **argv) /* destroy the codestream index */ opj_destroy_cstr_index(&cstr_index); - if(failed) remove(parameters.outfile); + if(failed) (void)remove(parameters.outfile); /* ignore return value */ } destroy_parameters(¶meters); if (numDecompressedImages) { diff --git a/src/bin/jp2/opj_dump.c b/src/bin/jp2/opj_dump.c index a85cfe90..4005f1c2 100644 --- a/src/bin/jp2/opj_dump.c +++ b/src/bin/jp2/opj_dump.c @@ -134,6 +134,7 @@ static int get_num_images(char *imgdirpath){ continue; num_images++; } + closedir(dir); return num_images; } @@ -160,6 +161,7 @@ static int load_images(dircnt_t *dirptr, char *imgdirpath){ strcpy(dirptr->filename[i],content->d_name); i++; } + closedir(dir); return 0; } From 4da7e9617fd28bee0b8c7509a00759ca9da6fb32 Mon Sep 17 00:00:00 2001 From: mayeut Date: Fri, 25 Sep 2015 00:39:05 +0200 Subject: [PATCH 3/4] Fix resource leak --- src/bin/jp2/opj_decompress.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bin/jp2/opj_decompress.c b/src/bin/jp2/opj_decompress.c index bd755c82..c27dc201 100644 --- a/src/bin/jp2/opj_decompress.c +++ b/src/bin/jp2/opj_decompress.c @@ -361,6 +361,7 @@ int get_num_images(char *imgdirpath){ continue; num_images++; } + closedir(dir); return num_images; } @@ -387,6 +388,7 @@ int load_images(dircnt_t *dirptr, char *imgdirpath){ strcpy(dirptr->filename[i],content->d_name); i++; } + closedir(dir); return 0; } From 838dfb8058df62af44905e1fa3936d989844effc Mon Sep 17 00:00:00 2001 From: mayeut Date: Fri, 25 Sep 2015 22:04:58 +0200 Subject: [PATCH 4/4] Provide safer string copy than strncpy As per @boxerab suggestion in commit b9ca882749597e4943e609daba1d3c27694fe2ff --- src/bin/common/opj_string.h | 72 ++++++++++++++++++++++++++++++++++++ src/bin/jp2/CMakeLists.txt | 1 + src/bin/jp2/opj_compress.c | 32 +++++++++++----- src/bin/jp2/opj_decompress.c | 49 +++++++++++++++--------- src/bin/jp2/opj_dump.c | 20 +++++++--- 5 files changed, 141 insertions(+), 33 deletions(-) create mode 100644 src/bin/common/opj_string.h diff --git a/src/bin/common/opj_string.h b/src/bin/common/opj_string.h new file mode 100644 index 00000000..8829926a --- /dev/null +++ b/src/bin/common/opj_string.h @@ -0,0 +1,72 @@ +/* + * The copyright in this software is being made available under the 2-clauses + * BSD License, included below. This software may be subject to other third + * party and contributor rights, including patent rights, and no such rights + * are granted under this license. + * + * Copyright (c) 2015, Matthieu Darbois + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef OPJ_STRING_H +#define OPJ_STRING_H + +#include +#include + +/* strnlen is not standard, strlen_s is C11... */ +/* keep in mind there still is a buffer read overflow possible */ +static size_t opj_strnlen_s(const char *src, size_t max_len) +{ + size_t len; + + if (src == NULL) { + return 0U; + } + for (len = 0U; (*src != '\0') && (len < max_len); src++, len++); + return len; +} + +/* should be equivalent to C11 function except for the handler */ +/* keep in mind there still is a buffer read overflow possible */ +static int opj_strcpy_s(char* dst, size_t dst_size, const char* src) +{ + size_t src_len = 0U; + if ((dst == NULL) || (dst_size == 0U)) { + return EINVAL; + } + if (src == NULL) { + dst[0] = '\0'; + return EINVAL; + } + src_len = opj_strnlen_s(src, dst_size); + if (src_len >= dst_size) { + return ERANGE; + } + memcpy(dst, src, src_len); + dst[src_len] = '\0'; + return 0; +} + +#endif /* OPJ_STRING_H */ diff --git a/src/bin/jp2/CMakeLists.txt b/src/bin/jp2/CMakeLists.txt index 7e2476df..d583c2e6 100644 --- a/src/bin/jp2/CMakeLists.txt +++ b/src/bin/jp2/CMakeLists.txt @@ -11,6 +11,7 @@ set(common_SRCS ${OPENJPEG_SOURCE_DIR}/src/bin/common/color.h ${OPENJPEG_SOURCE_DIR}/src/bin/common/opj_getopt.c ${OPENJPEG_SOURCE_DIR}/src/bin/common/opj_getopt.h + ${OPENJPEG_SOURCE_DIR}/src/bin/common/opj_string.h ) if(OPJ_HAVE_LIBTIFF) diff --git a/src/bin/jp2/opj_compress.c b/src/bin/jp2/opj_compress.c index e5f98532..9d690a56 100644 --- a/src/bin/jp2/opj_compress.c +++ b/src/bin/jp2/opj_compress.c @@ -69,6 +69,7 @@ #include "index.h" #include "format_defs.h" +#include "opj_string.h" typedef struct dircnt{ /** Buffer for holding images read from Directory*/ @@ -456,8 +457,10 @@ static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_c if (parameters->decod_format == -1) return 1; sprintf(infilename,"%s/%s",img_fol->imgdirpath,image_filename); - strncpy(parameters->infile, infilename, sizeof(infilename) - 1U); - + if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile), infilename) != 0) { + return 1; + } + /*Set output file*/ strcpy(temp_ofname,get_file_name(image_filename)); while((temp_p = strtok(NULL,".")) != NULL){ @@ -466,7 +469,9 @@ static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_c } if(img_fol->set_out_format==1){ sprintf(outfilename,"%s/%s.%s",img_fol->imgdirpath,temp_ofname,img_fol->out_format); - strncpy(parameters->outfile, outfilename, sizeof(outfilename) - 1U); + if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile), outfilename) != 0) { + return 1; + } } return 0; } @@ -474,7 +479,7 @@ static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_c /* ------------------------------------------------------------------------------------ */ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters, - img_fol_t *img_fol, raw_cparameters_t *raw_cp, char *indexfilename) { + img_fol_t *img_fol, raw_cparameters_t *raw_cp, char *indexfilename, size_t indexfilename_size) { OPJ_UINT32 i, j; int totlen, c; opj_option_t long_option[]={ @@ -528,7 +533,9 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param infile); return 1; } - strncpy(parameters->infile, infile, sizeof(parameters->infile)-1); + if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile), infile) != 0) { + return 1; + } } break; @@ -546,7 +553,9 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param fprintf(stderr, "Unknown output format image %s [only *.j2k, *.j2c or *.jp2]!! \n", outfile); return 1; } - strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1); + if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile), outfile) != 0) { + return 1; + } } break; @@ -812,8 +821,9 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param case 'x': /* creation of index file */ { - char *index = opj_optarg; - strncpy(indexfilename, index, OPJ_PATH_LEN); + if (opj_strcpy_s(indexfilename, indexfilename_size, opj_optarg) != 0) { + return 1; + } /* FIXME ADE INDEX >> */ fprintf(stderr, "[WARNING] Index file generation is currently broken.\n" @@ -1133,7 +1143,9 @@ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *param /* we need to enable indexing */ if (!indexfilename || !*indexfilename) { - strncpy(indexfilename, JPWL_PRIVATEINDEX_NAME, OPJ_PATH_LEN); + if (opj_strcpy_s(indexfilename, indexfilename_size, JPWL_PRIVATEINDEX_NAME) != 0) { + return 1; + } } /* search for different protection methods */ @@ -1622,7 +1634,7 @@ int main(int argc, char **argv) { /* parse input and get user encoding parameters */ parameters.tcp_mct = (char) 255; /* This will be set later according to the input image or the provided option */ - if(parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, &raw_cp, indexfilename) == 1) { + if(parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, &raw_cp, indexfilename, sizeof(indexfilename)) == 1) { return 1; } diff --git a/src/bin/jp2/opj_decompress.c b/src/bin/jp2/opj_decompress.c index c27dc201..3db36ebe 100644 --- a/src/bin/jp2/opj_decompress.c +++ b/src/bin/jp2/opj_decompress.c @@ -75,6 +75,7 @@ #include "color.h" #include "format_defs.h" +#include "opj_string.h" typedef struct dircnt{ /** Buffer for holding images read from Directory*/ @@ -121,6 +122,8 @@ typedef struct opj_decompress_params int decod_format; /** output file format 0: PGX, 1: PxM, 2: BMP */ int cod_format; + /** index file name */ + char indexfilename[OPJ_PATH_LEN]; /** Decoding area left boundary */ OPJ_UINT32 DA_x0; @@ -157,7 +160,7 @@ int get_file_format(const char *filename); char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_decompress_parameters *parameters); static int infile_format(const char *fname); -int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *parameters,img_fol_t *img_fol, char *indexfilename); +int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *parameters,img_fol_t *img_fol); int parse_DA_values( char* inArg, unsigned int *DA_x0, unsigned int *DA_y0, unsigned int *DA_x1, unsigned int *DA_y1); static opj_image_t* convert_gray_to_rgb(opj_image_t* original); @@ -429,7 +432,9 @@ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_decompre parameters->decod_format = infile_format(infilename); if (parameters->decod_format == -1) return 1; - strncpy(parameters->infile, infilename, sizeof(infilename)); + if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile), infilename) != 0) { + return 1; + } /*Set output file*/ strcpy(temp_ofname,strtok(image_filename,".")); @@ -439,7 +444,9 @@ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_decompre } if(img_fol->set_out_format==1){ sprintf(outfilename,"%s/%s.%s",img_fol->imgdirpath,temp_ofname,img_fol->out_format); - strncpy(parameters->outfile, outfilename, sizeof(outfilename)); + if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile), outfilename) != 0) { + return 1; + } } return 0; } @@ -505,7 +512,7 @@ static int infile_format(const char *fname) * Parse the command line */ /* -------------------------------------------------------------------------- */ -int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *parameters,img_fol_t *img_fol, char *indexfilename) { +int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *parameters,img_fol_t *img_fol) { /* parse the command line */ int totlen, c; opj_option_t long_option[]={ @@ -561,7 +568,10 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para infile); return 1; } - strncpy(parameters->infile, infile, sizeof(parameters->infile)-1); + if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile), infile) != 0) { + fprintf(stderr, "[ERROR] Path is too long\n"); + return 1; + } } break; @@ -592,7 +602,10 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outfile); return 1; } - strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1); + if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile), outfile) != 0) { + fprintf(stderr, "[ERROR] Path is too long\n"); + return 1; + } } break; @@ -676,11 +689,14 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para case 'd': /* Input decode ROI */ { - int size_optarg = (int)strlen(opj_optarg) + 1; - char *ROI_values = (char*) malloc((size_t)size_optarg); + size_t size_optarg = (size_t)strlen(opj_optarg) + 1U; + char *ROI_values = (char*) malloc(size_optarg); + if (ROI_values == NULL) { + fprintf(stderr, "[ERROR] Couldn't allocate memory\n"); + return 1; + } ROI_values[0] = '\0'; - strncpy(ROI_values, opj_optarg, strlen(opj_optarg)); - ROI_values[strlen(opj_optarg)] = '\0'; + memcpy(ROI_values, opj_optarg, size_optarg); /*printf("ROI_values = %s [%d / %d]\n", ROI_values, strlen(ROI_values), size_optarg ); */ parse_DA_values( ROI_values, ¶meters->DA_x0, ¶meters->DA_y0, ¶meters->DA_x1, ¶meters->DA_y1); @@ -701,8 +717,10 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para case 'x': /* Creation of index file */ { - char *index = opj_optarg; - strncpy(indexfilename, index, OPJ_PATH_LEN); + if (opj_strcpy_s(parameters->indexfilename, sizeof(parameters->indexfilename), opj_optarg) != 0) { + fprintf(stderr, "[ERROR] Path is too long\n"); + return 1; + } } break; @@ -1167,8 +1185,6 @@ int main(int argc, char **argv) opj_codec_t* l_codec = NULL; /* Handle to a decompressor */ opj_codestream_index_t* cstr_index = NULL; - char indexfilename[OPJ_PATH_LEN]; /* index file name */ - OPJ_INT32 num_images, imageno; img_fol_t img_fol; dircnt_t *dirptr = NULL; @@ -1179,14 +1195,11 @@ int main(int argc, char **argv) /* set decoding parameters to default values */ set_default_parameters(¶meters); - /* FIXME Initialize indexfilename and img_fol */ - *indexfilename = 0; - /* Initialize img_fol */ memset(&img_fol,0,sizeof(img_fol_t)); /* parse input and get user encoding parameters */ - if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) { + if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol) == 1) { destroy_parameters(¶meters); return EXIT_FAILURE; } diff --git a/src/bin/jp2/opj_dump.c b/src/bin/jp2/opj_dump.c index 4005f1c2..562fd5a5 100644 --- a/src/bin/jp2/opj_dump.c +++ b/src/bin/jp2/opj_dump.c @@ -57,6 +57,7 @@ #include "index.h" #include "format_defs.h" +#include "opj_string.h" typedef struct dircnt{ /** Buffer for holding images read from Directory*/ @@ -196,7 +197,9 @@ static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_d if (parameters->decod_format == -1) return 1; sprintf(infilename,"%s/%s",img_fol->imgdirpath,image_filename); - strncpy(parameters->infile, infilename, sizeof(infilename)); + if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile), infilename) != 0) { + return 1; + } /*Set output file*/ strcpy(temp_ofname,strtok(image_filename,".")); @@ -206,7 +209,9 @@ static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_d } if(img_fol->set_out_format==1){ sprintf(outfilename,"%s/%s.%s",img_fol->imgdirpath,temp_ofname,img_fol->out_format); - strncpy(parameters->outfile, outfilename, sizeof(outfilename)); + if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile), outfilename) != 0) { + return 1; + } } return 0; } @@ -303,7 +308,10 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param infile); return 1; } - strncpy(parameters->infile, infile, sizeof(parameters->infile)-1); + if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile), infile) != 0) { + fprintf(stderr, "[ERROR] Path is too long\n"); + return 1; + } } break; @@ -311,8 +319,10 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param case 'o': /* output file */ { - char *outfile = opj_optarg; - strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1); + if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile), opj_optarg) != 0) { + fprintf(stderr, "[ERROR] Path is too long\n"); + return 1; + } } break;