From 94c8faab9f5b7dfcf11b6a0084cf54029badb125 Mon Sep 17 00:00:00 2001 From: Jan Breuer <jan.breuer@jaybee.cz> Date: 周日, 24 4月 2016 18:25:36 +0800 Subject: [PATCH] Fix tests for device dependent info, convert to strndup, fix out of bounds access --- libscpi/inc/scpi/error.h | 2 libscpi/inc/scpi/types.h | 2 libscpi/src/parser.c | 10 ++-- libscpi/inc/scpi/config.h | 25 ++++++------ libscpi/src/utils_private.h | 4 +- libscpi/src/error.c | 8 ++-- libscpi/test/test_parser.c | 8 ++++ libscpi/src/utils.c | 11 ++--- 8 files changed, 39 insertions(+), 31 deletions(-) diff --git a/libscpi/inc/scpi/config.h b/libscpi/inc/scpi/config.h index 94bf67d..ee07954 100644 --- a/libscpi/inc/scpi/config.h +++ b/libscpi/inc/scpi/config.h @@ -90,13 +90,14 @@ #endif #ifndef USE_DEVICE_DEPENDENT_ERROR_INFORMATION -#define USE_DEVICE_DEPENDENT_ERROR_INFORMATION 0 +#define USE_DEVICE_DEPENDENT_ERROR_INFORMATION SYSTEM_TYPE +#endif + +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION #ifndef USE_MEMORY_ALLOCATION_FREE #define USE_MEMORY_ALLOCATION_FREE 1 #endif #endif - - #ifndef USE_COMMAND_TAGS #define USE_COMMAND_TAGS 1 @@ -266,18 +267,18 @@ #include <stdlib.h> #include <string.h> #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 2 -#define SCPIDEFINE_strdup(h, s) strdup((s)) -#define SCPIDEFINE_free(h, s, r) free((s)) +#define SCPIDEFINE_strndup(h, s, l) strndup((s), (l)) +#define SCPIDEFINE_free(h, s, r) free((s)) #else -#define SCPIDEFINE_DESCRIPTION_MAX_PARTS 3 -#define SCPIDEFINE_strdup(h, s) OUR_strdup((h), (s)) -#define SCPIDEFINE_free(h, s, r) OUR_free((h), (s), (r)) -#define SCPIDEFINE_get_parts(h, s, l1, s2, l2) OUR_get_parts((h), (s), (l1), (s2), (l2)) +#define SCPIDEFINE_DESCRIPTION_MAX_PARTS 3 +#define SCPIDEFINE_strndup(h, s, l) OUR_strndup((h), (s), (l)) +#define SCPIDEFINE_free(h, s, r) OUR_free((h), (s), (r)) +#define SCPIDEFINE_get_parts(h, s, l1, s2, l2) OUR_get_parts((h), (s), (l1), (s2), (l2)) #endif #else -#define SCPIDEFINE_DESCRIPTION_MAX_PARTS 1 -#define SCPIDEFINE_strdup(h, s) NULL -#define SCPIDEFINE_free(h, s, r) (void) +#define SCPIDEFINE_DESCRIPTION_MAX_PARTS 1 +#define SCPIDEFINE_strdup(h, s, l) NULL +#define SCPIDEFINE_free(h, s, r) (void) #endif #ifdef __cplusplus diff --git a/libscpi/inc/scpi/error.h b/libscpi/inc/scpi/error.h index 2b15e7c..6c7d744 100644 --- a/libscpi/inc/scpi/error.h +++ b/libscpi/inc/scpi/error.h @@ -47,7 +47,7 @@ void SCPI_ErrorInit(scpi_t * context, scpi_error_t * data, int16_t size); void SCPI_ErrorClear(scpi_t * context); scpi_bool_t SCPI_ErrorPop(scpi_t * context, scpi_error_t * error); - void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info); + void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info, size_t info_len); void SCPI_ErrorPush(scpi_t * context, int16_t err); int32_t SCPI_ErrorCount(scpi_t * context); const char * SCPI_ErrorTranslate(int16_t err); diff --git a/libscpi/inc/scpi/types.h b/libscpi/inc/scpi/types.h index fb9d438..a9f3cfe 100644 --- a/libscpi/inc/scpi/types.h +++ b/libscpi/inc/scpi/types.h @@ -212,7 +212,7 @@ struct _scpi_error_t { int16_t error_code; - const char * device_dependent_info; + char * device_dependent_info; }; typedef struct _scpi_error_t scpi_error_t; diff --git a/libscpi/src/error.c b/libscpi/src/error.c index 8913ab8..3b9ca01 100644 --- a/libscpi/src/error.c +++ b/libscpi/src/error.c @@ -128,7 +128,7 @@ error_value.device_dependent_info = info; if (!fifo_add(&context->error_queue, &error_value)) { fifo_remove_last(&context->error_queue, &error_value); - // TODO free device_dependent_info + SCPIDEFINE_free(&context->error_info_heap, error_value.device_dependent_info, false); error_value.error_code = SCPI_ERROR_QUEUE_OVERFLOW; error_value.device_dependent_info = NULL; fifo_add(&context->error_queue, &error_value); @@ -162,13 +162,13 @@ * @param context - scpi context * @param err - error number */ -void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info) { +void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info, size_t info_len) { int i; char * info_ptr = NULL; #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION if (info) { - info_ptr = SCPIDEFINE_strdup(&context->error_info_heap, info); + info_ptr = SCPIDEFINE_strndup(&context->error_info_heap, info, info_len); } #endif @@ -199,7 +199,7 @@ * @param err - error number */ void SCPI_ErrorPush(scpi_t * context, int16_t err) { - SCPI_ErrorPushEx(context, err, NULL); + SCPI_ErrorPushEx(context, err, NULL, 0); return; } diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c index 6d7f8a9..6ced497 100644 --- a/libscpi/src/parser.c +++ b/libscpi/src/parser.c @@ -219,11 +219,11 @@ result &= processCommand(context); cmd_prev = state->programHeader; } else { - /* test */ /* place undefined header with error */ - data[r ? (r - 1) : r] = 0; - SCPI_ErrorPushEx(context, SCPI_ERROR_UNDEFINED_HEADER, data); - //SCPI_ErrorPush(context, SCPI_ERROR_UNDEFINED_HEADER); + /* calculate length of errornouse header and trim \r\n */ + size_t r2 = r; + while(r2 > 0 && (data[r2 - 1] == '\r' || data[r2 - 1] == '\n')) r2--; + SCPI_ErrorPushEx(context, SCPI_ERROR_UNDEFINED_HEADER, data, r2); result = FALSE; } } @@ -547,7 +547,7 @@ result += writeDelimiter(context); result += writeData(context, "\"", 1); - for (i = 0; data[i] && outputlimit && (i < SCPIDEFINE_DESCRIPTION_MAX_PARTS); i++) { + for (i = 0; (i < SCPIDEFINE_DESCRIPTION_MAX_PARTS) && data[i] && outputlimit; i++) { if (i == 1) { result += writeSemicolon(context); outputlimit -= 1; diff --git a/libscpi/src/utils.c b/libscpi/src/utils.c index 99dfd06..ae2c2c6 100644 --- a/libscpi/src/utils.c +++ b/libscpi/src/utils.c @@ -760,7 +760,7 @@ * @param s - current pointer of duplication string * @return - pointer of duplicated string or NULL, if duplicate is not possible. */ -char * OUR_strdup(scpi_error_info_heap_t * heap, const char *s) { +char * OUR_strndup(scpi_error_info_heap_t * heap, const char *s, size_t n) { if (!s || !heap) { return NULL; } @@ -773,14 +773,13 @@ return NULL; } - size_t len = strlen(s) + 1; // additional '\0' at end + size_t len = SCPIDEFINE_strnlen(s, n) + 1; // additional '\0' at end if (len > heap->count) { return NULL; } - char * ptrs = s; + const char * ptrs = s; char * head = &heap->data[heap->wr]; size_t rem = heap->size - (&heap->data[heap->wr] - heap->data); - size_t sstp = 0; if (len >= rem) { memcpy(&heap->data[heap->wr], s, rem); @@ -836,14 +835,14 @@ * @param s - pointer of duplicate string * @param rollback - backward write pointer in heap */ -void OUR_free(scpi_error_info_heap_t * heap, const char * s, scpi_bool_t rollback) { +void OUR_free(scpi_error_info_heap_t * heap, char * s, scpi_bool_t rollback) { if (!s) return; char * data_add; size_t len[2]; - if (!OUR_get_parts(heap, s, &len[0], &data_add, &len[1])) return; + if (!OUR_get_parts(heap, s, &len[0], (const char **)&data_add, &len[1])) return; if (data_add) { len[1]++; diff --git a/libscpi/src/utils_private.h b/libscpi/src/utils_private.h index 09aad22..9252dcc 100644 --- a/libscpi/src/utils_private.h +++ b/libscpi/src/utils_private.h @@ -88,8 +88,8 @@ #endif #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE - char * OUR_strdup(scpi_error_info_heap_t * heap, const char *s) LOCAL; - void OUR_free(scpi_error_info_heap_t * heap, const char *s, scpi_bool_t rollback) LOCAL; + char * OUR_strndup(scpi_error_info_heap_t * heap, const char *s, size_t n) LOCAL; + void OUR_free(scpi_error_info_heap_t * heap, char *s, scpi_bool_t rollback) LOCAL; scpi_bool_t OUR_get_parts(scpi_error_info_heap_t * heap, const char *s1, size_t * len1, const char ** s2, size_t * len2) LOCAL; #endif diff --git a/libscpi/test/test_parser.c b/libscpi/test/test_parser.c index f08f692..bc11f74 100644 --- a/libscpi/test/test_parser.c +++ b/libscpi/test/test_parser.c @@ -328,7 +328,11 @@ TEST_IEEE4882("*ESR?\r\n", "0\r\n"); TEST_IEEE4882("SYST:ERR:COUNT?\r\n", "1\r\n"); +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION + TEST_IEEE4882("SYST:ERR:NEXT?\r\n", "-113,\"Undefined header;ABCD\"\r\n"); +#else /* USE_DEVICE_DEPENDENT_ERROR_INFORMATION */ TEST_IEEE4882("SYST:ERR:NEXT?\r\n", "-113,\"Undefined header\"\r\n"); +#endif /* USE_DEVICE_DEPENDENT_ERROR_INFORMATION */ TEST_IEEE4882("SYST:ERR:NEXT?\r\n", "0,\"No error\"\r\n"); TEST_IEEE4882("*STB?\r\n", "0\r\n"); /* Error queue is now empty */ @@ -339,7 +343,11 @@ CU_ASSERT_EQUAL(srq_val, 0); /* no control callback */ TEST_IEEE4882("*STB?\r\n", "100\r\n"); /* Event status register + Service request */ TEST_IEEE4882("*ESR?\r\n", "32\r\n"); /* Command error */ +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION + TEST_IEEE4882("SYST:ERR:NEXT?\r\n", "-113,\"Undefined header;ABCD\"\r\n"); +#else /* USE_DEVICE_DEPENDENT_ERROR_INFORMATION */ TEST_IEEE4882("SYST:ERR:NEXT?\r\n", "-113,\"Undefined header\"\r\n"); +#endif /* USE_DEVICE_DEPENDENT_ERROR_INFORMATION */ scpi_context.interface->control = SCPI_Control; RST_executed = FALSE; -- Gitblit v1.9.1