CVE-2016-9557 (C, published 2017-03-23T18:59Z)
Description: value: Integer overflow in jas_image.c in JasPer before 1.900.25 allows remote attackers to cause a denial of service (application crash) via a crafted file.
Severity: MEDIUM (CVSS v3 base score: 5.5)
Weakness: CWE-190 \u2014 Integer Overflow or Wraparound
The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
Repository: https://github.com/mdadams/jasper
Files changed:
.gitignore
configure.ac
src/appl/imginfo.c
src/libjasper/base/jas_debug.c
src/libjasper/base/jas_icc.c
src/libjasper/base/jas_iccdata.c
src/libjasper/base/jas_image.c
src/libjasper/base/jas_seq.c
src/libjasper/base/jas_stream.c
src/libjasper/base/jas_tmr.c
src/libjasper/bmp/bmp_dec.c
src/libjasper/include/jasper/jas_cm.h
src/libjasper/include/jasper/jas_config.h.in
src/libjasper/include/jasper/jas_config2.h
src/libjasper/include/jasper/jas_debug.h
src/libjasper/include/jasper/jas_fix.h
src/libjasper/include/jasper/jas_getopt.h
src/libjasper/include/jasper/jas_icc.h
src/libjasper/include/jasper/jas_image.h
src/libjasper/include/jasper/jas_init.h
src/libjasper/include/jasper/jas_malloc.h
src/libjasper/include/jasper/jas_math.h
src/libjasper/include/jasper/jas_seq.h
src/libjasper/include/jasper/jas_stream.h
src/libjasper/include/jasper/jas_string.h
src/libjasper/include/jasper/jas_tmr.h
src/libjasper/include/jasper/jas_tvp.h
src/libjasper/include/jasper/jas_types.h
src/libjasper/include/jasper/jas_version.h
src/libjasper/include/jasper/jasper.h
src/libjasper/jp2/jp2_dec.c
src/libjasper/jpc/jpc_cs.c
src/libjasper/jpc/jpc_cs.h
src/libjasper/jpc/jpc_dec.c
src/libjasper/jpc/jpc_dec.h
src/libjasper/jpc/jpc_enc.c
src/libjasper/jpc/jpc_mqdec.h
src/libjasper/jpg/jpg_dec.c
src/libjasper/jpg/jpg_val.c
src/libjasper/mif/mif_cod.c
src/libjasper/pgx/pgx_dec.c
src/libjasper/pnm/pnm_dec.c
src/libjasper/ras/ras_dec.c
test/bin/run_test_1
Commit message: The generation of the configuration file jas_config.h has been completely
reworked in order to avoid pollution of the global namespace.

Some problematic types like uchar, ulong, and friends have been replaced
with names with a jas_ prefix.

An option max_samples has been added to the BMP and JPEG decoders to
restrict the maximum size of image that they can decode.  This change
was made as a (possibly temporary) fix to address security concerns.
A max_samples command-line option has also been added to imginfo.

Whether an image component (for jas_image_t) is stored in memory or on
disk is now based on the component size (rather than the image size).

Some debug log message were added.

Some new integer overflow checks were added.

Some new safe integer add/multiply functions were added.

More pre-C99 cruft was removed.  JasPer has numerous "hacks" to
handle pre-C99 compilers.  JasPer now assumes C99 support.  So, this
pre-C99 cruft is unnecessary and can be removed.

The regression jasper-doublefree-mem_close.jpg has been re-enabled.
Theoretically, it should work more predictably now.


Vulnerable code:
/src/libjasper/include/jasper/jas_config.h.in
/src/libjasper/include/jasper/jas_config.h.in~
#if defined(__GNUC__) && !defined(__clang__)
#define JAS_ATTRIBUTE_DISABLE_USAN \
  __attribute__((no_sanitize_undefined))
#elif defined(__clang__)
#define JAS_ATTRIBUTE_DISABLE_USAN \
  __attribute__((no_sanitize("undefined")))
#else
#define JAS_ATTRIBUTE_DISABLE_USAN
#endif

#include <jasper/jas_config2.h>
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h limits.h unistd.h stdint.h stdbool.h io.h windows.h sys/types.h sys/time.h stdlib.h stddef.h)
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_CHECK_TYPE(uchar, unsigned char)
AC_CHECK_TYPE(ushort, unsigned short)
AC_CHECK_TYPE(uint, unsigned int)
AC_CHECK_TYPE(ulong, unsigned long)
AC_CHECK_TYPE(longlong, long long)
AC_CHECK_TYPE(ulonglong, unsigned long long)
AC_CHECK_TYPE(ssize_t, int)
AC_FUNC_VPRINTF
# Extra stuff for research purposes.
AC_ARG_ENABLE(special0,
[  --enable-special0    enable something],
[
case "${enableval}" in
yes)
	if test "$GCC" = yes; then
		CFLAGS="-g -O0"
	fi
	;;
no)
	;;
*)
	AC_MSG_ERROR(bad value ${enableval} for --enable-special0)
	;;
esac
], [])

AC_CONFIG_HEADERS([src/libjasper/include/jasper/jas_config.h])
	if (!(image = jas_image_decode(instream, fmtid, 0))) {
	if (!(fmtname = jas_image_fmttostr(fmtid))) {
		abort();
	}
	printf("%s %d %d %d %d %ld\n", fmtname, numcmpts, width, height, depth, (long) jas_image_rawsize(image));
	uchar *dp;
static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val);
static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val);
static int jas_iccputsint(jas_stream_t *out, int n, longlong val);
static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val)
	ulonglong v;
	ulonglong tmp;
	ulonglong tmp;
	*val = (tmp & 0x80000000) ? (-JAS_CAST(longlong, (((~tmp) &
	  0x7fffffff) + 1))) : JAS_CAST(longlong, tmp);
	ulonglong tmp;
	ulonglong tmp;
static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val)
static int jas_iccputsint(jas_stream_t *out, int n, longlong val)
	ulonglong tmp;
jas_iccprof_t *jas_iccprof_createfrombuf(uchar *buf, int len)
uchar jas_iccprofdata_srgb[] =
uchar jas_iccprofdata_sgray[] = {
	uint_fast32_t rawsize;
		return 0;
	image->inmem_ = true;
		jas_image_destroy(image);
		return 0;
			jas_image_destroy(image);
			return 0;
	image->inmem_ = true;
	if (!jas_safe_size_mul(cmpt->width_, cmpt->height_, &size) ||
	  !jas_safe_size_mul(size, cmpt->cps_, &size)) {
static inline long decode_twos_comp(ulong c, int prec)
static inline ulong encode_twos_comp(long n, int prec)
	ulong result;
	ulong tmp;
jas_matrix_t *jas_seq2d_create(int xstart, int ystart, int xend, int yend)
jas_matrix_t *jas_matrix_create(int numrows, int numcols)
	int i;
	int i;
	int j;
	int i;
	int j;
void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, int xstart,
  int ystart, int xend, int yend)
void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, int r0,
  int c0, int r1, int c1)
	int i;
	int i;
	int j;
	int i;
	int j;
	int rowstep;
	int i;
	int j;
	int rowstep;
	int i;
	int j;
	int rowstep;
	int i;
	int j;
	int rowstep;
int jas_matrix_resize(jas_matrix_t *matrix, int numrows, int numcols)
	int size;
	int i;
	int i;
	int j;
	int rowstep;
	int i;
	int j;
	int numrows;
	int numcols;
	int xoff;
	int yoff;

	if (fscanf(in, "%d %d", &xoff, &yoff) != 2)
	if (fscanf(in, "%d %d", &numcols, &numrows) != 2)
	if (!(matrix = jas_seq2d_create(xoff, yoff, xoff + numcols, yoff + numrows)))
	int i;
	int j;
#if defined(HAVE_FCNTL_H)
#if defined(HAVE_UNISTD_H)
#if defined(WIN32) || defined(HAVE_IO_H)
			stream->bufbase_ = JAS_CAST(uchar *, buf);
#if defined(HAVE_GETTIMEOFDAY)
#elif defined(HAVE_GETRUSAGE)
	if (optstr) {
		jas_eprintf("warning: ignoring BMP decoder options\n");
		//return 0;
		//return 0;
		//bmp_info_destroy(info);
		//return 0;
		//return 0;
			//bmp_info_destroy(info);
			//return 0;
		//bmp_info_destroy(info);
		//return 0;
		//bmp_info_destroy(info);
		//jas_image_destroy(image);
		//return 0;
	uchar buf[2];
#define	uchar		unsigned char
#define	ushort		unsigned short
#define	uint		unsigned int
#define	ulong		unsigned long
#undef longlong
#define	longlong	long long
#undef ulonglong
#define	ulonglong	unsigned long long
/*#define	ssize_t		int*/

#define	HAVE_LIMITS_H		1
#define	HAVE_STDLIB_H		1
#define	HAVE_STDDEF_H		1
#include <jasper/jas_config.h>
#include <jasper/jas_config.h>
	uchar *ucdata; /* Unicode localizable description */
	uchar macdata[69]; /* Localizable Macintosh description */
extern uchar jas_iccprofdata_srgb[];
extern uchar jas_iccprofdata_sgray[];
jas_iccprof_t *jas_iccprof_createfrombuf(uchar *buf, int len);
	bool inmem_;
	int_fast32_t xstart_;
	int_fast32_t ystart_;
	int_fast32_t xend_;
	int_fast32_t yend_;
	int_fast32_t numrows_;
	int_fast32_t numcols_;
	(((matrix)->numrows_ > 1) ? jas_matrix_getref(matrix, i, 0) : jas_matrix_getref(matrix, 0, i))
jas_matrix_t *jas_matrix_create(int numrows, int numcols);
int jas_matrix_resize(jas_matrix_t *matrix, int numrows, int numcols);
void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, int r0,
  int c0, int r1, int c1);
jas_matrix_t *jas_seq2d_create(int xstart, int ystart, int xend, int yend);
void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, int xstart,
  int ystart, int xend, int yend);
#if defined(HAVE_FCNTL_H)
#if defined(HAVE_UNISTD_H)
	uchar *bufbase_;
	uchar *bufstart_;
	uchar *ptr_;
	uchar tinybuf_[JAS_STREAM_MAXPUTBACK + 1];
	uchar *buf_;
	  jas_stream_flushbuf((stream), (uchar)(c)) : \
#include<time.h>
#if defined(HAVE_SYS_TIME_H)
#if defined(HAVE_GETTIMEOFDAY)
#elif defined(HAVE_GETRUSAGE)
#if defined(WIN32) || defined(HAVE_WINDOWS_H)
#undef longlong
#define	longlong	INT64
#undef ulonglong
#define	ulonglong	UINT64
#if defined(HAVE_SYS_TYPES_H)
/* Hopefully, these macro definitions will fix more problems than they cause. */
#if !defined(uchar)
#define uchar unsigned char
#endif
#if !defined(ushort)
#define ushort unsigned short
#endif
#if !defined(uint)
#define uint unsigned int
#endif
#if !defined(ulong)
#define ulong unsigned long
#endif
#if !defined(longlong)
#define longlong long long
#endif
#if !defined(ulonglong)
#define ulonglong unsigned long long
#endif
	if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(uint,
	for (i = 1; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) {
		if (dec->bpcc->data.bpcc.numcmpts != JAS_CAST(uint, jas_image_numcmpts(
			for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image));
	  JAS_CAST(uint, jas_image_numcmpts(dec->image));
			if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(uint,
	for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) {
		if (JAS_CAST(ulong, jas_stream_tell(tmpstream)) != ms->len) {
		if (JAS_CAST(uint, jas_stream_read(in, ppm->data, ppm->len)) != ppm->len) {
	if (JAS_CAST(uint, jas_stream_write(out, (char *) ppm->data, ppm->len)) != ppm->len) {
	uchar *data;
	uchar *data;
	uchar *data;
	uchar *dataptr;
	uchar *data;
	if (!(com->data = JAS_CAST(uchar *, jas_strdup(buf)))) {
	uchar inbuffer;
*
typedef struct {
	size_t max_size;
} jpg_dec_importopts_t;

typedef enum {
	OPT_MAXSIZE,
} optid_t;

	{OPT_MAXSIZE, "max_size"},
	opts->max_size = 0;
			opts->max_size = atoi(jas_tvparser_getval(tvp));
	size_t size;
	if (opts.max_size) {
		if (!jas_safe_size_mul(cinfo.output_width, cinfo.output_height,
		  &size) ||
		  !jas_safe_size_mul(size, cinfo.output_components, &size)) {
			goto error;
		}
		if (size > opts.max_size) {
			jas_eprintf("image is too large\n");
			goto error;
		}
	}

	uchar buf[JPG_MAGICLEN];
	uchar buf[MIF_MAGICLEN];
	uchar magicbuf[MIF_MAGICLEN];
	uchar buf[PGX_MAGICLEN];
	uchar buf[2];
	uchar buf[2];
	uchar buf[RAS_MAGICLEN];
	2_crashes.bmp|jasper-doublefree-mem_close.jpg)
	ASAN_OPTIONS="${special_asan_options[*]}" "$imginfo" < "$in_file"

Fixed code:
/src/libjasper/include/jasper/jas_pconf.h
/src/libjasper/include/jasper/jas_pconf.h.in
/src/libjasper/include/jasper/jas_pconf.h.in~
#include <jasper/jas_pconf2.h>
dnl AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h io.h unistd.h windows.h sys/time.h sys/types.h)

# Surely, there must be a better way to do this, but
# let's just get something working for now.

if test $ac_cv_header_fcntl_h = yes; then
	AC_SUBST([JAS_HAVE_FCNTL_H], ["#define JAS_HAVE_FCNTL_H 1"])
else
	AC_SUBST([JAS_HAVE_FCNTL_H], ["#undef JAS_HAVE_FCNTL_H"])
fi

if test $ac_cv_header_io_h = yes; then
	AC_SUBST([JAS_HAVE_IO_H], ["#define JAS_HAVE_IO_H 1"])
else
	AC_SUBST([JAS_HAVE_IO_H], ["#undef JAS_HAVE_IO_H"])
fi

if test $ac_cv_header_unistd_h = yes; then
	AC_SUBST([JAS_HAVE_UNISTD_H], ["#define JAS_HAVE_UNISTD_H 1"])
else
	AC_SUBST([JAS_HAVE_UNISTD_H], ["#undef JAS_HAVE_UNISTD_H"])
fi

if test $ac_cv_header_windows_h = yes; then
	AC_SUBST([JAS_HAVE_WINDOWS_H], ["#define JAS_HAVE_WINDOWS_H 1"])
else
	AC_SUBST([JAS_HAVE_WINDOWS_H], ["#undef JAS_HAVE_WINDOWS_H"])
fi

if test $ac_cv_header_sys_time_h = yes; then
	AC_SUBST([JAS_HAVE_SYS_TIME_H], ["#define JAS_HAVE_SYS_TIME_H 1"])
else
	AC_SUBST([JAS_HAVE_SYS_TIME_H], ["#undef JAS_HAVE_SYS_TIME_H"])
fi

if test $ac_cv_header_sys_types_h = yes; then
	AC_SUBST([JAS_HAVE_SYS_TYPES_H], ["#define JAS_HAVE_SYS_TYPES_H 1"])
else
	AC_SUBST([JAS_HAVE_SYS_TYPES_H], ["#undef JAS_HAVE_SYS_TYPES_H"])
fi
dnl AC_C_CONST
dnl AC_C_INLINE
dnl AC_TYPE_SIZE_T
dnl AC_CHECK_TYPE(uchar, unsigned char)
dnl AC_CHECK_TYPE(ushort, unsigned short)
dnl AC_CHECK_TYPE(uint, unsigned int)
dnl AC_CHECK_TYPE(ulong, unsigned long)
dnl AC_CHECK_TYPE(longlong, long long)
dnl AC_CHECK_TYPE(ulonglong, unsigned long long)
dnl AC_CHECK_TYPE(ssize_t, int)
if test $ac_cv_func_gettimeofday = yes; then
	AC_SUBST([JAS_HAVE_GETTIMEOFDAY], ["#define JAS_HAVE_GETTIMEOFDAY 1"])
else
	AC_SUBST([JAS_HAVE_GETTIMEOFDAY], ["#undef JAS_HAVE_GETTIMEOFDAY"])
fi

if test $ac_cv_func_getrusage = yes; then
	AC_SUBST([JAS_HAVE_GETRUSAGE], ["#define JAS_HAVE_GETRUSAGE 1"])
else
	AC_SUBST([JAS_HAVE_GETRUSAGE], ["#undef JAS_HAVE_GETRUSAGE"])
fi

dnl AC_FUNC_VPRINTF
# Extra stuff
# The private header file generated by AC_CONFIG_HEADERS is not
# currently used.  This just causes less verbose command lines
# when make is run.
AC_CONFIG_HEADERS([src/libjasper/include/jasper/jas_pconf.h])
src/libjasper/include/jasper/jas_config.h
	OPT_MAXSAMPLES,
	{OPT_MAXSAMPLES, "max-samples", JAS_OPT_HASARG},
	size_t max_samples;
	char optstr[32];
	max_samples = 64 * JAS_MEBI;
		case OPT_MAXSAMPLES:
			max_samples = strtoull(jas_optarg, 0, 10);
			break;
	snprintf(optstr, sizeof(optstr), "max_samples=%-zu", max_samples);

	if (!(image = jas_image_decode(instream, fmtid, optstr))) {
	if (!(fmtname = jas_image_fmttostr(fmtid))) {
		jas_eprintf("format name lookup failed\n");
		return EXIT_FAILURE;
	}

	printf("%s %d %d %d %d %ld\n", fmtname, numcmpts, width, height, depth,
	  JAS_CAST(long, jas_image_rawsize(image)));
	jas_uchar *dp;
static int jas_iccgetuint(jas_stream_t *in, int n, jas_ulonglong *val);
static int jas_iccputuint(jas_stream_t *out, int n, jas_ulonglong val);
static int jas_iccputsint(jas_stream_t *out, int n, jas_longlong val);
static int jas_iccgetuint(jas_stream_t *in, int n, jas_ulonglong *val)
	jas_ulonglong v;
	jas_ulonglong tmp;
	jas_ulonglong tmp;
	*val = (tmp & 0x80000000) ? (-JAS_CAST(jas_longlong, (((~tmp) &
	  0x7fffffff) + 1))) : JAS_CAST(jas_longlong, tmp);
	jas_ulonglong tmp;
	jas_ulonglong tmp;
static int jas_iccputuint(jas_stream_t *out, int n, jas_ulonglong val)
static int jas_iccputsint(jas_stream_t *out, int n, jas_longlong val)
	jas_ulonglong tmp;
jas_iccprof_t *jas_iccprof_createfrombuf(jas_uchar *buf, int len)
jas_uchar jas_iccprofdata_srgb[] =
jas_uchar jas_iccprofdata_sgray[] = {
	size_t rawsize;
	image = 0;

	JAS_DBGLOG(100, ("jas_image_create(%d, %p, %d)\n", numcmpts, cmptparms,
	  clrspc));

		goto error;
//	image->inmem_ = true;
		goto error;
#if 0
#endif
		if (!jas_safe_size_mul3(cmptparm->width, cmptparm->height,
		  (cmptparm->prec + 7), &rawsize)) {
			goto error;
		}
		rawsize /= 8;
		inmem = (rawsize < JAS_IMAGE_INMEMTHRESH);
			goto error;

error:
	if (image) {
		jas_image_destroy(image);
	}
	return 0;
//	image->inmem_ = true;
	JAS_DBGLOG(100, (
	  "jas_image_cmpt_create(%ld, %ld, %ld, %ld, %ld, %ld, %d, %d, %d)\n",
	  JAS_CAST(long, tlx),
	  JAS_CAST(long, tly),
	  JAS_CAST(long, hstep),
	  JAS_CAST(long, vstep),
	  JAS_CAST(long, width),
	  JAS_CAST(long, height),
	  JAS_CAST(int, depth),
	  sgnd,
	  inmem
	  ));

	if (!jas_safe_intfast32_mul3(width, height, depth, 0)) {
		goto error;
	}
	if (!jas_safe_size_mul3(cmpt->width_, cmpt->height_, cmpt->cps_, &size)) {
static inline long decode_twos_comp(jas_ulong c, int prec)
static inline jas_ulong encode_twos_comp(long n, int prec)
	jas_ulong result;
	jas_ulong tmp;
jas_matrix_t *jas_seq2d_create(jas_matind_t xstart, jas_matind_t ystart,
  jas_matind_t xend, jas_matind_t yend)
jas_matrix_t *jas_matrix_create(jas_matind_t numrows, jas_matind_t numcols)
	jas_matind_t i;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t i;
	jas_matind_t j;
void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, jas_matind_t xstart,
  jas_matind_t ystart, jas_matind_t xend, jas_matind_t yend)
void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1,
  jas_matind_t r0, jas_matind_t c0, jas_matind_t r1, jas_matind_t c1)
	jas_matind_t i;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t rowstep;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t rowstep;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t rowstep;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t rowstep;
int jas_matrix_resize(jas_matrix_t *matrix, jas_matind_t numrows,
  jas_matind_t numcols)
	jas_matind_t size;
	jas_matind_t i;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t rowstep;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t numrows;
	jas_matind_t numcols;
	jas_matind_t xoff;
	jas_matind_t yoff;
	long tmp_xoff;
	long tmp_yoff;
	long tmp_numrows;
	long tmp_numcols;

	if (fscanf(in, "%ld %ld", &tmp_xoff, &tmp_yoff) != 2) {
	}
	xoff = tmp_xoff;
	yoff = tmp_yoff;
	if (fscanf(in, "%ld %ld", &tmp_numcols, &tmp_numrows) != 2) {
	}
	numrows = tmp_numrows;
	numcols = tmp_numcols;
	if (!(matrix = jas_seq2d_create(xoff, yoff, xoff + numcols,
	  yoff + numrows))) {
	}
	jas_matind_t i;
	jas_matind_t j;
/* The configuration header file should be included first. */
#include "jasper/jas_config.h"

#if defined(JAS_HAVE_FCNTL_H)
#if defined(JAS_HAVE_UNISTD_H)
#if defined(WIN32) || defined(JAS_HAVE_IO_H)
			stream->bufbase_ = JAS_CAST(jas_uchar *, buf);
/* The configuration header file should be included first. */
#include "jasper/jas_config.h"

#if defined(JAS_HAVE_GETTIMEOFDAY)
#elif defined(JAS_HAVE_GETRUSAGE)
#include "jasper/jas_tvp.h"
/******************************************************************************\
* Local types.
\******************************************************************************/

typedef struct {
	size_t max_samples;
} bmp_dec_importopts_t;

typedef enum {
	OPT_MAXSIZE,
} optid_t;

/******************************************************************************\
* Option parsing.
\******************************************************************************/

static jas_taginfo_t decopts[] = {
	{OPT_MAXSIZE, "max_samples"},
	{-1, 0}
};

static int bmp_dec_parseopts(char *optstr, bmp_dec_importopts_t *opts)
{
	jas_tvparser_t *tvp;

	opts->max_samples = 128 * JAS_MEBI;

	if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) {
		return -1;
	}

	while (!jas_tvparser_next(tvp)) {
		switch (jas_taginfo_nonull(jas_taginfos_lookup(decopts,
		  jas_tvparser_gettag(tvp)))->id) {
		case OPT_MAXSIZE:
			opts->max_samples = atoi(jas_tvparser_getval(tvp));
			break;
		default:
			jas_eprintf("warning: ignoring invalid option %s\n",
			  jas_tvparser_gettag(tvp));
			break;
		}
	}

	jas_tvparser_destroy(tvp);

	return 0;
}

	bmp_dec_importopts_t opts;
	size_t num_samples;
	if (bmp_dec_parseopts(optstr, &opts)) {
		goto error;
	if (!jas_safe_size_mul3(info->width, info->height, info->numplanes,
	  &num_samples)) {
		jas_eprintf("image size too large\n");
		goto error;
	}

	if (opts.max_samples > 0 && num_samples > opts.max_samples) {
		jas_eprintf("maximum number of pixels exceeded (%zu)\n",
		  opts.max_samples);
		goto error;
	}

	jas_uchar buf[2];
/* The configuration header file should be included first. */

#ifndef JAS_CONFIG_H
#define JAS_CONFIG_H

/* This preprocessor symbol identifies the version of JasPer. */
#define	JAS_VERSION "@JAS_VERSION@"

@JAS_HAVE_FCNTL_H@
@JAS_HAVE_IO_H@
@JAS_HAVE_UNISTD_H@
@JAS_HAVE_WINDOWS_H@
@JAS_HAVE_SYS_TIME_H@
@JAS_HAVE_SYS_TYPES_H@

@JAS_HAVE_GETTIMEOFDAY@
@JAS_HAVE_GETRUSAGE@

#if defined(__GNUC__) && !defined(__clang__)
#define JAS_ATTRIBUTE_DISABLE_USAN \
  __attribute__((no_sanitize_undefined))
#elif defined(__clang__)
#define JAS_ATTRIBUTE_DISABLE_USAN \
  __attribute__((no_sanitize("undefined")))
#else
#define JAS_ATTRIBUTE_DISABLE_USAN
#endif

#endif
/* The configuration header file should be included first. */
#include <jasper/jas_config.h>

/* The configuration header file should be included first. */
#include <jasper/jas_config.h>

/* The configuration header file should be included first. */
/* The configuration header file should be included first. */

	jas_uchar *ucdata; /* Unicode localizable description */
	jas_uchar macdata[69]; /* Localizable Macintosh description */
extern jas_uchar jas_iccprofdata_srgb[];
extern jas_uchar jas_iccprofdata_sgray[];
jas_iccprof_t *jas_iccprof_createfrombuf(jas_uchar *buf, int len);
/* The configuration header file should be included first. */

//	bool inmem_;
/* The configuration header file should be included first. */
/* The configuration header file should be included first. */
/* The configuration header file should be included first. */

#define JAS_KIBI	JAS_CAST(size_t, 1024)
#define JAS_MEBI	(JAS_KIBI * JAS_KIBI)

inline static bool jas_safe_size_mul3(size_t a, size_t b, size_t c,
  size_t *result)
{
	size_t tmp;
	if (!jas_safe_size_mul(a, b, &tmp) ||
	  !jas_safe_size_mul(tmp, c, &tmp)) {
		return false;
	}
	if (result) {
		*result = tmp;
	}
	return true;
}

/* Compute the sum of two size_t integer with overflow checking. */
inline static bool jas_safe_intfast32_mul(int_fast32_t x, int_fast32_t y,
  int_fast32_t *result)
{
	if (x > 0) {
		/* x is positive */
		if (y > 0) {
			/* x and y are positive */
			if (x > INT_FAST32_MAX / y) {
				return false;
			}
		} else {
			/* x positive, y nonpositive */
			if (y < INT_FAST32_MIN / x) {
				return false;
			}
		}
	} else {
		/* x is nonpositive */
		if (y > 0) {
			/* x is nonpositive, y is positive */
			if (x < INT_FAST32_MIN / y) {
				return false;
			}
		} else { /* x and y are nonpositive */
			if (x != 0 && y < INT_FAST32_MAX / x) {
				return false;
			}
		}
	}

	if (result) {
		*result = x * y;
	}
	return true;
}

inline static bool jas_safe_intfast32_mul3(int_fast32_t a, int_fast32_t b,
  int_fast32_t c, int_fast32_t *result)
{
	int_fast32_t tmp;
	if (!jas_safe_intfast32_mul(a, b, &tmp) ||
	  !jas_safe_intfast32_mul(tmp, c, &tmp)) {
		return false;
	}
	if (result) {
		*result = tmp;
	}
	return true;
}

/* The configuration header file should be included first. */
typedef int_fast32_t jas_matind_t;

	jas_matind_t xstart_;
	jas_matind_t ystart_;
	jas_matind_t xend_;
	jas_matind_t yend_;
	jas_matind_t numrows_;
	jas_matind_t numcols_;
	(((matrix)->numrows_ > 1) ? jas_matrix_getref(matrix, i, 0) : \
	  jas_matrix_getref(matrix, 0, i))
jas_matrix_t *jas_matrix_create(jas_matind_t numrows, jas_matind_t numcols);
int jas_matrix_resize(jas_matrix_t *matrix, jas_matind_t numrows, jas_matind_t numcols);
void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, jas_matind_t r0,
  jas_matind_t c0, jas_matind_t r1, jas_matind_t c1);
jas_matrix_t *jas_seq2d_create(jas_matind_t xstart, jas_matind_t ystart,
  jas_matind_t xend, jas_matind_t yend);
void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, jas_matind_t xstart,
  jas_matind_t ystart, jas_matind_t xend, jas_matind_t yend);
/* The configuration header file should be included first. */
#if defined(JAS_HAVE_FCNTL_H)
#if defined(JAS_HAVE_UNISTD_H)
	jas_uchar *bufbase_;
	jas_uchar *bufstart_;
	jas_uchar *ptr_;
	jas_uchar tinybuf_[JAS_STREAM_MAXPUTBACK + 1];
	jas_uchar *buf_;
	  jas_stream_flushbuf((stream), (jas_uchar)(c)) : \
/* The configuration header file should be included first. */

/* The configuration header file should be included first. */

#include<time.h>
#if defined(JAS_HAVE_SYS_TIME_H)
#if defined(JAS_HAVE_GETTIMEOFDAY)
#elif defined(JAS_HAVE_GETRUSAGE)
/* The configuration header file should be included first. */
/* The configuration header file should be included first. */
#if defined(WIN32) || defined(JAS_HAVE_WINDOWS_H)
// THIS SHOULD NO LONGER BE NEEDED SINCE MSVC SUPPORTS LONG LONG.
//#undef longlong
//#define	longlong	INT64
//#undef ulonglong
//#define	ulonglong	UINT64
#if defined(JAS_HAVE_SYS_TYPES_H)
#define jas_uchar unsigned char
#define jas_uint unsigned int
#define jas_ulong unsigned long
#define jas_longlong long long
#define jas_ulonglong unsigned long long
/* The configuration header file should be included first. */
/* The configuration header file should be included first. */

#include "jasper/jas_types.h"
	if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(jas_uint,
	for (i = 1; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); ++i) {
		if (dec->bpcc->data.bpcc.numcmpts != JAS_CAST(jas_uint, jas_image_numcmpts(
			for (i = 0; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image));
	  JAS_CAST(jas_uint, jas_image_numcmpts(dec->image));
			if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(jas_uint,
	for (i = 0; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); ++i) {
		if (JAS_CAST(jas_ulong, jas_stream_tell(tmpstream)) != ms->len) {
		if (JAS_CAST(jas_uint, jas_stream_read(in, ppm->data, ppm->len)) != ppm->len) {
	if (JAS_CAST(jas_uint, jas_stream_write(out, (char *) ppm->data, ppm->len)) != ppm->len) {
	jas_uchar *data;
	jas_uchar *data;
	jas_uchar *data;
	jas_uchar *dataptr;
	jas_uchar *data;
	if (!(com->data = JAS_CAST(jas_uchar *, jas_strdup(buf)))) {
	jas_uchar inbuffer;
typedef struct {
	size_t max_samples;
} jpg_dec_importopts_t;

typedef enum {
	OPT_MAXSIZE,
} optid_t;

* Option parsing.
	{OPT_MAXSIZE, "max_samples"},
	opts->max_samples = 64 * JAS_MEBI;
			opts->max_samples = atoi(jas_tvparser_getval(tvp));
	size_t num_samples;

	JAS_DBGLOG(100, ("jpg_decode(%p, \"%s\")\n", in, optstr));
	if (opts.max_samples > 0) {
		if (!jas_safe_size_mul3(cinfo.image_width, cinfo.image_height,
		  cinfo.num_components, &num_samples)) {
			goto error;
		}
		if (num_samples > opts.max_samples) {
			jas_eprintf("image is too large (%zu > %zu)\n", num_samples,
			  opts.max_samples);
			goto error;
		}
	}

	jas_uchar buf[JPG_MAGICLEN];
	jas_uchar buf[MIF_MAGICLEN];
	jas_uchar magicbuf[MIF_MAGICLEN];
	jas_uchar buf[PGX_MAGICLEN];
	jas_uchar buf[2];
	jas_uchar buf[2];
	jas_uchar buf[RAS_MAGICLEN];
	2_crashes.bmp)
		#jasper-doublefree-mem_close.jpg
		# Thie file 2_crashes.bmp must be skipped since it will try
		# to allocate a huge palette which can cause an ASAN failure.
	imginfo_opts=()
	imginfo_opts+=(--max-samples 100000000)
	ASAN_OPTIONS="${special_asan_options[*]}" \
	  "$imginfo" "${imginfo_opts[@]}" < "$in_file"