session_driver: avoid division by zero, catch API violation

Avoid a division by zero, by not using a zero unitsize in a modulo
operation. As a byproduct, avoid processing and counting input that
neither has analog nor logic data. This should never have happened,
but the change now catches the error if invalid input is seen.

This was reported by clang's scan-build.
This commit is contained in:
Gerhard Sittig 2018-02-08 22:18:02 +01:00 committed by Uwe Hermann
parent f129014ca4
commit 7ee8511be4
1 changed files with 13 additions and 4 deletions

View File

@ -150,8 +150,8 @@ static gboolean stream_session_data(struct sr_dev_inst *sdi)
ret = zip_fread(vdev->capfile, buf, CHUNKSIZE); ret = zip_fread(vdev->capfile, buf, CHUNKSIZE);
if (ret > 0) { if (ret > 0) {
got_data = TRUE;
if (vdev->cur_analog_channel != 0) { if (vdev->cur_analog_channel != 0) {
got_data = TRUE;
packet.type = SR_DF_ANALOG; packet.type = SR_DF_ANALOG;
packet.payload = &analog; packet.payload = &analog;
/* TODO: Use proper 'digits' value for this device (and its modes). */ /* TODO: Use proper 'digits' value for this device (and its modes). */
@ -164,7 +164,8 @@ static gboolean stream_session_data(struct sr_dev_inst *sdi)
analog.meaning->unit = SR_UNIT_VOLT; analog.meaning->unit = SR_UNIT_VOLT;
analog.meaning->mqflags = SR_MQFLAG_DC; analog.meaning->mqflags = SR_MQFLAG_DC;
analog.data = (float *) buf; analog.data = (float *) buf;
} else { } else if (vdev->unitsize) {
got_data = TRUE;
if (ret % vdev->unitsize != 0) if (ret % vdev->unitsize != 0)
sr_warn("Read size %d not a multiple of the" sr_warn("Read size %d not a multiple of the"
" unit size %d.", ret, vdev->unitsize); " unit size %d.", ret, vdev->unitsize);
@ -173,9 +174,17 @@ static gboolean stream_session_data(struct sr_dev_inst *sdi)
logic.length = ret; logic.length = ret;
logic.unitsize = vdev->unitsize; logic.unitsize = vdev->unitsize;
logic.data = buf; logic.data = buf;
} else {
/*
* Neither analog data, nor logic which has
* unitsize, must be an unexpected API use.
*/
sr_warn("Neither analog nor logic data. Ignoring.");
} }
if (got_data) {
vdev->bytes_read += ret; vdev->bytes_read += ret;
sr_session_send(sdi, &packet); sr_session_send(sdi, &packet);
}
} else { } else {
/* done with this capture file */ /* done with this capture file */
zip_fclose(vdev->capfile); zip_fclose(vdev->capfile);