From ae43769789cf11c7b13fdc648bcec5f91d8b6e3e Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Thu, 10 Feb 2005 22:30:59 +0000 Subject: [PATCH] Added overflow-safe string functions allocating everything on the stack. Actually, they are all macros, but passing parameters with side-effects should be safe, because they are always evaluated exactly once. --- lib/Makefile | 5 ++-- lib/stkstring.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/stkstring.h | 23 +++++++++++++++++ lib/stkstring.t | 4 +++ 4 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 lib/stkstring.c create mode 100644 lib/stkstring.h create mode 100644 lib/stkstring.t diff --git a/lib/Makefile b/lib/Makefile index deb40b0b..390a3794 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -15,7 +15,7 @@ LIBUCW_MODS= \ profile \ fastbuf ff-printf ff-utf8 \ fb-file carefulio fb-mem fb-temp fb-mmap fb-limfd fb-buffer \ - str_ctype str_upper str_lower unicode-utf8 \ + str_ctype str_upper str_lower unicode-utf8 stkstring \ wildmatch wordsplit ctmatch patimatch patmatch regex \ prime random timer log2 randomkey \ db \ @@ -51,11 +51,12 @@ obj/lib/redblack-test: obj/lib/redblack-test.o $(LIBUCW) obj/lib/binheap-test: obj/lib/binheap-test.o $(LIBUCW) obj/lib/lizard-test: obj/lib/lizard-test.o $(LIBUCW) -TESTS+=$(addprefix obj/lib/,regex.test unicode-utf8.test hash-test.test mempool.test) +TESTS+=$(addprefix obj/lib/,regex.test unicode-utf8.test hash-test.test mempool.test stkstring.test) obj/lib/regex.test: obj/lib/regex-t obj/lib/unicode-utf8.test: obj/lib/unicode-utf8-t obj/lib/hash-test.test: obj/lib/hash-test obj/lib/mempool.test: obj/lib/mempool-fmt-t obj/lib/mempool-str-t +obj/lib/stkstring.test: obj/lib/stkstring-t ifdef CONFIG_UCW_PERL include lib/perl/Makefile diff --git a/lib/stkstring.c b/lib/stkstring.c new file mode 100644 index 00000000..31623747 --- /dev/null +++ b/lib/stkstring.c @@ -0,0 +1,67 @@ +#include "lib/lib.h" +#include "lib/stkstring.h" + +#include + +uns +stk_array_len(char **s, uns cnt) +{ + uns l = 1; + while (cnt--) + l += strlen(*s++); + return l; +} + +void +stk_array_copy(char *x, char **s, uns cnt) +{ + while (cnt--) + { + uns l = strlen(*s); + memcpy(x, *s, l); + x += l; + s++; + } + *x = 0; +} + +char *stk_printf_buf; +static int stk_printf_len; + +uns +stk_printf_internal(char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + if (!stk_printf_buf) + { + stk_printf_buf = xmalloc(256); + stk_printf_len = 256; + } + for (;;) + { + int l = vsnprintf(stk_printf_buf, stk_printf_len, fmt, args); + if (l < 0) + stk_printf_len *= 2; + else if (l < stk_printf_len) + return l+1; + else + stk_printf_len = MAX(stk_printf_len*2, l+1); + } +} + +#ifdef TEST + +int main(void) +{ + char *a = stk_strdup("are"); + a = stk_strcat(a, " the "); + a = stk_strmulticat(a, "Jabberwock, ", "my", NULL); + char *arr[] = { a, " son" }; + a = stk_strarraycat(arr, 2); + a = stk_printf("Bew%s!", a); + puts(a); + return 0; +} + +#endif diff --git a/lib/stkstring.h b/lib/stkstring.h new file mode 100644 index 00000000..75508fbb --- /dev/null +++ b/lib/stkstring.h @@ -0,0 +1,23 @@ +/* + * UCW Library -- Strings Allocated on the Stack + * + * (c) 2005 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#include +#include + +#define stk_strdup(s) ({ char *_s=(s); uns _l=strlen(_s)+1; char *_x=alloca(_l); memcpy(_x, _s, _l); _x; }) +#define stk_strcat(s1,s2) ({ char *_s1=(s1); char *_s2=(s2); uns _l1=strlen(_s1); uns _l2=strlen(_s2); char *_x=alloca(_l1+_l2+1); memcpy(_x,_s1,_l1); memcpy(_x+_l1,_s2,_l2+1); _x; }) +#define stk_strmulticat(s...) ({ char *_s[]={s}; char *_x=alloca(stk_array_len(_s, ARRAY_SIZE(_s)-1)); stk_array_copy(_x, _s, ARRAY_SIZE(_s)-1); _x; }) +#define stk_strarraycat(s,n) ({ char **_s=(s); int _n=(n); char *_x=alloca(stk_array_len(_s,_n)); stk_array_copy(_x, _s, _n); _x; }) +#define stk_printf(f...) ({ uns _l=stk_printf_internal(f); char *_x=alloca(_l); memcpy(_x, stk_printf_buf, _l); _x; }) + +uns stk_array_len(char **s, uns cnt); +void stk_array_copy(char *x, char **s, uns cnt); +uns stk_printf_internal(char *x, ...); + +extern char *stk_printf_buf; diff --git a/lib/stkstring.t b/lib/stkstring.t new file mode 100644 index 00000000..62f00477 --- /dev/null +++ b/lib/stkstring.t @@ -0,0 +1,4 @@ +# Tests for stkstring modules + +Run: obj/lib/stkstring-t +Out: Beware the Jabberwock, my son! -- 2.39.2