From: Josef 'Jupp' Schugt Date: 2003-06-14T03:46:08+09:00 Subject: Hispeed String concat / Failsafe (RE)ALLOC_N usage? Saluton! This message contains a C implementation of a string buffer (see below). It is an alpha version because I have no information about the behavior of ALLOC_N and REALLOC_N in the case of a memory allocation failure - I didn't find any documentation on that topic. Besides that it seems to be bullet-proof (I use it to to concatenate chunks of all mails I download from my POP3 accounts - which is the reason why I want to avoid vulnerabilities). As every C programmer knows not checking the return value of 'malloc' is a vulnerability to be exploited. In the case of the Rubyish routines ALLOC_N and REALLOC_N two different behaviors are equally likely: - return NULL buffer in the same way as plain C functions do - raise an exception I did assume the latter but if the former is true that will mean the code given below is vulnerable to exploits! * Dominik Werder; 2003-06-13, 13:18 UTC: > What is the fastest way to add many small Strings to a big buffer? Follows my C version for that problem: 'new' set size of buffer, append does append to it (if capacity is too slow it is automagically increased), get gets whole buffer. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #include #include VALUE cStorage; char *m = NULL; char *end = NULL; int capacity = 0; static VALUE resize(VALUE, VALUE); static VALUE new(VALUE self, VALUE size) { resize(self, size); *m = '\0'; end = m; return self; } static VALUE resize(VALUE self, VALUE size) { int chars; Check_Type(size, T_FIXNUM); chars = NUM2ULONG(size); if (!m) { m = ALLOC_N(char, chars + 1); capacity = chars; } else if (capacity < chars) { REALLOC_N(m, char, chars + 1); capacity = chars; } return self; } static VALUE append(VALUE self, VALUE text) { int len; char * str; Check_Type(text, T_STRING); str = STR2CSTR(text); len = strlen(str); if (end - m + len > capacity) resize(self, end - m + len); strcat(end, str); end += len; return self; } static VALUE get(VALUE self) { return rb_str_new2(m); } void Init_Storage() { cStorage = rb_define_module("Storage"); rb_define_module_function(cStorage, "new", new, 1); rb_define_module_function(cStorage, "append", append, 1); rb_define_module_function(cStorage, "get", get, 0); } -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Gis, Josef 'Jupp' Schugt