Commit message: Fixed an integral type promotion problem by adding a JAS_CAST.
Modified the jpc_tsfb_synthesize function so that it will be a noop for
an empty sequence (in order to avoid dereferencing a null pointer).
CVE: CVE-2016-10248
CWE: CWE-476
Vulnerability description: The jpc_tsfb_synthesize function in jpc_tsfb.c in JasPer before 1.900.9 allows remote attackers to cause a denial of service (NULL pointer dereference) via vectors involving an empty sequence.

Project: jasper
File: jpc_dec.c

static int jpc_dec_cp_setfromcod(jpc_dec_cp_t *cp, jpc_cod_t *cod)
{
	jpc_dec_ccp_t *ccp;
	int compno;
	cp->flags |= JPC_CSET;
	cp->prgord = cod->prg;
	if (cod->mctrans) {
		cp->mctid = (cod->compparms.qmfbid == JPC_COX_INS) ? (JPC_MCT_ICT) : (JPC_MCT_RCT);
	} else {
		cp->mctid = JPC_MCT_NONE;
	}
	cp->numlyrs = cod->numlyrs;
	cp->csty = cod->csty & (JPC_COD_SOP | JPC_COD_EPH);
	for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
	  ++compno, ++ccp) {
		jpc_dec_cp_setfromcox(cp, ccp, &cod->compparms, 0);
	}
	cp->flags |= JPC_CSET;
	return 0;
}

Project: jasper
File: jpc_dec.c

static int jpc_dec_cp_setfromcox(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
  jpc_coxcp_t *compparms, int flags)
{
	int rlvlno;

	/* Eliminate compiler warnings about unused variables. */
	cp = 0;

	if ((flags & JPC_COC) || !(ccp->flags & JPC_COC)) {
		ccp->numrlvls = compparms->numdlvls + 1;
		ccp->cblkwidthexpn = JPC_COX_GETCBLKSIZEEXPN(
		  compparms->cblkwidthval);
		ccp->cblkheightexpn = JPC_COX_GETCBLKSIZEEXPN(
		  compparms->cblkheightval);
		ccp->qmfbid = compparms->qmfbid;
		ccp->cblkctx = compparms->cblksty;
		ccp->csty = compparms->csty & JPC_COX_PRT;
		for (rlvlno = 0; rlvlno < compparms->numrlvls; ++rlvlno) {
			ccp->prcwidthexpns[rlvlno] =
			  compparms->rlvls[rlvlno].parwidthval;
			ccp->prcheightexpns[rlvlno] =
			  compparms->rlvls[rlvlno].parheightval;
		}
		ccp->flags |= flags | JPC_CSET;
	}
	return 0;
}

Project: jasper
File: jpc_dec.c

static int jpc_dec_cp_setfromrgn(jpc_dec_cp_t *cp, jpc_rgn_t *rgn)
{
	jpc_dec_ccp_t *ccp;
	ccp = &cp->ccps[rgn->compno];
	ccp->roishift = rgn->roishift;
	return 0;
}

Project: jasper
File: jpc_dec.c

static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms)
{
	jpc_coc_t *coc = &ms->parms.coc;
	jpc_dec_tile_t *tile;

	if (JAS_CAST(int, coc->compno) >= dec->numcomps) {
		jas_eprintf("invalid component number in COC marker segment\n");
		return -1;
	}
	switch (dec->state) {
	case JPC_MH:
		jpc_dec_cp_setfromcoc(dec->cp, coc);
		break;
	case JPC_TPH:
		if (!(tile = dec->curtile)) {
			return -1;
		}
		if (tile->partno > 0) {
			return -1;
		}
		jpc_dec_cp_setfromcoc(tile->cp, coc);
		break;
	}
	return 0;
}

Project: jasper
File: jpc_dec.c

static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms)
{
	jpc_dec_tile_t *tile;
	jpc_sot_t *sot = &ms->parms.sot;
	jas_image_cmptparm_t *compinfos;
	jas_image_cmptparm_t *compinfo;
	jpc_dec_cmpt_t *cmpt;
	int cmptno;

	if (dec->state == JPC_MH) {

		if (!(compinfos = jas_alloc2(dec->numcomps,
		  sizeof(jas_image_cmptparm_t)))) {
			abort();
		}
		for (cmptno = 0, cmpt = dec->cmpts, compinfo = compinfos;
		  cmptno < dec->numcomps; ++cmptno, ++cmpt, ++compinfo) {
			compinfo->tlx = 0;
			compinfo->tly = 0;
			compinfo->prec = cmpt->prec;
			compinfo->sgnd = cmpt->sgnd;
			compinfo->width = cmpt->width;
			compinfo->height = cmpt->height;
			compinfo->hstep = cmpt->hstep;
			compinfo->vstep = cmpt->vstep;
		}

		if (!(dec->image = jas_image_create(dec->numcomps, compinfos,
		  JAS_CLRSPC_UNKNOWN))) {
			jas_free(compinfos);
			return -1;
		}
		jas_free(compinfos);

		/* Is the packet header information stored in PPM marker segments in
		  the main header? */
		if (dec->ppmstab) {
			/* Convert the PPM marker segment data into a collection of streams
			  (one stream per tile-part). */
			if (!(dec->pkthdrstreams = jpc_ppmstabtostreams(dec->ppmstab))) {
				abort();
			}
			jpc_ppxstab_destroy(dec->ppmstab);
			dec->ppmstab = 0;
		}
	}

	if (sot->len > 0) {
		dec->curtileendoff = jas_stream_getrwcount(dec->in) - ms->len -
		  4 + sot->len;
	} else {
		dec->curtileendoff = 0;
	}

	if (JAS_CAST(int, sot->tileno) >= dec->numtiles) {
		jas_eprintf("invalid tile number in SOT marker segment\n");
		return -1;
	}
	/* Set the current tile. */
	dec->curtile = &dec->tiles[sot->tileno];
	tile = dec->curtile;
	/* Ensure that this is the expected part number. */
	if (sot->partno != tile->partno) {
		return -1;
	}
	if (tile->numparts > 0 && sot->partno >= tile->numparts) {
		return -1;
	}
	if (!tile->numparts && sot->numparts > 0) {
		tile->numparts = sot->numparts;
	}

	tile->pptstab = 0;

	switch (tile->state) {
	case JPC_TILE_INIT:
		/* This is the first tile-part for this tile. */
		tile->state = JPC_TILE_ACTIVE;
		assert(!tile->cp);
		if (!(tile->cp = jpc_dec_cp_copy(dec->cp))) {
			return -1;
		}
		jpc_dec_cp_resetflags(dec->cp);
		break;
	default:
		if (sot->numparts == sot->partno - 1) {
			tile->state = JPC_TILE_ACTIVELAST;
		}
		break;
	}

	/* Note: We do not increment the expected tile-part number until
	  all processing for this tile-part is complete. */

	/* We should expect to encounter other tile-part header marker
	  segments next. */
	dec->state = JPC_TPH;

	return 0;
}

Project: jasper
File: jpc_dec.c

static int jpc_dec_process_unk(jpc_dec_t *dec, jpc_ms_t *ms)
{
	/* Eliminate compiler warnings about unused variables. */
	dec = 0;

	jas_eprintf("warning: ignoring unknown marker segment\n");
	jpc_ms_dump(ms, stderr);
	return 0;
}

Project: jasper
File: jpc_dec.c

void jpc_streamlist_destroy(jpc_streamlist_t *streamlist)
{
	int streamno;
	if (streamlist->streams) {
		for (streamno = 0; streamno < streamlist->numstreams;
		  ++streamno) {
			jas_stream_close(streamlist->streams[streamno]);
		}
		jas_free(streamlist->streams);
	}
	jas_free(streamlist);
}