char *p_strconcat(pool_t pool, const char *str1, ...) { va_list args; char *temp, *ret; size_t len; i_assert(str1 != NULL); va_start(args, str1); if (pool->datastack_pool) { ret = vstrconcat(str1, args, &len); t_buffer_alloc(len); } else { T_BEGIN { temp = vstrconcat(str1, args, &len); t_buffer_alloc(len); ret = p_malloc(pool, len); memcpy(ret, temp, len); } T_END; } va_end(args); return ret; }
static const char * driver_mysql_escape_string(struct sql_db *_db, const char *string) { struct mysql_db *db = (struct mysql_db *)_db; size_t len = strlen(string); char *to; if (_db->state == SQL_DB_STATE_DISCONNECTED) { /* try connecting */ (void)sql_connect(&db->api); } if (db->mysql == NULL) { /* FIXME: we don't have a valid connection, so fallback to using default escaping. the next query will most likely fail anyway so it shouldn't matter that much what we return here.. Anyway, this API needs changing so that the escaping function could already fail the query reliably. */ to = t_buffer_get(len * 2 + 1); len = mysql_escape_string(to, string, len); t_buffer_alloc(len + 1); return to; } to = t_buffer_get(len * 2 + 1); len = mysql_real_escape_string(db->mysql, to, string, len); t_buffer_alloc(len + 1); return to; }
static char * p_strarray_join_n(pool_t pool, const char *const *arr, unsigned int arr_len, const char *separator) { size_t alloc_len, sep_len, len, pos, needed_space; unsigned int i; char *str; sep_len = strlen(separator); alloc_len = 64; str = t_buffer_get(alloc_len); pos = 0; for (i = 0; i < arr_len; i++) { len = strlen(arr[i]); needed_space = pos + len + sep_len + 1; if (needed_space > alloc_len) { alloc_len = nearest_power(needed_space); str = t_buffer_reget(str, alloc_len); } if (pos != 0) { memcpy(str + pos, separator, sep_len); pos += sep_len; } memcpy(str + pos, arr[i], len); pos += len; } str[pos] = '\0'; if (!pool->datastack_pool) return p_memdup(pool, str, pos + 1); t_buffer_alloc(pos + 1); return str; }
char *p_strdup_vprintf(pool_t pool, const char *format, va_list args) { char *tmp, *buf; unsigned int size; tmp = t_noalloc_strdup_vprintf(format, args, &size); if (pool->datastack_pool) { t_buffer_alloc(size); return tmp; } else { buf = p_malloc(pool, size); memcpy(buf, tmp, size - 1); return buf; } }
const char *t_strconcat(const char *str1, ...) { va_list args; const char *ret; size_t len; va_start(args, str1); ret = vstrconcat(str1, args, &len); if (ret != NULL) t_buffer_alloc(len); va_end(args); return ret; }
const char *t_strflocaltime(const char *fmt, time_t t) { const struct tm *tm; size_t bufsize = strlen(fmt) + 32; char *buf = t_buffer_get(bufsize); size_t ret; tm = localtime(&t); while ((ret = strftime(buf, bufsize, fmt, tm)) == 0) { bufsize *= 2; i_assert(bufsize <= STRFTIME_MAX_BUFSIZE); buf = t_buffer_get(bufsize); } t_buffer_alloc(ret + 1); return buf; }
int t_get_current_dir(const char **dir_r) { /* @UNSAFE */ char *dir; size_t size = 128; dir = t_buffer_get(size); while (getcwd(dir, size) == NULL) { if (errno != ERANGE) return -1; size = nearest_power(size+1); dir = t_buffer_get(size); } t_buffer_alloc(strlen(dir) + 1); *dir_r = dir; return 0; }
int t_readlink(const char *path, const char **dest_r) { /* @UNSAFE */ ssize_t ret; char *dest; size_t size = 128; dest = t_buffer_get(size); while ((ret = readlink(path, dest, size)) >= (ssize_t)size) { size = nearest_power(size+1); dest = t_buffer_get(size); } if (ret < 0) return -1; dest[ret] = '\0'; t_buffer_alloc(ret + 1); *dest_r = dest; return 0; }
char *i_strconcat(const char *str1, ...) { va_list args; char *ret; size_t len; va_start(args, str1); T_BEGIN { const char *temp = vstrconcat(str1, args, &len); if (temp == NULL) ret = NULL; else { t_buffer_alloc(len); ret = p_malloc(default_pool, len); memcpy(ret, temp, len); } } T_END; va_end(args); return ret; }
static void test_ds_recurse(int depth, int number, size_t size) { int i; char **ps; char tag[2] = { depth+1, '\0' }; int try_fails = 0; data_stack_frame_t t_id = t_push_named("test_ds_recurse[%i]", depth); ps = t_buffer_get(sizeof(char *) * number); i_assert(ps != NULL); t_buffer_alloc(sizeof(char *) * number); for (i = 0; i < number; i++) { ps[i] = t_malloc_no0(size/2); bool re = t_try_realloc(ps[i], size); i_assert(ps[i] != NULL); if (!re) { try_fails++; ps[i] = t_malloc_no0(size); } /* drop our own canaries */ memset(ps[i], tag[0], size); ps[i][size-2] = 0; } /* Do not expect a high failure rate from t_try_realloc */ test_assert_idx(try_fails <= number / 20, depth); /* Now recurse... */ if(depth>0) test_ds_recurse(depth-1, number, size); /* Test our canaries are still intact */ for (i = 0; i < number; i++) { test_assert_idx(strspn(ps[i], tag) == size - 2, i); test_assert_idx(ps[i][size-1] == tag[0], i); } test_assert_idx(t_pop(&t_id), depth); }