Commit message: Made some changes to the I/O stream library for memory streams.
There were a number of potential problems due to the possibility
of integer overflow.
Changed some integral types to the larger types size_t or ssize_t.
For example, the function mem_resize now takes the buffer size parameter
as a size_t.
Added a new function jas_stream_memopen2, which takes a
buffer size specified as a size_t instead of an int.
This can be used in jas_image_cmpt_create to avoid potential
overflow problems.

Added a new function jas_deprecated to warn about reliance on
deprecated library behavior.
CVE: CVE-2015-5203
CWE: CWE-190
Vulnerability description: Double free vulnerability in the jasper_image_stop_load function in JasPer 1.900.17 allows remote attackers to cause a denial of service (crash) via a crafted JPEG 2000 image file.

Project: jasper

static jas_image_cmpt_t *jas_image_cmpt_create(int_fast32_t tlx,
  int_fast32_t tly, int_fast32_t hstep, int_fast32_t vstep,
  int_fast32_t width, int_fast32_t height, uint_fast16_t depth, bool sgnd,
  uint_fast32_t inmem)
{
	jas_image_cmpt_t *cmpt;
	size_t size;

	cmpt = 0;
	if (width < 0 || height < 0 || hstep <= 0 || vstep <= 0) {
		goto error;
	}
	if (!jas_safe_intfast32_add(tlx, width, 0) ||
	  !jas_safe_intfast32_add(tly, height, 0)) {
		goto error;
	}

	if (!(cmpt = jas_malloc(sizeof(jas_image_cmpt_t)))) {
		goto error;
	}

	cmpt->type_ = JAS_IMAGE_CT_UNKNOWN;
	cmpt->tlx_ = tlx;
	cmpt->tly_ = tly;
	cmpt->hstep_ = hstep;
	cmpt->vstep_ = vstep;
	cmpt->width_ = width;
	cmpt->height_ = height;
	cmpt->prec_ = depth;
	cmpt->sgnd_ = sgnd;
	cmpt->stream_ = 0;
	cmpt->cps_ = (depth + 7) / 8;

	if (!jas_safe_size_mul(cmpt->width_, cmpt->height_, &size) ||
 	  !jas_safe_size_mul(size, cmpt->cps_, &size)) {
 		goto error;
 	}
	cmpt->stream_ = (inmem) ? jas_stream_memopen2(0, size) :
 	  jas_stream_tmpfile();
 	if (!cmpt->stream_) {
 		goto error;
	}

	/* Zero the component data.  This isn't necessary, but it is
	convenient for debugging purposes. */
	/* Note: conversion of size - 1 to long can overflow */
	if (jas_stream_seek(cmpt->stream_, size - 1, SEEK_SET) < 0 ||
	  jas_stream_putc(cmpt->stream_, 0) == EOF ||
	  jas_stream_seek(cmpt->stream_, 0, SEEK_SET) < 0) {
		goto error;
	}

	return cmpt;

error:
	if (cmpt) {
		jas_image_cmpt_destroy(cmpt);
	}
	return 0;
}

Project: jasper
File: jas_stream.c

 int jas_stream_gobble(jas_stream_t *stream, int n)
 {
 	int m;
	if (n < 0) {
		jas_deprecated("negative count for jas_stream_gobble");
	}
 	m = n;
 	for (m = n; m > 0; --m) {
 		if (jas_stream_getc(stream) == EOF) {
			return n - m;
		}
	}
	return n;
}

Project: jasper
File: jas_stream.c

 int jas_stream_pad(jas_stream_t *stream, int n, int c)
 {
 	int m;
	if (n < 0) {
		jas_deprecated("negative count for jas_stream_pad");
	}
 	m = n;
 	for (m = n; m > 0; --m) {
 		if (jas_stream_putc(stream, c) == EOF)
			return n - m;
	}
	return n;
}

Project: jasper
File: jas_stream.c

int jas_stream_read(jas_stream_t *stream, void *buf, int cnt)
{
	int n;
 	int c;
 	char *bufptr;
 
	if (cnt < 0) {
		jas_deprecated("negative count for jas_stream_read");
	}

 	bufptr = buf;
 
 	n = 0;
	while (n < cnt) {
		if ((c = jas_stream_getc(stream)) == EOF) {
			return n;
		}
		*bufptr++ = c;
		++n;
	}

	return n;
}

Project: jasper
File: jas_stream.c

int jas_stream_write(jas_stream_t *stream, const void *buf, int cnt)
{
 	int n;
 	const char *bufptr;
 
	if (cnt < 0) {
		jas_deprecated("negative count for jas_stream_write");
	}

 	bufptr = buf;
 
 	n = 0;
	while (n < cnt) {
		if (jas_stream_putc(stream, *bufptr) == EOF) {
			return n;
		}
		++bufptr;
		++n;
	}

	return n;
}

Project: jasper

static int mem_resize(jas_stream_memobj_t *m, int bufsize)
static int mem_resize(jas_stream_memobj_t *m, size_t bufsize)
 {
 	unsigned char *buf;
 
	//assert(bufsize >= 0);

	JAS_DBGLOG(100, ("mem_resize(%p, %zu)\n", m, bufsize));
	if (!bufsize) {
		jas_eprintf(
		  "mem_resize was not really designed to handle a buffer of size 0\n"
		  "This may not work.\n"
		);
	}
 
 	if (!(buf = jas_realloc2(m->buf_, bufsize, sizeof(unsigned char))) &&
 	  bufsize) {
 		JAS_DBGLOG(100, ("mem_resize realloc failed\n"));
		return -1;
	}
	JAS_DBGLOG(100, ("mem_resize realloc succeeded\n"));
	m->buf_ = buf;
	m->bufsize_ = bufsize;
	return 0;
}

Project: jasper
File: jas_stream.c

 static int mem_write(jas_stream_obj_t *obj, char *buf, int cnt)
 {
	size_t n;
 	int ret;
 	jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj;
	size_t newbufsize;
	size_t newpos;
 
 	assert(buf);
 	assert(cnt >= 0);

	JAS_DBGLOG(100, ("mem_write(%p, %p, %d)\n", obj, buf, cnt));
	newpos = m->pos_ + cnt;
 	if (newpos > m->bufsize_ && m->growable_) {
 		newbufsize = m->bufsize_;
 		while (newbufsize < newpos) {
			//newbufsize <<= 1;
			if (!jas_safe_size_mul(newbufsize, 2, &newbufsize)) {
				JAS_DBGLOG(100, ("new buffer size would cause overflow\n"));
				return -1;
			}
 		}
		JAS_DBGLOG(100, ("mem_write resizing from %d to %zu\n", m->bufsize_,
 		  newbufsize));
		assert(newbufsize > 0);
 		if (mem_resize(m, newbufsize)) {
 			return -1;
 		}
	}
	if (m->pos_ > m->len_) {
		/* The current position is beyond the end of the file, so
		  pad the file to the current position with zeros. */
		n = JAS_MIN(m->pos_, m->bufsize_) - m->len_;
		if (n > 0) {
			memset(&m->buf_[m->len_], 0, n);
			m->len_ += n;
		}
		if (m->pos_ != m->len_) {
			/* The buffer is not big enough. */
			return 0;
		}
	}
	n = m->bufsize_ - m->pos_;
	ret = JAS_MIN(n, cnt);
	if (ret > 0) {
		memcpy(&m->buf_[m->pos_], buf, ret);
		m->pos_ += ret;
	}
	if (m->pos_ > m->len_) {
		m->len_ = m->pos_;
	}
	assert(ret == cnt);
	return ret;
}