1 #ifndef STRFUNC_H
2 #define STRFUNC_H
3 
4 /* Maximum number of bytes needed for the largest uintmax_t or the lowest
5    intmax_t number in base 10. This value includes the trailing \0. */
6 #define MAX_INT_STRLEN ((sizeof(uintmax_t) * CHAR_BIT + 2) / 3 + 1)
7 
8 extern const unsigned char uchar_nul; /* (const unsigned char *)"" */
9 extern const unsigned char *uchar_empty_ptr; /* non-NULL pointer that shouldn't be dereferenced. */
10 
11 /* Returns -1 if dest wasn't large enough, 0 if not. */
12 int i_snprintf(char *dest, size_t max_chars, const char *format, ...)
13 	ATTR_FORMAT(3, 4);
14 
15 char *p_strdup(pool_t pool, const char *str) ATTR_MALLOC;
16 void *p_memdup(pool_t pool, const void *data, size_t size) ATTR_MALLOC;
17 /* return NULL if str = "" */
18 char *p_strdup_empty(pool_t pool, const char *str) ATTR_MALLOC;
19 /* *end isn't included */
20 char *p_strdup_until(pool_t pool, const void *start, const void *end)
21 	ATTR_MALLOC ATTR_RETURNS_NONNULL;
22 char *p_strndup(pool_t pool, const void *str, size_t max_chars) ATTR_MALLOC;
23 char *p_strdup_printf(pool_t pool, const char *format, ...)
24 	ATTR_FORMAT(2, 3) ATTR_MALLOC ATTR_RETURNS_NONNULL;
25 char *p_strdup_vprintf(pool_t pool, const char *format, va_list args)
26 	ATTR_FORMAT(2, 0) ATTR_MALLOC ATTR_RETURNS_NONNULL;
27 char *p_strconcat(pool_t pool, const char *str1, ...)
28 	ATTR_SENTINEL ATTR_MALLOC;
29 
30 /* same with temporary memory allocations: */
31 const char *t_strdup(const char *str) ATTR_MALLOC;
32 char *t_strdup_noconst(const char *str) ATTR_MALLOC;
33 /* return NULL if str = "" */
34 const char *t_strdup_empty(const char *str) ATTR_MALLOC;
35 /* *end isn't included */
36 const char *t_strdup_until(const void *start, const void *end)
37 	ATTR_MALLOC ATTR_RETURNS_NONNULL;
38 const char *t_strndup(const void *str, size_t max_chars) ATTR_MALLOC;
39 const char *t_strdup_printf(const char *format, ...)
40 	ATTR_FORMAT(1, 2) ATTR_MALLOC ATTR_RETURNS_NONNULL;
41 const char *t_strdup_vprintf(const char *format, va_list args)
42 	ATTR_FORMAT(1, 0) ATTR_MALLOC ATTR_RETURNS_NONNULL;
43 const char *t_strconcat(const char *str1, ...)
44 	ATTR_SENTINEL ATTR_MALLOC;
45 
46 /* Like t_strdup(), but stop at cutchar. */
47 const char *t_strcut(const char *str, char cutchar);
48 /* Replace all from->to chars in the string. */
49 const char *t_str_replace(const char *str, char from, char to);
50 /* Put the string on a single line by replacing all newlines with spaces and
51    dropping any carriage returns. Sequences of several newlines are merged into
52    one space and newlines at the beginning and end of the string are dropped. */
53 const char *t_str_oneline(const char *str);
54 
55 /* Like strlcpy(), but return -1 if buffer was overflown, 0 if not. */
56 int i_strocpy(char *dest, const char *src, size_t dstsize);
57 
58 char *str_ucase(char *str);
59 char *str_lcase(char *str);
60 const char *t_str_lcase(const char *str);
61 const char *t_str_ucase(const char *str);
62 
63 /* Return pointer to first matching needle */
64 const char *i_strstr_arr(const char *haystack, const char *const *needles);
65 
66 /* Trim matching chars from either side of the string */
67 const char *t_str_trim(const char *str, const char *chars);
68 const char *p_str_trim(pool_t pool, const char *str, const char *chars);
69 const char *str_ltrim(const char *str, const char *chars);
70 const char *t_str_ltrim(const char *str, const char *chars);
71 const char *p_str_ltrim(pool_t pool, const char *str, const char *chars);
72 const char *t_str_rtrim(const char *str, const char *chars);
73 const char *p_str_rtrim(pool_t pool, const char *str, const char *chars);
74 
75 int null_strcmp(const char *s1, const char *s2) ATTR_PURE;
76 int null_strcasecmp(const char *s1, const char *s2) ATTR_PURE;
77 int i_memcasecmp(const void *p1, const void *p2, size_t size) ATTR_PURE;
78 int i_strcmp_p(const char *const *p1, const char *const *p2) ATTR_PURE;
79 int i_strcasecmp_p(const char *const *p1, const char *const *p2) ATTR_PURE;
80 /* Returns TRUE if the two memory areas are equal. This function is safe
81    against timing attacks, so it compares all the bytes every time. */
82 bool mem_equals_timing_safe(const void *p1, const void *p2, size_t size);
83 /* Returns TRUE if the two strings are equal. Similar to
84    mem_equals_timing_safe() this function is safe against timing attacks when
85    the string lengths are the same. If not, the length of the secret string may
86    be leaked, but otherwise the contents won't be. */
87 bool str_equals_timing_almost_safe(const char *s1, const char *s2);
88 
89 size_t str_match(const char *p1, const char *p2) ATTR_PURE;
str_begins(const char * haystack,const char * needle)90 static inline ATTR_PURE bool str_begins(const char *haystack, const char *needle)
91 {
92 	return needle[str_match(haystack, needle)] == '\0';
93 }
94 #if defined(__GNUC__) && (__GNUC__ >= 2)
95 /* GCC (and Clang) are known to have a compile-time strlen("literal") shortcut, and
96    an optimised strncmp(), so use that by default. Macro is multi-evaluation safe. */
97 # define str_begins(h, n) (__builtin_constant_p(n) ? strncmp((h), (n), strlen(n))==0 : (str_begins)((h), (n)))
98 #endif
99 
100 /* Get length of a prefix segment.
101 
102   Calculates the length (in bytes) of the initial segment of s which consists
103   entirely of bytes in accept.
104 */
105 size_t i_memspn(const void *data, size_t data_len,
106 		const void *accept, size_t accept_len);
107 /* Get length of a prefix segment.
108 
109   Calculates the length of the initial segment of s which consists entirely of
110   bytes not in reject.
111 */
112 size_t i_memcspn(const void *data, size_t data_len,
113 		 const void *reject, size_t reject_len);
114 
i_strchr_to_next(const char * str,char chr)115 static inline char *i_strchr_to_next(const char *str, char chr)
116 {
117 	char *tmp = (char *)strchr(str, chr);
118 	return tmp == NULL ? NULL : tmp+1;
119 }
120 
121 /* separators is an array of separator characters, not a separator string.
122    an empty data string results in an array containing only NULL. */
123 char **p_strsplit(pool_t pool, const char *data, const char *separators)
124 	ATTR_MALLOC ATTR_RETURNS_NONNULL;
125 const char **t_strsplit(const char *data, const char *separators)
126 	ATTR_MALLOC ATTR_RETURNS_NONNULL;
127 /* like p_strsplit(), but treats multiple adjacent separators as a single
128    separator. separators at the beginning or at the end of the string are also
129    ignored, so it's not possible for the result to have any empty strings. */
130 char **p_strsplit_spaces(pool_t pool, const char *data, const char *separators)
131 	ATTR_MALLOC ATTR_RETURNS_NONNULL;
132 const char **t_strsplit_spaces(const char *data, const char *separators)
133 	ATTR_MALLOC ATTR_RETURNS_NONNULL;
134 void p_strsplit_free(pool_t pool, char **arr);
135 
136 const char *dec2str(uintmax_t number);
137 /* Use the given buffer to write out the number. Returns pointer to the
138    written number in the buffer. Note that this isn't the same as the beginning
139    of the buffer. */
140 char *dec2str_buf(char buffer[STATIC_ARRAY MAX_INT_STRLEN], uintmax_t number);
141 
142 /* Return length of NULL-terminated list string array */
143 unsigned int str_array_length(const char *const *arr) ATTR_PURE;
144 /* Return all strings from array joined into one string. */
145 const char *t_strarray_join(const char *const *arr, const char *separator)
146 	ATTR_MALLOC ATTR_RETURNS_NONNULL;
147 /* Removes a value from NULL-terminated string array. Returns TRUE if found. */
148 bool str_array_remove(const char **arr, const char *value);
149 /* Returns TRUE if value exists in NULL-terminated string array. */
150 bool str_array_find(const char *const *arr, const char *value);
151 /* Like str_array_find(), but use strcasecmp(). */
152 bool str_array_icase_find(const char *const *arr, const char *value);
153 /* Duplicate array of strings. The memory can be freed by freeing the
154    return value. */
155 const char **p_strarray_dup(pool_t pool, const char *const *arr)
156 	ATTR_MALLOC ATTR_RETURNS_NONNULL;
157 
158 /* Join ARRAY_TYPE(const_string) to a string, similar to t_strarray_join() */
159 char *p_array_const_string_join(pool_t pool, const ARRAY_TYPE(const_string) *arr,
160 				const char *separator);
161 #define t_array_const_string_join(arr, separator) \
162 	((const char *)p_array_const_string_join(unsafe_data_stack_pool, arr, separator))
163 
164 /* INTERNAL */
165 char *t_noalloc_strdup_vprintf(const char *format, va_list args,
166 			       unsigned int *size_r)
167 	ATTR_FORMAT(1, 0) ATTR_RETURNS_NONNULL;
168 char *vstrconcat(const char *str1, va_list args, size_t *ret_len) ATTR_MALLOC;
169 
170 #endif
171