Jan Breuer
2016-04-24 94c8faab9f5b7dfcf11b6a0084cf54029badb125
Fix tests for device dependent info, convert to strndup, fix out of bounds access
8个文件已修改
58 ■■■■■ 已修改文件
libscpi/inc/scpi/config.h 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/inc/scpi/error.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/inc/scpi/types.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/src/error.c 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/src/parser.c 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/src/utils.c 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/src/utils_private.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libscpi/test/test_parser.c 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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,17 +267,17 @@
#include <stdlib.h>
#include <string.h>
#define SCPIDEFINE_DESCRIPTION_MAX_PARTS        2
#define SCPIDEFINE_strdup(h, s)                    strdup((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_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_strdup(h, s, l)                      NULL
#define SCPIDEFINE_free(h, s, r)                (void)
#endif
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);
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;
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;
}
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;
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]++;
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
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;