Commit message: Added range check on XRsiz and YRsiz fields of SIZ marker segment.
CVE: CVE-2016-8692
CWE: CWE-369
Vulnerability description: The jpc_dec_process_siz function in libjasper/jpc/jpc_dec.c in JasPer before 1.900.4 allows remote attackers to cause a denial of service (divide-by-zero error and application crash) via a crafted YRsiz value in a BMP image to the imginfo command.

Project: jasper
File: jpc_cs.c

static int jpc_coc_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_coc_t *coc = &ms->parms.coc;
	fprintf(out, "compno = %d; csty = 0x%02x; numdlvls = %d;\n",
	  coc->compno, coc->compparms.csty, coc->compparms.numdlvls);
	fprintf(out, "cblkwidthval = %d; cblkheightval = %d; "
	  "cblksty = 0x%02x; qmfbid = %d;\n", coc->compparms.cblkwidthval,
	  coc->compparms.cblkheightval, coc->compparms.cblksty, coc->compparms.qmfbid);
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_cod_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_cod_t *cod = &ms->parms.cod;
	if (jpc_getuint8(in, &cod->csty)) {
		return -1;
	}
	if (jpc_getuint8(in, &cod->prg) ||
	  jpc_getuint16(in, &cod->numlyrs) ||
	  jpc_getuint8(in, &cod->mctrans)) {
		return -1;
	}
	if (jpc_cox_getcompparms(ms, cstate, in,
	  (cod->csty & JPC_COX_PRT) != 0, &cod->compparms)) {
		return -1;
	}
	if (jas_stream_eof(in)) {
		jpc_cod_destroyparms(ms);
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_cox_getcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate,
  jas_stream_t *in, int prtflag, jpc_coxcp_t *compparms)
{
	uint_fast8_t tmp;
	int i;

	/* Eliminate compiler warning about unused variables. */
	ms = 0;
	cstate = 0;

	if (jpc_getuint8(in, &compparms->numdlvls) ||
	  jpc_getuint8(in, &compparms->cblkwidthval) ||
	  jpc_getuint8(in, &compparms->cblkheightval) ||
	  jpc_getuint8(in, &compparms->cblksty) ||
	  jpc_getuint8(in, &compparms->qmfbid)) {
		return -1;
	}
	compparms->numrlvls = compparms->numdlvls + 1;
	if (prtflag) {
		for (i = 0; i < compparms->numrlvls; ++i) {
			if (jpc_getuint8(in, &tmp)) {
				jpc_cox_destroycompparms(compparms);
				return -1;
			}
			compparms->rlvls[i].parwidthval = tmp & 0xf;
			compparms->rlvls[i].parheightval = (tmp >> 4) & 0xf;
		}
/* Sigh.  This bit should be in the same field in both COC and COD mrk segs. */
compparms->csty |= JPC_COX_PRT;
	} else {
	}
	if (jas_stream_eof(in)) {
		jpc_cox_destroycompparms(compparms);
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_crg_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_crg_t *crg = &ms->parms.crg;
	jpc_crgcomp_t *comp;
	uint_fast16_t compno;
	crg->numcomps = cstate->numcomps;
	if (!(crg->comps = jas_alloc2(cstate->numcomps, sizeof(uint_fast16_t)))) {
		return -1;
	}
	for (compno = 0, comp = crg->comps; compno < cstate->numcomps;
	  ++compno, ++comp) {
		if (jpc_getuint16(in, &comp->hoff) ||
		  jpc_getuint16(in, &comp->voff)) {
			jpc_crg_destroyparms(ms);
			return -1;
		}
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

void jpc_ms_dump(jpc_ms_t *ms, FILE *out)
{
	jpc_mstabent_t *mstabent;
	mstabent = jpc_mstab_lookup(ms->id);
	fprintf(out, "type = 0x%04x (%s);", ms->id, mstabent->name);
	if (JPC_MS_HASPARMS(ms->id)) {
		fprintf(out, " len = %d;", ms->len + 2);
		if (ms->ops->dumpparms) {
			(*ms->ops->dumpparms)(ms, out);
		} else {
			fprintf(out, "\n");
		}
	} else {
		fprintf(out, "\n");
	}
}

Project: jasper
File: jpc_cs.c

static int jpc_poc_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_poc_t *poc = &ms->parms.poc;
	jpc_pocpchg_t *pchg;
	int pchgno;
	for (pchgno = 0, pchg = poc->pchgs; pchgno < poc->numpchgs;
	  ++pchgno, ++pchg) {
		fprintf(out, "po[%d] = %d; ", pchgno, pchg->prgord);
		fprintf(out, "cs[%d] = %d; ce[%d] = %d; ",
		  pchgno, pchg->compnostart, pchgno, pchg->compnoend);
		fprintf(out, "rs[%d] = %d; re[%d] = %d; ",
		  pchgno, pchg->rlvlnostart, pchgno, pchg->rlvlnoend);
		fprintf(out, "le[%d] = %d\n", pchgno, pchg->lyrnoend);
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_ppt_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_ppt_t *ppt = &ms->parms.ppt;
	fprintf(out, "ind=%d; len = %d;\n", ppt->ind, ppt->len);
	if (ppt->len > 0) {
		fprintf(out, "data =\n");
		jas_memdump(out, ppt->data, ppt->len);
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_qcc_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_qcc_t *qcc = &ms->parms.qcc;
	int i;
	fprintf(out, "compno = %d; qntsty = %d; numguard = %d; "
	  "numstepsizes = %d\n", qcc->compno, qcc->compparms.qntsty, qcc->compparms.numguard,
	  qcc->compparms.numstepsizes);
	for (i = 0; i < qcc->compparms.numstepsizes; ++i) {
		fprintf(out, "expn[%d] = 0x%04x; mant[%d] = 0x%04x;\n",
		  i, (unsigned) JPC_QCX_GETEXPN(qcc->compparms.stepsizes[i]),
		  i, (unsigned) JPC_QCX_GETMANT(qcc->compparms.stepsizes[i]));
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_qcx_getcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate,
  jas_stream_t *in, uint_fast16_t len)
{
	uint_fast8_t tmp;
	int n;
	int i;

	/* Eliminate compiler warning about unused variables. */
	cstate = 0;

	n = 0;
	if (jpc_getuint8(in, &tmp)) {
		return -1;
	}
	++n;
	compparms->qntsty = tmp & 0x1f;
	compparms->numguard = (tmp >> 5) & 7;
	switch (compparms->qntsty) {
	case JPC_QCX_SIQNT:
		compparms->numstepsizes = 1;
		break;
	case JPC_QCX_NOQNT:
		compparms->numstepsizes = (len - n);
		break;
	case JPC_QCX_SEQNT:
		/* XXX - this is a hack */
		compparms->numstepsizes = (len - n) / 2;
		break;
	}
	if (compparms->numstepsizes > 0) {
		compparms->stepsizes = jas_alloc2(compparms->numstepsizes,
		  sizeof(uint_fast16_t));
		assert(compparms->stepsizes);
		for (i = 0; i < compparms->numstepsizes; ++i) {
			if (compparms->qntsty == JPC_QCX_NOQNT) {
				if (jpc_getuint8(in, &tmp)) {
					return -1;
				}
				compparms->stepsizes[i] = JPC_QCX_EXPN(tmp >> 3);
			} else {
				if (jpc_getuint16(in, &compparms->stepsizes[i])) {
					return -1;
				}
			}
		}
	} else {
		compparms->stepsizes = 0;
	}
	if (jas_stream_error(in) || jas_stream_eof(in)) {
		jpc_qcx_destroycompparms(compparms);
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_rgn_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_rgn_t *rgn = &ms->parms.rgn;
	fprintf(out, "compno = %d; roisty = %d; roishift = %d\n",
	  rgn->compno, rgn->roisty, rgn->roishift);
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_siz_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_siz_t *siz = &ms->parms.siz;
	unsigned int i;
	fprintf(out, "caps = 0x%02x;\n", siz->caps);
	fprintf(out, "width = %d; height = %d; xoff = %d; yoff = %d;\n",
	  siz->width, siz->height, siz->xoff, siz->yoff);
	fprintf(out, "tilewidth = %d; tileheight = %d; tilexoff = %d; "
	  "tileyoff = %d;\n", siz->tilewidth, siz->tileheight, siz->tilexoff,
	  siz->tileyoff);
	for (i = 0; i < siz->numcomps; ++i) {
		fprintf(out, "prec[%d] = %d; sgnd[%d] = %d; hsamp[%d] = %d; "
		  "vsamp[%d] = %d\n", i, siz->comps[i].prec, i,
		  siz->comps[i].sgnd, i, siz->comps[i].hsamp, i,
		  siz->comps[i].vsamp);
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_sop_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_sop_t *sop = &ms->parms.sop;
	fprintf(out, "seqno = %d;\n", sop->seqno);
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_sot_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_sot_t *sot = &ms->parms.sot;

	/* Eliminate compiler warning about unused variables. */
	cstate = 0;

	if (jpc_getuint16(in, &sot->tileno) ||
	  jpc_getuint32(in, &sot->len) ||
	  jpc_getuint8(in, &sot->partno) ||
	  jpc_getuint8(in, &sot->numparts)) {
		return -1;
	}
	if (jas_stream_eof(in)) {
		return -1;
	}
	return 0;
}