Bug 1888590 - Mark some subtests on trusted-types-event-handlers.html as failing...
[gecko.git] / third_party / sipcc / cpr_string.c
blob1e97c186ae1b682889a3ac329ad9f70635e25491
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include <stdarg.h>
7 #include "mozilla/Assertions.h"
8 #include "cpr_types.h"
9 #include "cpr_string.h"
10 #include "cpr_strings.h"
12 /* From cpr_stdlib.h */
13 #ifdef CPR_STRING_USE_FALLIBLE_MALLOC
14 #define cpr_malloc(a) malloc(a)
15 #define cpr_calloc(a, b) calloc(a, b)
16 #define cpr_realloc(a, b) realloc(a, b)
17 #define cpr_free(a) free(a)
18 #else
19 #include "mozilla/mozalloc.h"
21 #define cpr_malloc(a) moz_xmalloc(a)
22 #define cpr_calloc(a, b) moz_xcalloc(a, b)
23 #define cpr_realloc(a, b) moz_xrealloc(a, b)
24 #define cpr_free(a) free(a)
25 #endif
27 /**
28 * sstrncpy
30 * This is Cisco's *safe* version of strncpy. The string will always
31 * be NUL terminated (which is not ANSI compliant).
33 * Parameters: s1 - first string
34 * s2 - second string
35 * max - maximum length in octets to concat.
37 * Return: Pointer to the *end* of the string
39 * Remarks: Modified to be explicitly safe for all inputs.
40 * Also return the number of characters copied excluding the
41 * NUL terminator vs. the original string s1. This simplifies
42 * code where sstrncat functions follow.
44 unsigned long
45 sstrncpy (char *dst, const char *src, unsigned long max)
47 unsigned long cnt = 0;
49 if (dst == NULL) {
50 return 0;
53 if (src) {
54 while ((max-- > 1) && (*src)) {
55 *dst = *src;
56 dst++;
57 src++;
58 cnt++;
62 #if defined(CPR_SSTRNCPY_PAD)
64 * To be equivalent to the TI compiler version
65 * v2.01, SSTRNCPY_PAD needs to be defined
67 while (max-- > 1) {
68 *dst = '\0';
69 dst++;
71 #endif
72 *dst = '\0';
74 return cnt;
77 /**
78 * sstrncat
80 * This is Cisco's *safe* version of strncat. The string will always
81 * be NUL terminated (which is not ANSI compliant).
83 * Parameters: s1 - first string
84 * s2 - second string
85 * max - maximum length in octets to concatenate
87 * Return: Pointer to the *end* of the string
89 * Remarks: Modified to be explicitly safe for all inputs.
90 * Also return the end vs. the beginning of the string s1
91 * which is useful for multiple sstrncat calls.
93 char *
94 sstrncat (char *s1, const char *s2, unsigned long max)
96 if (s1 == NULL)
97 return (char *) NULL;
99 while (*s1)
100 s1++;
102 if (s2) {
103 while ((max-- > 1) && (*s2)) {
104 *s1 = *s2;
105 s1++;
106 s2++;
109 *s1 = '\0';
111 return s1;
115 * flex_string
119 * flex_string_init
121 * Not thread-safe
123 void flex_string_init(flex_string *fs) {
124 fs->buffer_length = FLEX_STRING_CHUNK_SIZE;
125 fs->string_length = 0;
126 fs->buffer = cpr_malloc(fs->buffer_length);
127 fs->buffer[0] = '\0';
131 * flex_string_free
133 * Not thread-safe
135 void flex_string_free(flex_string *fs) {
136 fs->buffer_length = 0;
137 fs->string_length = 0;
138 cpr_free(fs->buffer);
139 fs->buffer = NULL;
142 /* For sanity check before alloc */
143 #define FLEX_STRING_MAX_SIZE (10 * 1024 * 1024) /* 10MB */
146 * flex_string_check_alloc
148 * Allocate enough chunks to hold the new minimum size.
150 * Not thread-safe
152 void flex_string_check_alloc(flex_string *fs, size_t new_min_length) {
153 if (new_min_length > fs->buffer_length) {
154 /* Oversize, allocate more */
156 /* Sanity check on allocation size */
157 if (new_min_length > FLEX_STRING_MAX_SIZE) {
158 MOZ_CRASH();
161 /* Alloc to nearest chunk */
162 fs->buffer_length = (((new_min_length - 1) / FLEX_STRING_CHUNK_SIZE) + 1) * FLEX_STRING_CHUNK_SIZE;
164 fs->buffer = cpr_realloc(fs->buffer, fs->buffer_length);
169 * flex_string_append
171 * Not thread-safe
173 void flex_string_append(flex_string *fs, const char *more) {
174 fs->string_length += strlen(more);
176 flex_string_check_alloc(fs, fs->string_length + 1);
178 sstrncat(fs->buffer, more, fs->buffer_length - strlen(fs->buffer));
182 * va_copy is part of the C99 spec but MSVC doesn't have it.
184 #ifndef va_copy
185 #define va_copy(d,s) ((d) = (s))
186 #endif
189 * flex_string_vsprintf
191 * Not thread-safe
193 void flex_string_vsprintf(flex_string *fs, const char *format, va_list original_ap) {
194 va_list ap;
195 int vsnprintf_result;
197 va_copy(ap, original_ap);
198 vsnprintf_result = vsnprintf(fs->buffer + fs->string_length, fs->buffer_length - fs->string_length, format, ap);
199 va_end(ap);
201 /* Special case just for Windows where vsnprintf is broken
202 and returns -1 if buffer too large unless you size it 0. */
203 if (vsnprintf_result < 0) {
204 va_copy(ap, original_ap);
205 vsnprintf_result = vsnprintf(NULL, 0, format, ap);
206 va_end(ap);
209 if (fs->string_length + vsnprintf_result >= fs->buffer_length) {
210 /* Buffer overflow, resize */
211 flex_string_check_alloc(fs, fs->string_length + vsnprintf_result + 1);
213 /* Try again with new buffer */
214 va_copy(ap, original_ap);
215 vsnprintf_result = vsnprintf(fs->buffer + fs->string_length, fs->buffer_length - fs->string_length, format, ap);
216 va_end(ap);
217 MOZ_ASSERT(vsnprintf_result > 0 &&
218 (size_t)vsnprintf_result < (fs->buffer_length - fs->string_length));
221 if (vsnprintf_result > 0) {
222 fs->string_length += vsnprintf_result;
227 * flex_string_sprintf
229 * Not thread-safe
231 void flex_string_sprintf(flex_string *fs, const char *format, ...) {
232 va_list ap;
234 va_start(ap, format);
235 flex_string_vsprintf(fs, format, ap);
236 va_end(ap);
241 /* From cpr_linux_string.c */
243 * cpr_strdup
245 * @brief The CPR wrapper for strdup
247 * The cpr_strdup shall return a pointer to a new string, which is a duplicate
248 * of the string pointed to by "str" argument. A null pointer is returned if the
249 * new string cannot be created.
251 * @param[in] str - The string that needs to be duplicated
253 * @return The duplicated string or NULL in case of no memory
256 char *
257 cpr_strdup (const char *str)
259 char *dup;
260 size_t len;
262 if (!str) {
263 return (char *) NULL;
266 len = strlen(str);
267 if (len == 0) {
268 return (char *) NULL;
270 len++;
272 dup = cpr_malloc(len * sizeof(char));
273 if (!dup) {
274 return (char *) NULL;
276 (void) memcpy(dup, str, len);
277 return dup;