]> mj.ucw.cz Git - libucw.git/commitdiff
Added overflow-safe string functions allocating everything on the stack.
authorMartin Mares <mj@ucw.cz>
Thu, 10 Feb 2005 22:30:59 +0000 (22:30 +0000)
committerMartin Mares <mj@ucw.cz>
Thu, 10 Feb 2005 22:30:59 +0000 (22:30 +0000)
Actually, they are all macros, but passing parameters with side-effects
should be safe, because they are always evaluated exactly once.

lib/Makefile
lib/stkstring.c [new file with mode: 0644]
lib/stkstring.h [new file with mode: 0644]
lib/stkstring.t [new file with mode: 0644]

index deb40b0bcd813f0adad65803b3f4f5fafea1d5e1..390a37942167753d1d4d8fb60e880b484c54c2ff 100644 (file)
@@ -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 (file)
index 0000000..3162374
--- /dev/null
@@ -0,0 +1,67 @@
+#include "lib/lib.h"
+#include "lib/stkstring.h"
+
+#include <stdio.h>
+
+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 (file)
index 0000000..75508fb
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ *     UCW Library -- Strings Allocated on the Stack
+ *
+ *     (c) 2005 Martin Mares <mj@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+#include <alloca.h>
+#include <string.h>
+
+#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 (file)
index 0000000..62f0047
--- /dev/null
@@ -0,0 +1,4 @@
+# Tests for stkstring modules
+
+Run:   obj/lib/stkstring-t
+Out:   Beware the Jabberwock, my son!