Use snprintf() instead of strncpy() for space-padded strings

The output from the SCSI inquiry command uses fixed-length space-padded
strings, which are copied into null-terminated strings before use.

This is currently done using strncpy(), with the count parameter set to
the string's fixed length. Because a null terminator is not encountered
in the input, strncpy() does not write one in the output, and GCC warns
about potential string truncation. A null terminator is added manually,
but this is error prone (as shown by the fix for the microtek backend).

Use snprintf() instead, which guarantees a null-terminated result and
resolves the warnings from GCC.
merge-requests/701/head
David Ward 2022-03-08 19:00:00 -05:00
rodzic 6a16e78788
commit b3d105cba5
8 zmienionych plików z 45 dodań i 36 usunięć

Wyświetl plik

@ -131,9 +131,12 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes)
#define IN_periph_devtype_unknown 0x1f
#define get_IN_response_format(in) getbitfield(in + 0x03, 0x07, 0)
#define IN_recognized 0x02
#define get_IN_vendor(in, buf) strncpy(buf, (char *)in + 0x08, 0x08)
#define get_IN_product(in, buf) strncpy(buf, (char *)in + 0x10, 0x010)
#define get_IN_version(in, buf) strncpy(buf, (char *)in + 0x20, 0x04)
#define get_IN_vendor(in, buf) snprintf(buf, 0x08 + 1, "%.*s", \
0x08, (char*)in + 0x08)
#define get_IN_product(in, buf) snprintf(buf, 0x10 + 1, "%.*s", \
0x10, (char*)in + 0x10)
#define get_IN_version(in, buf) snprintf(buf, 0x04 + 1, "%.*s", \
0x04, (char*)in + 0x20)
/* the VPD response */
#define get_IN_page_length(in) in[0x04]

Wyświetl plik

@ -140,9 +140,12 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes)
#define IN_periph_devtype_unknown 0x1f
#define get_IN_response_format(in) getbitfield(in + 0x03, 0x07, 0)
#define IN_recognized 0x02
#define get_IN_vendor(in, buf) strncpy(buf, (char *)in + 0x08, 0x08)
#define get_IN_product(in, buf) strncpy(buf, (char *)in + 0x10, 0x010)
#define get_IN_version(in, buf) strncpy(buf, (char *)in + 0x20, 0x04)
#define get_IN_vendor(in, buf) snprintf(buf, 0x08 + 1, "%.*s", \
0x08, (char *)in + 0x08)
#define get_IN_product(in, buf) snprintf(buf, 0x10 + 1, "%.*s", \
0x10, (char *)in + 0x10)
#define get_IN_version(in, buf) snprintf(buf, 0x04 + 1, "%.*s", \
0x04, (char *)in + 0x20)
#define get_IN_color_offset(in) getnbyte (in+0x2A, 2) /* offset between colors */
/* these only in some scanners */

Wyświetl plik

@ -133,10 +133,14 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes)
#define get_I_cmdque(in) getbitfield(in + 7, 1, 1)
#define get_I_sftre(in) getbitfield(in + 7, 0, 1)
#define get_I_vendor(in, buf) strncpy(buf,(char *)in + 0x08, 0x08)
#define get_I_product(in, buf) strncpy(buf,(char *)in + 0x10, 0x10)
#define get_I_version(in, buf) strncpy(buf,(char *)in + 0x20, 0x04)
#define get_I_build(in, buf) strncpy(buf,(char *)in + 0x24, 0x02)
#define get_I_vendor(in, buf) snprintf(buf, 0x08 + 1, "%.*s", \
0x08, (char *)in + 0x08)
#define get_I_product(in, buf) snprintf(buf, 0x10 + 1, "%.*s", \
0x10, (char *)in + 0x10)
#define get_I_version(in, buf) snprintf(buf, 0x04 + 1, "%.*s", \
0x04, (char *)in + 0x20)
#define get_I_build(in, buf) snprintf(buf, 0x02 + 1, "%.*s", \
0x02, (char *)in + 0x24)
#define get_I_mf_disable(in) getbitfield(in + 38, 7, 1)
#define get_I_checkdigit(in) getbitfield(in + 38, 6, 1)

Wyświetl plik

@ -1502,14 +1502,10 @@ parse_inquiry(Microtek_Info *mi, unsigned char *result)
};
#endif
DBG(15, "parse_inquiry...\n");
strncpy(mi->vendor_id, (char *)&result[8], 8);
strncpy(mi->model_name, (char *)&result[16], 16);
strncpy(mi->revision_num, (char *)&result[32], 4);
strncpy(mi->vendor_string, (char *)&result[36], 20);
mi->vendor_id[8] = 0;
mi->model_name[16] = 0;
mi->revision_num[4] = 0;
mi->vendor_string[20] = 0;
snprintf(mi->vendor_id, 8 + 1, "%.*s", 8, (char *)&result[8]);
snprintf(mi->model_name, 16 + 1, "%.*s", 16, (char *)&result[16]);
snprintf(mi->revision_num, 4 + 1, "%.*s", 4, (char *)&result[32]);
snprintf(mi->vendor_string, 20 + 1, "%.*s", 20, (char *)&result[36]);
mi->device_type = (SANE_Byte)(result[0] & 0x1f);
mi->SCSI_firmware_ver_major = (SANE_Byte)((result[1] & 0xf0) >> 4);
@ -1947,12 +1943,9 @@ dump_suspect_inquiry(unsigned char *result)
}
fprintf(stderr, "\n\n");
#endif
strncpy(vendor_id, (char *)&result[8], 8);
strncpy(model_name, (char *)&result[16], 16);
strncpy(revision_num, (char *)&result[32], 4);
vendor_id[8] = 0;
model_name[16] = 0;
revision_num[4] = 0;
snprintf(vendor_id, 8 + 1, "%.*s", 8, (char *)&result[8]);
snprintf(model_name, 16 + 1, "%.*s", 16, (char *)&result[16]);
snprintf(revision_num, 4 + 1, "%.*s", 4, (char *)&result[32]);
device_type = (SANE_Byte)(result[0] & 0x1f);
SCSI_firmware_ver_major = (SANE_Byte)((result[1] & 0xf0) >> 4);
SCSI_firmware_ver_minor = (SANE_Byte)(result[1] & 0x0f);

Wyświetl plik

@ -189,9 +189,12 @@ static scsiblk inquiry = { inquiryC, sizeof(inquiryC) };
#define get_inquiry_additional_length(in) in[0x04]
#define set_inquiry_length(out,n) out[0x04]=n-5
#define get_inquiry_vendor(in, buf) strncpy(buf, in + 0x08, 0x08)
#define get_inquiry_product(in, buf) strncpy(buf, in + 0x10, 0x010)
#define get_inquiry_version(in, buf) strncpy(buf, in + 0x20, 0x04)
#define get_inquiry_vendor(in, buf) snprintf(buf, 0x08 + 1, "%.*s", \
0x08, in + 0x08)
#define get_inquiry_product(in, buf) snprintf(buf, 0x10 + 1, "%.*s", \
0x10, in + 0x10)
#define get_inquiry_version(in, buf) snprintf(buf, 0x04 + 1, "%.*s", \
0x04, in + 0x20)
#define get_inquiry_max_x_res(in) getnbyte1(in + 0x24, 2)
#define get_inquiry_max_y_res(in) getnbyte1(in + 0x26, 2)

Wyświetl plik

@ -744,11 +744,8 @@ pie_get_inquiry_values (Pie_Device * dev, unsigned char *buffer)
dev->inquiry_len = get_inquiry_additional_length (buffer) + 5;
get_inquiry_vendor ((char *) buffer, dev->vendor);
dev->vendor[8] = '\0';
get_inquiry_product ((char *) buffer, dev->product);
dev->product[16] = '\0';
get_inquiry_version ((char *) buffer, dev->version);
dev->version[4] = '\0';
dev->inquiry_x_res = get_inquiry_max_x_res (buffer);
dev->inquiry_y_res = get_inquiry_max_y_res (buffer);

Wyświetl plik

@ -209,9 +209,12 @@ static scsiblk inquiryB =
#define get_IN_response_format(in) getbitfield(in + 0x03, 0x0f, 0)
#define IN_recognized 0x02
#define get_IN_additional_length(in) in[0x04]
#define get_IN_vendor(in, buf) strncpy(buf, in + 0x08, 0x08)
#define get_IN_product(in, buf) strncpy(buf, in + 0x10, 0x010)
#define get_IN_version(in, buf) strncpy(buf, in + 0x20, 0x04)
#define get_IN_vendor(in, buf) snprintf(buf, 0x08 + 1, "%.*s", \
0x08, in + 0x08)
#define get_IN_product(in, buf) snprintf(buf, 0x10 + 1, "%.*s", \
0x10, in + 0x10)
#define get_IN_version(in, buf) snprintf(buf, 0x04 + 1, "%.*s", \
0x04, in + 0x20)
#define get_IN_color_mode(in) getbitfield(in + 0x24, 0xf, 0)
#define get_IN_color_seq(in) getbitfield(in + 0x24, 0x7, 4)
#define get_IN_adf(in) getbitfield(in + 0x24, 0x1, 7)

Wyświetl plik

@ -89,9 +89,12 @@ scsiblk;
#define set_inquiry_return_size(icb,val) icb[0x04]=val
#define IN_periph_devtype_cpu 0x03
#define IN_periph_devtype_scanner 0x06
#define get_scsi_inquiry_vendor(in, buf) strncpy(buf, in + 0x08, 0x08)
#define get_scsi_inquiry_product(in, buf) strncpy(buf, in + 0x10, 0x010)
#define get_scsi_inquiry_version(in, buf) strncpy(buf, in + 0x20, 0x04)
#define get_scsi_inquiry_vendor(in, buf) snprintf(buf, 0x08 + 1, "%.*s", \
0x08, in + 0x08)
#define get_scsi_inquiry_product(in, buf) snprintf(buf, 0x10 + 1, "%.*s", \
0x10, in + 0x10)
#define get_scsi_inquiry_version(in, buf) snprintf(buf, 0x04 + 1, "%.*s", \
0x04, in + 0x20)
#define get_scsi_inquiry_periph_devtype(in) (in[0] & 0x1f)
#define get_scsi_inquiry_additional_length(in) in[0x04]
#define set_scsi_inquiry_length(out,n) out[0x04]=n-5