Fix PNM file reading (#847)

Malformed PNM file could cause a crash in opj_compress.
Checks were added to prevent this.

Fixes #843
Updates #440
This commit is contained in:
Matthieu Darbois 2016-09-22 00:30:34 +02:00 committed by Mathieu Malaterre
parent 7a5fb35b8d
commit f053508f6f
2 changed files with 30 additions and 39 deletions

View File

@ -1327,6 +1327,8 @@ struct pnm_header
};
static char *skip_white(char *s)
{
if (s != NULL)
{
while(*s)
{
@ -1334,6 +1336,7 @@ static char *skip_white(char *s)
if(isspace(*s)) { ++s; continue; }
return s;
}
}
return NULL;
}
@ -1377,7 +1380,7 @@ static char *skip_idf(char *start, char out_idf[256])
static void read_pnm_header(FILE *reader, struct pnm_header *ph)
{
int format, have_wh, end, ttype;
int format, end, ttype;
char idf[256], type[256];
char line[256];
@ -1398,11 +1401,12 @@ static void read_pnm_header(FILE *reader, struct pnm_header *ph)
return;
}
ph->format = format;
ttype = end = have_wh = 0;
ttype = end = 0;
while(fgets(line, 250, reader))
{
char *s;
int allow_null = 0;
if(*line == '#') continue;
@ -1478,36 +1482,25 @@ static void read_pnm_header(FILE *reader, struct pnm_header *ph)
return;
} /* if(format == 7) */
if( !have_wh)
{
/* Here format is in range [1,6] */
if (ph->width == 0) {
s = skip_int(s, &ph->width);
s = skip_int(s, &ph->height);
have_wh = 1;
if(format == 1 || format == 4) break;
if(format == 2 || format == 3 || format == 5 || format == 6)
{
if (skip_int(s, &ph->maxval) != NULL) {
if(ph->maxval > 65535) {
return;
if ((s == NULL) || (*s == 0) || (ph->width < 1)) return;
allow_null = 1;
}
else {
if (ph->height == 0) {
s = skip_int(s, &ph->height);
if ((s == NULL) && allow_null) continue;
if ((s == NULL) || (*s == 0) || (ph->height < 1)) return;
if(format == 1 || format == 4) {
break;
}
allow_null = 1;
}
}
continue;
}
if(format == 2 || format == 3 || format == 5 || format == 6)
{
/* P2, P3, P5, P6: */
/* here, format is in P2, P3, P5, P6 */
s = skip_int(s, &ph->maxval);
if(ph->maxval > 65535) return;
}
if ((s == NULL) && allow_null) continue;
if ((s == NULL) || (*s == 0)) return;
break;
}/* while(fgets( ) */
if(format == 2 || format == 3 || format > 4)
@ -1524,18 +1517,14 @@ static void read_pnm_header(FILE *reader, struct pnm_header *ph)
}
if(ph->depth < 1 || ph->depth > 4) return;
if(ph->width && ph->height && ph->depth && ph->maxval && ttype)
if (ttype)
ph->ok = 1;
}
else
{
if(format != 1 && format != 4)
ph->ok = 1;
if(format == 1 || format == 4)
{
if(ph->width && ph->height && ph->maxval) ph->ok = 1;
}
else
{
if(ph->width && ph->height) ph->ok = 1;
ph->maxval = 255;
}
}

View File

@ -146,6 +146,8 @@ opj_compress -i @INPUT_NR_PATH@/flower-minisblack-11.tif -o @TEMP_PATH@/flower-m
opj_compress -i @INPUT_NR_PATH@/flower-minisblack-13.tif -o @TEMP_PATH@/flower-minisblack-13.tif.jp2
opj_compress -i @INPUT_NR_PATH@/flower-minisblack-15.tif -o @TEMP_PATH@/flower-minisblack-15.tif.jp2
# issue 843 Crash with invalid ppm file
!opj_compress -i @INPUT_NR_PATH@/issue843.ppm -o @TEMP_PATH@/issue843.ppm.jp2
# DECODER TEST SUITE
opj_decompress -i @INPUT_NR_PATH@/Bretagne2.j2k -o @TEMP_PATH@/Bretagne2.j2k.pgx