From f19d233fad2f302e48be8b9c39a17ea37836c80e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 9 Mar 2013 00:46:45 +0100 Subject: [PATCH 1/9] Merge log-printf.c into log.c, inline with prototypes in log.h & platform files log_*.c --- libnfc/Makefile.am | 3 +- libnfc/log-printf.c | 92 --------------------------------------------- libnfc/log.c | 67 +++++++++++++++++++++++++++++++-- 3 files changed, 65 insertions(+), 97 deletions(-) delete mode 100644 libnfc/log-printf.c diff --git a/libnfc/Makefile.am b/libnfc/Makefile.am index a5ad329..709f4e2 100644 --- a/libnfc/Makefile.am +++ b/libnfc/Makefile.am @@ -40,11 +40,10 @@ if LIBUSB_ENABLED endif if WITH_LOG - libnfc_la_SOURCES += log-printf.c log_posix.c + libnfc_la_SOURCES += log_posix.c endif EXTRA_DIST = \ CMakeLists.txt \ - log-printf.c \ log_posix.c \ log_win32.c diff --git a/libnfc/log-printf.c b/libnfc/log-printf.c deleted file mode 100644 index 3f912be..0000000 --- a/libnfc/log-printf.c +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * Copyright (C) 2011 Romain Tartière - * Copyright (C) 2011, 2012 Romuald Conty - * Copyright (C) 2013 Alex Lian - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - */ - -#include "log.h" - -#include -#include -#include -#include -#include -#include - -#ifndef LOG -// Leaving in a preprocessor error, as the build system should skip this -// file otherwise. -#error "No logging defined, but log-printf.c still compiled." -#else // LOG - -// Internal methods so different platforms can route the logging -// Offering both forms of the variadic function -// These are implemented in the log_ specific file -void log_put_internal(const char *format, ...); -void log_vput_internal(const char *format, va_list args); - -void -log_init(const nfc_context *context) -{ -#ifdef ENVVARS - char str[32]; - sprintf(str, "%"PRIu32, context->log_level); - setenv("LIBNFC_LOG_LEVEL", str, 1); -#else - (void)context; -#endif -} - -void -log_exit(void) -{ -} - -void -log_put(const uint8_t group, const char *category, const uint8_t priority, const char *format, ...) -{ - char *env_log_level = NULL; -#ifdef ENVVARS - env_log_level = getenv("LIBNFC_LOG_LEVEL"); -#endif - uint32_t log_level; - if (NULL == env_log_level) { - // LIBNFC_LOG_LEVEL is not set -#ifdef DEBUG - log_level = 3; -#else - log_level = 1; -#endif - } else { - log_level = atoi(env_log_level); - } - - // printf("log_level = %"PRIu32" group = %"PRIu8" priority = %"PRIu8"\n", log_level, group, priority); - if (log_level) { // If log is not disabled by log_level=none - if (((log_level & 0x00000003) >= priority) || // Global log level - (((log_level >> (group * 2)) & 0x00000003) >= priority)) { // Group log level - - va_list va; - va_start(va, format); - log_put_internal("%s\t%s\t", log_priority_to_str(priority), category); - log_vput_internal(format, va); - log_put_internal("\n"); - va_end(va); - } - } -} - -#endif // LOG diff --git a/libnfc/log.c b/libnfc/log.c index 758b0d3..d845227 100644 --- a/libnfc/log.c +++ b/libnfc/log.c @@ -16,12 +16,13 @@ */ #include "log.h" -/* +#include +#include #include +#include #include #include -*/ -#include +#include /* int @@ -70,3 +71,63 @@ log_priority_to_str(const int priority) return "unknown"; } + +#ifdef LOG +// Internal methods so different platforms can route the logging +// Offering both forms of the variadic function +// These are implemented in the log_ specific file +void log_put_internal(const char *format, ...); +void log_vput_internal(const char *format, va_list args); + +void +log_init(const nfc_context *context) +{ +#ifdef ENVVARS + char str[32]; + sprintf(str, "%"PRIu32, context->log_level); + setenv("LIBNFC_LOG_LEVEL", str, 1); +#else + (void)context; +#endif +} + +void +log_exit(void) +{ +} + +void +log_put(const uint8_t group, const char *category, const uint8_t priority, const char *format, ...) +{ + char *env_log_level = NULL; +#ifdef ENVVARS + env_log_level = getenv("LIBNFC_LOG_LEVEL"); +#endif + uint32_t log_level; + if (NULL == env_log_level) { + // LIBNFC_LOG_LEVEL is not set +#ifdef DEBUG + log_level = 3; +#else + log_level = 1; +#endif + } else { + log_level = atoi(env_log_level); + } + + // printf("log_level = %"PRIu32" group = %"PRIu8" priority = %"PRIu8"\n", log_level, group, priority); + if (log_level) { // If log is not disabled by log_level=none + if (((log_level & 0x00000003) >= priority) || // Global log level + (((log_level >> (group * 2)) & 0x00000003) >= priority)) { // Group log level + + va_list va; + va_start(va, format); + log_put_internal("%s\t%s\t", log_priority_to_str(priority), category); + log_vput_internal(format, va); + log_put_internal("\n"); + va_end(va); + } + } +} + +#endif // LOG From 7e26aa368de83d5c226b60605d1faf847d3ffb38 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 9 Mar 2013 00:47:21 +0100 Subject: [PATCH 2/9] log_win32: declare log_output_debug() static --- libnfc/log_win32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnfc/log_win32.c b/libnfc/log_win32.c index 81196a7..d4fba60 100644 --- a/libnfc/log_win32.c +++ b/libnfc/log_win32.c @@ -26,7 +26,7 @@ #include #include -void +static void log_output_debug(const char *format, va_list args) { char buffer[1024]; From 6a110b3849adc677215211f0b8e74c9913ed1a94 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 9 Mar 2013 00:59:29 +0100 Subject: [PATCH 3/9] Creating log_internal.h for log_*put_internal() prototypes Fixed warning "no previous prototype for function" in log_posix.c --- libnfc/log.c | 7 ++----- libnfc/log.h | 2 ++ libnfc/log_posix.c | 5 +---- libnfc/log_win32.c | 5 +---- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/libnfc/log.c b/libnfc/log.c index d845227..6f12491 100644 --- a/libnfc/log.c +++ b/libnfc/log.c @@ -73,11 +73,8 @@ log_priority_to_str(const int priority) #ifdef LOG -// Internal methods so different platforms can route the logging -// Offering both forms of the variadic function -// These are implemented in the log_ specific file -void log_put_internal(const char *format, ...); -void log_vput_internal(const char *format, va_list args); + +#include "log_internal.h" void log_init(const nfc_context *context) diff --git a/libnfc/log.h b/libnfc/log.h index d3604fa..05c3f34 100644 --- a/libnfc/log.h +++ b/libnfc/log.h @@ -70,6 +70,8 @@ void log_put(const uint8_t group, const char *category, const uint8_t priority, __attribute__((format(printf, 4, 5))) # endif ; +void log_put_internal(const char *format, ...); +void log_vput_internal(const char *format, va_list args); #else // No logging diff --git a/libnfc/log_posix.c b/libnfc/log_posix.c index 3e963d2..3f483dd 100644 --- a/libnfc/log_posix.c +++ b/libnfc/log_posix.c @@ -17,11 +17,8 @@ * along with this program. If not, see */ -#include "log.h" +#include "log_internal.h" -#include -#include -#include #include #include diff --git a/libnfc/log_win32.c b/libnfc/log_win32.c index d4fba60..adeb729 100644 --- a/libnfc/log_win32.c +++ b/libnfc/log_win32.c @@ -17,11 +17,8 @@ * along with this program. If not, see */ -#include "log.h" +#include "log_internal.h" -#include -#include -#include #include #include #include From a9e3365d98295a762bac19d179a7a15b10f772b0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 9 Mar 2013 10:41:07 +0100 Subject: [PATCH 4/9] Add log_internal.h to Makefile --- libnfc/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/libnfc/Makefile.am b/libnfc/Makefile.am index 709f4e2..937350e 100644 --- a/libnfc/Makefile.am +++ b/libnfc/Makefile.am @@ -18,6 +18,7 @@ libnfc_la_SOURCES = \ drivers.h \ iso7816.h \ log.h \ + log_internal.h \ mirror-subr.h \ nfc-internal.h \ target-subr.h From ad8b338a7b6985c58d9d3414b59d8f16955d2f55 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 9 Mar 2013 10:41:25 +0100 Subject: [PATCH 5/9] Remove log-printf from CMakefile --- libnfc/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libnfc/CMakeLists.txt b/libnfc/CMakeLists.txt index 50fff78..54f2690 100644 --- a/libnfc/CMakeLists.txt +++ b/libnfc/CMakeLists.txt @@ -48,9 +48,9 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) IF(LIBNFC_LOG) IF(WIN32) SET(CMAKE_C_FLAGS "-fgnu89-inline ${CMAKE_C_FLAGS}") - LIST(APPEND LIBRARY_SOURCES log-printf log_win32) + LIST(APPEND LIBRARY_SOURCES log_win32) ELSE(WIN32) - LIST(APPEND LIBRARY_SOURCES log-printf log_posix) + LIST(APPEND LIBRARY_SOURCES log_posix) ENDIF(WIN32) ENDIF(LIBNFC_LOG) ADD_LIBRARY(nfc SHARED ${LIBRARY_SOURCES}) From 38966cb2fbed780bddc344c10d52155167e2f817 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 9 Mar 2013 10:56:51 +0100 Subject: [PATCH 6/9] Forgot to commit new log internal header file --- libnfc/Makefile.am | 2 +- libnfc/log-internal.h | 33 +++++++++++++++++++++++++++++++++ libnfc/log.c | 2 +- libnfc/log.h | 3 --- libnfc/log_posix.c | 2 +- libnfc/log_win32.c | 2 +- 6 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 libnfc/log-internal.h diff --git a/libnfc/Makefile.am b/libnfc/Makefile.am index 937350e..5d02b77 100644 --- a/libnfc/Makefile.am +++ b/libnfc/Makefile.am @@ -18,7 +18,7 @@ libnfc_la_SOURCES = \ drivers.h \ iso7816.h \ log.h \ - log_internal.h \ + log-internal.h \ mirror-subr.h \ nfc-internal.h \ target-subr.h diff --git a/libnfc/log-internal.h b/libnfc/log-internal.h new file mode 100644 index 0000000..f8bcb2d --- /dev/null +++ b/libnfc/log-internal.h @@ -0,0 +1,33 @@ +/*- + * Copyright (C) 2013 Romuald Conty + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see + */ + +#ifndef __LOG_INTERNAL_H__ +#define __LOG_INTERNAL_H__ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif // HAVE_CONFIG_H + +#include + +// Internal methods so different platforms can route the logging +// Offering both forms of the variadic function +// These are implemented in the log_ specific file +void log_put_internal(const char *format, ...); +void log_vput_internal(const char *format, va_list args); + +#endif // __LOG_INTERNAL_H__ diff --git a/libnfc/log.c b/libnfc/log.c index 6f12491..66556ef 100644 --- a/libnfc/log.c +++ b/libnfc/log.c @@ -74,7 +74,7 @@ log_priority_to_str(const int priority) #ifdef LOG -#include "log_internal.h" +#include "log-internal.h" void log_init(const nfc_context *context) diff --git a/libnfc/log.h b/libnfc/log.h index 05c3f34..64228f2 100644 --- a/libnfc/log.h +++ b/libnfc/log.h @@ -70,9 +70,6 @@ void log_put(const uint8_t group, const char *category, const uint8_t priority, __attribute__((format(printf, 4, 5))) # endif ; -void log_put_internal(const char *format, ...); -void log_vput_internal(const char *format, va_list args); - #else // No logging #define log_init(nfc_context) ((void) 0) diff --git a/libnfc/log_posix.c b/libnfc/log_posix.c index 3f483dd..b7c4371 100644 --- a/libnfc/log_posix.c +++ b/libnfc/log_posix.c @@ -17,7 +17,7 @@ * along with this program. If not, see */ -#include "log_internal.h" +#include "log-internal.h" #include #include diff --git a/libnfc/log_win32.c b/libnfc/log_win32.c index adeb729..a302097 100644 --- a/libnfc/log_win32.c +++ b/libnfc/log_win32.c @@ -17,7 +17,7 @@ * along with this program. If not, see */ -#include "log_internal.h" +#include "log-internal.h" #include #include From e7f4d0778e0506c83a709b43a139a90eb4854aef Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 9 Mar 2013 11:27:56 +0100 Subject: [PATCH 7/9] Update NEWS & Changelog --- ChangeLog | 20 ++++++++++++++++++++ NEWS | 4 +++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ea24f75..c04fbc8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +TBD +--- + +Fixes: + - Fix bug when compiling without libusb + - Fixes several memory leaks in error handling conditions + - Remove calls to exit() from the library + - Numerous minor fixes suggested by cppcheck & clang + - Windows: Clean up compiler/linker warnings + +Improvements: + - Developers HACKING file: introduce clang & cppcheck for better code + - Windows: better logging via OutputDebugString() + +Changes: + - Upon malloc error, nfc_init() doesn't force exit() anymore + so now you should test if context != NULL after nfc_init() call + - API: nfc_initiator_target_is_present() & str_nfc_target() + now take a pointer to nfc_target as argument instead of passing by value + Mar 03, 2013 - 1.7.0-rc6 (release candidate) -------------------------------------------- diff --git a/NEWS b/NEWS index 59a18a6..f6c2170 100644 --- a/NEWS +++ b/NEWS @@ -3,8 +3,10 @@ New in 1.7.0-***: API Changes: * Functions - - nfc_initiator_target_is_present() & str_nfc_target() + - nfc_initiator_target_is_present() & str_nfc_target(): now take a pointer to nfc_target as argument + - nfc_init(): upon malloc error, doesn't force exit() anymore + so now you should test if context != NULL after nfc_init() call New in 1.7.0-rc5: From 59271d27e98b2bc5c302bdbc39aeffb7b2fd95b5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 9 Mar 2013 16:33:51 +0100 Subject: [PATCH 8/9] Update Changelog --- ChangeLog | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index c04fbc8..3636b5e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,14 +3,25 @@ TBD Fixes: - Fix bug when compiling without libusb - - Fixes several memory leaks in error handling conditions + - Fix several memory leaks in error handling conditions - Remove calls to exit() from the library - - Numerous minor fixes suggested by cppcheck & clang + - Create safer snprint_nfc_*() instead of sprint_nfc_*() functions + - Fix warnings returned by cppcheck & clang/scan-build + - Obsolete function 'usleep' => nanosleep() + - Non reentrant function 'readdir' => readdir_r() + - Buffer may not be null-terminated after call to strncpy() + - scanf without field width limits can crash with huge input data + - Resource leaks: missing fclose() + - Dead code, unused vars & vars scopes warnings + - Windows: Fix compilation due to new usbbus file - Windows: Clean up compiler/linker warnings + - Fixed the suppression of the auto-fixup for linking against MS built libs + - Fixed all the formatting warnings by shifting to inttypes.h specifiers + - shifted to %lu for DWORD printf Improvements: - - Developers HACKING file: introduce clang & cppcheck for better code - - Windows: better logging via OutputDebugString() + - Devels HACKING file: introduce clang/scan-build & cppcheck for better code + - Windows: logging via OutputDebugString(), ease debugging Changes: - Upon malloc error, nfc_init() doesn't force exit() anymore From cc03f84636c03d6a06d47dd3ca84fe2ace04fea8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 10 Mar 2013 00:20:52 +0100 Subject: [PATCH 9/9] New connstring_decode() fix cppcheck warning "Non reentrant function 'strtok' called" --- libnfc/drivers/acr122_pcsc.c | 54 +++++++------------------- libnfc/drivers/acr122_usb.c | 46 +--------------------- libnfc/drivers/acr122s.c | 70 +++++++++------------------------ libnfc/drivers/arygon.c | 73 ++++++++++------------------------- libnfc/drivers/pn532_uart.c | 75 ++++++++++-------------------------- libnfc/drivers/pn53x_usb.c | 46 +--------------------- libnfc/nfc-internal.c | 64 ++++++++++++++++++++++++++++++ libnfc/nfc-internal.h | 2 + 8 files changed, 140 insertions(+), 290 deletions(-) diff --git a/libnfc/drivers/acr122_pcsc.c b/libnfc/drivers/acr122_pcsc.c index 4341aad..a60825c 100644 --- a/libnfc/drivers/acr122_pcsc.c +++ b/libnfc/drivers/acr122_pcsc.c @@ -191,49 +191,14 @@ acr122_pcsc_scan(const nfc_context *context, nfc_connstring connstrings[], const } struct acr122_pcsc_descriptor { - char pcsc_device_name[512]; + char *pcsc_device_name; }; -static int -acr122_pcsc_connstring_decode(const nfc_connstring connstring, struct acr122_pcsc_descriptor *desc) -{ - char *cs = malloc(strlen(connstring) + 1); - if (!cs) { - perror("malloc"); - return -1; - } - strcpy(cs, connstring); - const char *driver_name = strtok(cs, ":"); - if (!driver_name) { - // Parse error - free(cs); - return -1; - } - - if (0 != strcmp(driver_name, ACR122_PCSC_DRIVER_NAME)) { - // Driver name does not match. - free(cs); - return 0; - } - - const char *device_name = strtok(NULL, ":"); - if (!device_name) { - // Only driver name was specified (or parsing error) - free(cs); - return 1; - } - strncpy(desc->pcsc_device_name, device_name, sizeof(desc->pcsc_device_name) - 1); - desc->pcsc_device_name[sizeof(desc->pcsc_device_name) - 1] = '\0'; - - free(cs); - return 2; -} - static nfc_device * acr122_pcsc_open(const nfc_context *context, const nfc_connstring connstring) { struct acr122_pcsc_descriptor ndd; - int connstring_decode_level = acr122_pcsc_connstring_decode(connstring, &ndd); + int connstring_decode_level = connstring_decode(connstring, ACR122_PCSC_DRIVER_NAME, "pcsc", &ndd.pcsc_device_name, NULL); if (connstring_decode_level < 1) { return NULL; @@ -245,7 +210,7 @@ acr122_pcsc_open(const nfc_context *context, const nfc_connstring connstring) size_t szDeviceFound = acr122_pcsc_scan(context, &fullconnstring, 1); if (szDeviceFound < 1) return NULL; - connstring_decode_level = acr122_pcsc_connstring_decode(fullconnstring, &ndd); + connstring_decode_level = connstring_decode(fullconnstring, ACR122_PCSC_DRIVER_NAME, "pcsc", &ndd.pcsc_device_name, NULL); if (connstring_decode_level < 2) { return NULL; } @@ -255,23 +220,29 @@ acr122_pcsc_open(const nfc_context *context, const nfc_connstring connstring) if (strlen(ndd.pcsc_device_name) < 5) { // We can assume it's a reader ID as pcsc_name always ends with "NN NN" // Device was not specified, only ID, retrieve it size_t index; - if (sscanf(ndd.pcsc_device_name, "%4" SCNuPTR, &index) != 1) + if (sscanf(ndd.pcsc_device_name, "%4" SCNuPTR, &index) != 1) { + free(ndd.pcsc_device_name); return NULL; + } nfc_connstring *ncs = malloc(sizeof(nfc_connstring) * (index + 1)); if (!ncs) { perror("malloc"); + free(ndd.pcsc_device_name); return NULL; } size_t szDeviceFound = acr122_pcsc_scan(context, ncs, index + 1); if (szDeviceFound < index + 1) { free(ncs); + free(ndd.pcsc_device_name); return NULL; } strncpy(fullconnstring, ncs[index], sizeof(nfc_connstring)); fullconnstring[sizeof(nfc_connstring) - 1] = '\0'; free(ncs); - connstring_decode_level = acr122_pcsc_connstring_decode(fullconnstring, &ndd); + connstring_decode_level = connstring_decode(fullconnstring, ACR122_PCSC_DRIVER_NAME, "pcsc", &ndd.pcsc_device_name, NULL); + if (connstring_decode_level < 2) { + free(ndd.pcsc_device_name); return NULL; } } @@ -324,12 +295,13 @@ acr122_pcsc_open(const nfc_context *context, const nfc_connstring connstring) pn53x_init(pnd); + free(ndd.pcsc_device_name); return pnd; } error: + free(ndd.pcsc_device_name); nfc_device_free(pnd); - return NULL; } diff --git a/libnfc/drivers/acr122_usb.c b/libnfc/drivers/acr122_usb.c index 93e65f3..e4ccae2 100644 --- a/libnfc/drivers/acr122_usb.c +++ b/libnfc/drivers/acr122_usb.c @@ -347,50 +347,6 @@ struct acr122_usb_descriptor { char *filename; }; -static int -acr122_usb_connstring_decode(const nfc_connstring connstring, struct acr122_usb_descriptor *desc) -{ - int n = strlen(connstring) + 1; - char *driver_name = malloc(n); - if (!driver_name) { - perror("malloc"); - return 0; - } - char *dirname = malloc(n); - if (!dirname) { - perror("malloc"); - free(driver_name); - return 0; - } - char *filename = malloc(n); - if (!filename) { - perror("malloc"); - free(driver_name); - free(dirname); - return 0; - } - - driver_name[0] = '\0'; - - char format[32]; - snprintf(format, sizeof(format), "%%%i[^:]:%%%i[^:]:%%%i[^:]", n - 1, n - 1, n - 1); - int res = sscanf(connstring, format, driver_name, dirname, filename); - - if (!res || ((0 != strcmp(driver_name, ACR122_USB_DRIVER_NAME)) && (0 != strcmp(driver_name, "usb")))) { - // Driver name does not match. - res = 0; - } else { - desc->dirname = strdup(dirname); - desc->filename = strdup(filename); - } - - free(driver_name); - free(dirname); - free(filename); - - return res; -} - static bool acr122_usb_get_usb_device_name(struct usb_device *dev, usb_dev_handle *udev, char *buffer, size_t len) { @@ -424,7 +380,7 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring) { nfc_device *pnd = NULL; struct acr122_usb_descriptor desc = { NULL, NULL }; - int connstring_decode_level = acr122_usb_connstring_decode(connstring, &desc); + int connstring_decode_level = connstring_decode(connstring, ACR122_USB_DRIVER_NAME, "usb", &desc.dirname, &desc.filename); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%d element(s) have been decoded from \"%s\"", connstring_decode_level, connstring); if (connstring_decode_level < 1) { goto free_mem; diff --git a/libnfc/drivers/acr122s.c b/libnfc/drivers/acr122s.c index 3daf30b..f6e69e1 100644 --- a/libnfc/drivers/acr122s.c +++ b/libnfc/drivers/acr122s.c @@ -396,59 +396,10 @@ acr122s_get_firmware_version(nfc_device *pnd, char *version, size_t length) } struct acr122s_descriptor { - char port[128]; + char *port; uint32_t speed; }; -static int -acr122s_connstring_decode(const nfc_connstring connstring, struct acr122s_descriptor *desc) -{ - char *cs = malloc(strlen(connstring) + 1); - if (!cs) { - perror("malloc"); - return -1; - } - strcpy(cs, connstring); - const char *driver_name = strtok(cs, ":"); - if (!driver_name) { - // Parse error - free(cs); - return -1; - } - - if (0 != strcmp(driver_name, ACR122S_DRIVER_NAME)) { - // Driver name does not match. - free(cs); - return 0; - } - - const char *port = strtok(NULL, ":"); - if (!port) { - // Only driver name was specified (or parsing error) - free(cs); - return 1; - } - strncpy(desc->port, port, sizeof(desc->port) - 1); - desc->port[sizeof(desc->port) - 1] = '\0'; - - const char *speed_s = strtok(NULL, ":"); - if (!speed_s) { - // speed not specified (or parsing error) - free(cs); - return 2; - } - unsigned long speed; - if (sscanf(speed_s, "%10lu", &speed) != 1) { - // speed_s is not a number - free(cs); - return 2; - } - desc->speed = speed; - - free(cs); - return 3; -} - static size_t acr122s_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len) { @@ -540,6 +491,7 @@ acr122s_close(nfc_device *pnd) close(DRIVER_DATA(pnd)->abort_fds[1]); #endif + free(DRIVER_DATA(pnd)->port); pn53x_data_free(pnd); nfc_device_free(pnd); } @@ -550,8 +502,18 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring) serial_port sp; nfc_device *pnd; struct acr122s_descriptor ndd; - int connstring_decode_level = acr122s_connstring_decode(connstring, &ndd); - + char *speed_s; + int connstring_decode_level = connstring_decode(connstring, ACR122S_DRIVER_NAME, NULL, &ndd.port, &speed_s); + if (connstring_decode_level == 3) { + ndd.speed = 0; + if (sscanf(speed_s, "%10"PRIu32, &ndd.speed) != 1) { + // speed_s is not a number + free(ndd.port); + free(speed_s); + return NULL; + } + free(speed_s); + } if (connstring_decode_level < 2) { return NULL; } @@ -566,11 +528,13 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring) if (sp == INVALID_SERIAL_PORT) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Invalid serial port: %s", ndd.port); + free(ndd.port); return NULL; } if (sp == CLAIMED_SERIAL_PORT) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Serial port already claimed: %s", ndd.port); + free(ndd.port); return NULL; } @@ -580,6 +544,7 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring) pnd = nfc_device_new(context, connstring); if (!pnd) { perror("malloc"); + acr122s_close(pnd); return NULL; } pnd->driver = &acr122s_driver; @@ -597,6 +562,7 @@ acr122s_open(const nfc_context *context, const nfc_connstring connstring) #ifndef WIN32 if (pipe(DRIVER_DATA(pnd)->abort_fds) < 0) { + acr122s_close(pnd); return NULL; } #else diff --git a/libnfc/drivers/arygon.c b/libnfc/drivers/arygon.c index 729b0b8..d7f78d7 100644 --- a/libnfc/drivers/arygon.c +++ b/libnfc/drivers/arygon.c @@ -165,59 +165,10 @@ arygon_scan(const nfc_context *context, nfc_connstring connstrings[], const size } struct arygon_descriptor { - char port[128]; + char *port; uint32_t speed; }; -static int -arygon_connstring_decode(const nfc_connstring connstring, struct arygon_descriptor *desc) -{ - char *cs = malloc(strlen(connstring) + 1); - if (!cs) { - perror("malloc"); - return -1; - } - strcpy(cs, connstring); - const char *driver_name = strtok(cs, ":"); - if (!driver_name) { - // Parse error - free(cs); - return -1; - } - - if (0 != strcmp(driver_name, ARYGON_DRIVER_NAME)) { - // Driver name does not match. - free(cs); - return 0; - } - - const char *port = strtok(NULL, ":"); - if (!port) { - // Only driver name was specified (or parsing error) - free(cs); - return 1; - } - strncpy(desc->port, port, sizeof(desc->port) - 1); - desc->port[sizeof(desc->port) - 1] = '\0'; - - const char *speed_s = strtok(NULL, ":"); - if (!speed_s) { - // speed not specified (or parsing error) - free(cs); - return 2; - } - unsigned long speed; - if (sscanf(speed_s, "%10lu", &speed) != 1) { - // speed_s is not a number - free(cs); - return 2; - } - desc->speed = speed; - - free(cs); - return 3; -} - static void arygon_close(nfc_device *pnd) { @@ -232,6 +183,7 @@ arygon_close(nfc_device *pnd) close(DRIVER_DATA(pnd)->iAbortFds[1]); #endif + free(DRIVER_DATA(pnd)->port); pn53x_data_free(pnd); nfc_device_free(pnd); } @@ -240,8 +192,18 @@ static nfc_device * arygon_open(const nfc_context *context, const nfc_connstring connstring) { struct arygon_descriptor ndd; - int connstring_decode_level = arygon_connstring_decode(connstring, &ndd); - + char *speed_s; + int connstring_decode_level = connstring_decode(connstring, ARYGON_DRIVER_NAME, NULL, &ndd.port, &speed_s); + if (connstring_decode_level == 3) { + ndd.speed = 0; + if (sscanf(speed_s, "%10"PRIu32, &ndd.speed) != 1) { + // speed_s is not a number + free(ndd.port); + free(speed_s); + return NULL; + } + free(speed_s); + } if (connstring_decode_level < 2) { return NULL; } @@ -258,8 +220,10 @@ arygon_open(const nfc_context *context, const nfc_connstring connstring) log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Invalid serial port: %s", ndd.port); if (sp == CLAIMED_SERIAL_PORT) log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Serial port already claimed: %s", ndd.port); - if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) + if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) { + free(ndd.port); return NULL; + } // We need to flush input to be sure first reply does not comes from older byte transceive uart_flush_input(sp); @@ -269,6 +233,7 @@ arygon_open(const nfc_context *context, const nfc_connstring connstring) pnd = nfc_device_new(context, connstring); if (!pnd) { perror("malloc"); + free(ndd.port); return NULL; } snprintf(pnd->name, sizeof(pnd->name), "%s:%s", ARYGON_DRIVER_NAME, ndd.port); @@ -276,6 +241,7 @@ arygon_open(const nfc_context *context, const nfc_connstring connstring) pnd->driver_data = malloc(sizeof(struct arygon_data)); if (!pnd->driver_data) { perror("malloc"); + free(ndd.port); return NULL; } DRIVER_DATA(pnd)->port = sp; @@ -293,6 +259,7 @@ arygon_open(const nfc_context *context, const nfc_connstring connstring) #ifndef WIN32 // pipe-based abort mecanism if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) { + free(ndd.port); return NULL; } #else diff --git a/libnfc/drivers/pn532_uart.c b/libnfc/drivers/pn532_uart.c index 6816558..409b2e7 100644 --- a/libnfc/drivers/pn532_uart.c +++ b/libnfc/drivers/pn532_uart.c @@ -142,59 +142,10 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const } struct pn532_uart_descriptor { - char port[128]; + char *port; uint32_t speed; }; -static int -pn532_connstring_decode(const nfc_connstring connstring, struct pn532_uart_descriptor *desc) -{ - char *cs = malloc(strlen(connstring) + 1); - if (!cs) { - perror("malloc"); - return -1; - } - strcpy(cs, connstring); - const char *driver_name = strtok(cs, ":"); - if (!driver_name) { - // Parse error - free(cs); - return -1; - } - - if (0 != strcmp(driver_name, PN532_UART_DRIVER_NAME)) { - // Driver name does not match. - free(cs); - return 0; - } - - const char *port = strtok(NULL, ":"); - if (!port) { - // Only driver name was specified (or parsing error) - free(cs); - return 1; - } - strncpy(desc->port, port, sizeof(desc->port) - 1); - desc->port[sizeof(desc->port) - 1] = '\0'; - - const char *speed_s = strtok(NULL, ":"); - if (!speed_s) { - // speed not specified (or parsing error) - free(cs); - return 2; - } - unsigned long speed; - if (sscanf(speed_s, "%10lu", &speed) != 1) { - // speed_s is not a number - free(cs); - return 2; - } - desc->speed = speed; - - free(cs); - return 3; -} - static void pn532_uart_close(nfc_device *pnd) { @@ -209,6 +160,7 @@ pn532_uart_close(nfc_device *pnd) close(DRIVER_DATA(pnd)->iAbortFds[1]); #endif + free(DRIVER_DATA(pnd)->port); pn53x_data_free(pnd); nfc_device_free(pnd); } @@ -217,8 +169,18 @@ static nfc_device * pn532_uart_open(const nfc_context *context, const nfc_connstring connstring) { struct pn532_uart_descriptor ndd; - int connstring_decode_level = pn532_connstring_decode(connstring, &ndd); - + char *speed_s; + int connstring_decode_level = connstring_decode(connstring, PN532_UART_DRIVER_NAME, NULL, &ndd.port, &speed_s); + if (connstring_decode_level == 3) { + ndd.speed = 0; + if (sscanf(speed_s, "%10"PRIu32, &ndd.speed) != 1) { + // speed_s is not a number + free(ndd.port); + free(speed_s); + return NULL; + } + free(speed_s); + } if (connstring_decode_level < 2) { return NULL; } @@ -235,9 +197,10 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring) log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Invalid serial port: %s", ndd.port); if (sp == CLAIMED_SERIAL_PORT) log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Serial port already claimed: %s", ndd.port); - if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) + if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) { + free(ndd.port); return NULL; - + } // We need to flush input to be sure first reply does not comes from older byte transceive uart_flush_input(sp); uart_set_speed(sp, ndd.speed); @@ -246,6 +209,7 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring) pnd = nfc_device_new(context, connstring); if (!pnd) { perror("malloc"); + free(ndd.port); return NULL; } snprintf(pnd->name, sizeof(pnd->name), "%s:%s", PN532_UART_DRIVER_NAME, ndd.port); @@ -253,6 +217,7 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring) pnd->driver_data = malloc(sizeof(struct pn532_uart_data)); if (!pnd->driver_data) { perror("malloc"); + free(ndd.port); return NULL; } DRIVER_DATA(pnd)->port = sp; @@ -271,6 +236,7 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring) #ifndef WIN32 // pipe-based abort mecanism if (pipe(DRIVER_DATA(pnd)->iAbortFds) < 0) { + free(ndd.port); return NULL; } #else @@ -281,6 +247,7 @@ pn532_uart_open(const nfc_context *context, const nfc_connstring connstring) if (pn53x_check_communication(pnd) < 0) { nfc_perror(pnd, "pn53x_check_communication"); pn532_uart_close(pnd); + free(ndd.port); return NULL; } diff --git a/libnfc/drivers/pn53x_usb.c b/libnfc/drivers/pn53x_usb.c index edc9eee..6ef3f16 100644 --- a/libnfc/drivers/pn53x_usb.c +++ b/libnfc/drivers/pn53x_usb.c @@ -232,50 +232,6 @@ struct pn53x_usb_descriptor { char *filename; }; -static int -pn53x_usb_connstring_decode(const nfc_connstring connstring, struct pn53x_usb_descriptor *desc) -{ - int n = strlen(connstring) + 1; - char *driver_name = malloc(n); - if (!driver_name) { - perror("malloc"); - return 0; - } - char *dirname = malloc(n); - if (!dirname) { - perror("malloc"); - free(driver_name); - return 0; - } - char *filename = malloc(n); - if (!filename) { - perror("malloc"); - free(driver_name); - free(dirname); - return 0; - } - - driver_name[0] = '\0'; - - char format[32]; - snprintf(format, sizeof(format), "%%%i[^:]:%%%i[^:]:%%%i[^:]", n - 1, n - 1, n - 1); - int res = sscanf(connstring, format, driver_name, dirname, filename); - - if (!res || ((0 != strcmp(driver_name, PN53X_USB_DRIVER_NAME)) && (0 != strcmp(driver_name, "usb")))) { - // Driver name does not match. - res = 0; - } else { - desc->dirname = strdup(dirname); - desc->filename = strdup(filename); - } - - free(driver_name); - free(dirname); - free(filename); - - return res; -} - bool pn53x_usb_get_usb_device_name(struct usb_device *dev, usb_dev_handle *udev, char *buffer, size_t len) { @@ -309,7 +265,7 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring) { nfc_device *pnd = NULL; struct pn53x_usb_descriptor desc = { NULL, NULL }; - int connstring_decode_level = pn53x_usb_connstring_decode(connstring, &desc); + int connstring_decode_level = connstring_decode(connstring, PN53X_USB_DRIVER_NAME, "usb", &desc.dirname, &desc.filename); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%d element(s) have been decoded from \"%s\"", connstring_decode_level, connstring); if (connstring_decode_level < 1) { goto free_mem; diff --git a/libnfc/nfc-internal.c b/libnfc/nfc-internal.c index 715c7ff..39d7f2e 100644 --- a/libnfc/nfc-internal.c +++ b/libnfc/nfc-internal.c @@ -185,3 +185,67 @@ prepare_initiator_data(const nfc_modulation nm, uint8_t **ppbtInitiatorData, siz break; } } + +int +connstring_decode(const nfc_connstring connstring, const char *driver_name, const char *bus_name, char **pparam1, char **pparam2) +{ + if (driver_name == NULL) { + driver_name = ""; + } + if (bus_name == NULL) { + bus_name = ""; + } + int n = strlen(connstring) + 1; + char *param0 = malloc(n); + if (param0 == NULL) { + perror("malloc"); + return 0; + } + char *param1 = malloc(n); + if (param1 == NULL) { + perror("malloc"); + free(param0); + return 0; + } + char *param2 = malloc(n); + if (param2 == NULL) { + perror("malloc"); + free(param0); + free(param1); + return 0; + } + + char format[32]; + snprintf(format, sizeof(format), "%%%i[^:]:%%%i[^:]:%%%i[^:]", n - 1, n - 1, n - 1); + int res = sscanf(connstring, format, param0, param1, param2); + + if (res < 1 || ((0 != strcmp(param0, driver_name)) && + (bus_name != NULL) && + (0 != strcmp(param0, bus_name)))) { + // Driver name does not match. + res = 0; + } + if (pparam1 != NULL) { + if (res < 2) { + free(param1); + *pparam1 = NULL; + } else { + *pparam1 = param1; + } + } else { + free(param1); + } + if (pparam2 != NULL) { + if (res < 3) { + free(param2); + *pparam2 = NULL; + } else { + *pparam2 = param2; + } + } else { + free(param2); + } + free(param0); + return res; +} + diff --git a/libnfc/nfc-internal.h b/libnfc/nfc-internal.h index 1a5eec4..f0f396d 100644 --- a/libnfc/nfc-internal.h +++ b/libnfc/nfc-internal.h @@ -215,4 +215,6 @@ void iso14443_cascade_uid(const uint8_t abtUID[], const size_t szUID, uint8_t *p void prepare_initiator_data(const nfc_modulation nm, uint8_t **ppbtInitiatorData, size_t *pszInitiatorData); +int connstring_decode(const nfc_connstring connstring, const char *driver_name, const char *bus_name, char **pparam1, char **pparam2); + #endif // __NFC_INTERNAL_H__