From 169c05cc1529d3165aaa5d14a41e45db6a75b48a Mon Sep 17 00:00:00 2001 From: QC Date: Fri, 29 Aug 2014 12:14:43 +0200 Subject: [PATCH] Fix crash in history when removing last entry. --- source/history.c | 4 +- test/Makefile | 13 ++++++ test/history-test.c | 100 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 test/Makefile create mode 100644 test/history-test.c diff --git a/source/history.c b/source/history.c index 779f6e1b..1d1ffd7f 100644 --- a/source/history.c +++ b/source/history.c @@ -52,7 +52,7 @@ static int __element_sort_func ( const void *ea, const void *eb ) static void __history_write_element_list ( FILE *fd, _element **list, unsigned int length ) { - if ( list == NULL ) { + if ( list == NULL || length == 0 ) { return; } // Sort the list before writing out. @@ -235,6 +235,8 @@ void history_remove ( const char *filename, const char *entry ) char ** history_get_list ( const char *filename, unsigned int *length ) { + *length = 0; + if ( config.disable_history ) { return NULL; } diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 00000000..26bb0aea --- /dev/null +++ b/test/Makefile @@ -0,0 +1,13 @@ +CC=gcc +CFLAGS=-I../include/ -I../ -std=c99 -fprofile-arcs -ftest-coverage -g3 +SOURCES=\ + history-test.c\ + ../config/config.c\ + ../source/history.c + +history-test: $(SOURCES) + $(CC) -o $@ $^ `pkg-config --libs --cflags glib-2.0` $(CFLAGS) + + +test: history-test + ./$^ diff --git a/test/history-test.c b/test/history-test.c new file mode 100644 index 00000000..7d6f34f0 --- /dev/null +++ b/test/history-test.c @@ -0,0 +1,100 @@ +#include + +#include +#include +#include +#include +#include + + +static int test = 0; + +#define TASSERT(a) {\ + assert ( a );\ + printf("Test %i passed (%s)\n", ++test, #a);\ +} + +const char *file = "text"; + +int main ( int argc, char **argv ) +{ + unlink(file); + + // Empty list. + unsigned int length= 0; + char **retv = history_get_list ( file, &length); + + TASSERT ( retv == NULL ); + TASSERT ( length == 0 ); + + // 1 item + history_set( file, "aap"); + + retv = history_get_list ( file, &length); + + TASSERT ( retv != NULL ); + TASSERT ( length == 1 ); + + TASSERT ( strcmp(retv[0], "aap") == 0 ); + + g_strfreev(retv); + + // Remove entry + history_remove ( file, "aap" ); + + length= 0; + retv = history_get_list ( file, &length); + + TASSERT ( retv == NULL ); + TASSERT ( length == 0 ); + + // 2 items + history_set( file, "aap"); + history_set( file, "aap"); + + retv = history_get_list ( file, &length); + + TASSERT ( retv != NULL ); + TASSERT ( length == 1 ); + + TASSERT ( strcmp(retv[0], "aap") == 0 ); + + g_strfreev(retv); + + for(int in=length+1; in < 26; in++) { + char *p = g_strdup_printf("aap%i", in); + printf("%s- %d\n",p, in); + history_set( file, p); + retv = history_get_list ( file, &length); + + TASSERT ( retv != NULL ); + TASSERT ( length == (in) ); + + g_strfreev(retv); + + g_free(p); + } + // Max 25 entries. + history_set( file, "blaat" ); + retv = history_get_list ( file, &length); + + TASSERT ( retv != NULL ); + TASSERT ( length == 25 ); + + g_strfreev(retv); + + // Test fail. + history_set ( NULL, "aap"); + + retv = history_get_list ( NULL , &length); + printf("Test %i passed\n", ++test); + + TASSERT ( retv == NULL ); + TASSERT ( length == 0 ); + + history_remove ( NULL, "aap" ); + printf("Test %i passed\n", ++test); + + + return 0; +}