xerox_mfp: Fix crash in test mode

Do not decode JPEG into output buffer if it's NULL.
Also, I add assert() for `dev->decData` size, which is never
checked anywhere. Thanks to Michal Nowak for report and
testing. Fixes #128.

References:
  https://gitlab.com/sane-project/backends/issues/128

Tested-by: Michal Nowak <Mno-hime@gitlab>
merge-requests/234/merge
Alex Belkin 2019-11-05 22:01:53 +03:00
rodzic 3c863c2bd9
commit 7e7f02773e
2 zmienionych plików z 24 dodań i 20 usunięć

Wyświetl plik

@ -95,6 +95,9 @@ static char *str_cmd(int cmd)
#define MAX_DUMP 70
const char *encTmpFileName = "/tmp/stmp_enc.tmp";
/*
* Decode jpeg from `infilename` into dev->decData of dev->decDataSize size.
*/
static int decompress(struct device __sane_unused__ *dev,
const char __sane_unused__ *infilename)
{
@ -131,6 +134,7 @@ static int decompress(struct device __sane_unused__ *dev,
height = cinfo.output_height;
pixel_size = cinfo.output_components;
bmp_size = width * height * pixel_size;
assert(bmp_size <= POST_DATASIZE);
dev->decDataSize = bmp_size;
row_stride = width * pixel_size;
@ -152,32 +156,30 @@ static int decompress(struct device __sane_unused__ *dev,
#endif
}
/* copy from decoded jpeg image (dev->decData) into user's buffer (pDest) */
/* returns 0 if there is no data to copy */
static int copy_decompress_data(struct device *dev, unsigned char *pDest, int maxlen, int *destLen)
{
int data_size = 0;
size_t result = 0, retVal = 0;
if (0 == dev->decDataSize) {
*destLen = 0;
return retVal;
}
if (destLen)
*destLen = 0;
if (!dev->decDataSize)
return 0;
data_size = dev->decDataSize - dev->currentDecDataIndex;
if (data_size > maxlen) {
if (data_size > maxlen)
data_size = maxlen;
if (data_size && pDest) {
memcpy(pDest, dev->decData + dev->currentDecDataIndex, data_size);
if (destLen)
*destLen = data_size;
dev->currentDecDataIndex += data_size;
}
memcpy(pDest, dev->decData+dev->currentDecDataIndex, data_size);
result = data_size;
*destLen = result;
dev->currentDecDataIndex += result;
retVal = result;
if (dev->decDataSize == dev->currentDecDataIndex) {
dev->currentDecDataIndex = 0;
dev->decDataSize = 0;
}
return retVal;
return 1;
}
static int decompress_tempfile(struct device *dev)
@ -1294,9 +1296,10 @@ sane_read(SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
dev->decDataSize > 0) {
int diff = dev->total_img_size - dev->total_out_size;
int bufLen = (diff < maxlen) ? diff : maxlen;
if (0 < diff &&
0 < copy_decompress_data(dev, buf, bufLen, lenp)) {
dev->total_out_size += *lenp;
if (diff &&
copy_decompress_data(dev, buf, bufLen, lenp)) {
if (lenp)
dev->total_out_size += *lenp;
return SANE_STATUS_GOOD;
}
}
@ -1460,6 +1463,7 @@ sane_start(SANE_Handle h)
if (!dev->data && !(dev->data = malloc(DATASIZE)))
return ret_cancel(dev, SANE_STATUS_NO_MEM);
/* this is for jpeg mode only */
if (!dev->decData && !(dev->decData = malloc(POST_DATASIZE)))
return ret_cancel(dev, SANE_STATUS_NO_MEM);

Wyświetl plik

@ -74,8 +74,8 @@ struct device {
#define DATATAIL(dev) ((dev->dataoff + dev->datalen) & DATAMASK)
#define DATAROOM(dev) dataroom(dev)
#define POST_DATASIZE 0xFFFFFF
SANE_Byte *decData;
#define POST_DATASIZE 0xFFFFFF /* 16777215 bytes */
SANE_Byte *decData; /* static buffer of POST_DATASIZE bytes */
int decDataSize;
int currentDecDataIndex;
/* data from CMD_INQUIRY: */