Hello David, using a pointer parameter, without testing it for NULL before is a general coding error. Multiple tests on every sub procedure call level can be dropped only, if the „not NULL“ property can be taken as sure thru all call branch possibilities. Such is proven by static code analysis tools. Hence, if the strncpy function use is as you told, you revealed a driver bug. Modifying libftdi is the only way to fix it.
Best regards, Harald Bergmann > Am 17.07.2024 um 03:42 schrieb David Walton <dwalton...@gmail.com>: > > I have installed the latest version of libftdi in a RPi: "libftdi 1.5 (major: > 1, minor: 5, micro: 0, snapshot ver: v1.5-42-gde9f01e)" > > ftdi_eeprom_get_strings() fails with a segmentation fault if the connected > device does not have a serial number. ftdi_eeprom_get_strings() calls > strncpy(serial, eeprom->serial, serial_len);, however if the device has no > serial number, then eeprom->serial == NULL > > Am I taking the wrong approach, is there a way around this without modifying > libftdi?. The code I am running is as follows: > > /* Based on simple.c > > Simple libftdi usage example > > This program is distributed under the GPL, version 2 > */ > > #include <stdio.h> > #include <stdlib.h> > #include <ftdi.h> > > int main(void) > { > int ret; > struct ftdi_context *ftdi; > struct ftdi_version_info version; > if ((ftdi = ftdi_new()) == 0) > { > fprintf(stderr, "ftdi_new failed\n"); > return EXIT_FAILURE; > } > > version = ftdi_get_library_version(); > printf("Initialized libftdi %s (major: %d, minor: %d, micro: %d, snapshot > ver: %s)\n", > version.version_str, version.major, version.minor, version.micro, > version.snapshot_str); > > if ((ret = ftdi_usb_open_desc(ftdi, 0x0403, 0x6010, "Lattice FTUSB > Interface Cable", NULL)) < 0) > { > fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret, > ftdi_get_error_string(ftdi)); > ftdi_free(ftdi); > return EXIT_FAILURE; > } > > if ((ret = ftdi_read_eeprom(ftdi)) < 0) > { > fprintf(stderr, "unable to open ftdi eeprom: %d (%s)\n", ret, > ftdi_get_error_string(ftdi)); > ftdi_free(ftdi); > return EXIT_FAILURE; > } > > int value; > if ((ret = ftdi_get_eeprom_value(ftdi, CHIP_SIZE, &value)) < 0) > { > fprintf(stderr, "unable to get ftdi eeprom size: %d (%s)\n", ret, > ftdi_get_error_string(ftdi)); > ftdi_free(ftdi); > return EXIT_FAILURE; > } > > if (value < 0) > { > fprintf(stderr, "No EEPROM found or EEPROM empty\n"); > return EXIT_FAILURE; > } > > if ((ret = ftdi_eeprom_decode(ftdi, 0)) < 0) > { > fprintf(stderr, "unable to decode ftdi eeprom: %d (%s)\n", ret, > ftdi_get_error_string(ftdi)); > ftdi_free(ftdi); > return EXIT_FAILURE; > } > > char manufacturer[512] = "\0"; > char product[512] = "\0"; > char serial[512] = "\0"; > struct ftdi_eeprom *eeprom = ftdi->eeprom; > if ((ret = ftdi_eeprom_get_strings(ftdi, manufacturer, > sizeof(manufacturer), product, sizeof(product), serial, sizeof(serial))) < 0) > { > fprintf(stderr, "unable to get ftdi device info: %d (%s)\n", ret, > ftdi_get_error_string(ftdi)); > ftdi_free(ftdi); > return EXIT_FAILURE; > } > printf("manufacturer = %s, product = %s, serial = %s\n", manufacturer, > product, serial); > > if (ftdi->type != TYPE_2232H) > { > fprintf(stderr, "Expected a FT2232H\n"); > } > > if ((ret = ftdi_usb_close(ftdi)) < 0) > { > fprintf(stderr, "unable to close ftdi device: %d (%s)\n", ret, > ftdi_get_error_string(ftdi)); > ftdi_free(ftdi); > return EXIT_FAILURE; > } > > ftdi_free(ftdi); > > return EXIT_SUCCESS; > } > > > libftdi - see http://www.intra2net.com/en/developer/libftdi for details. > To unsubscribe send a mail to libftdi+unsubscr...@developer.intra2net.com > <mailto:libftdi+unsubscr...@developer.intra2net.com> -- libftdi - see http://www.intra2net.com/en/developer/libftdi for details. To unsubscribe send a mail to libftdi+unsubscr...@developer.intra2net.com