s3:ntlm_auth: make logs more consistent with length check
[Samba.git] / lib / util / substitute.c
blobb7b5588da863faa960200d9f9fd32e2120462b46
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-2001
6 Copyright (C) Simo Sorce 2001-2002
7 Copyright (C) Martin Pool 2003
8 Copyright (C) James Peach 2005
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "replace.h"
25 #include "debug.h"
26 #ifndef SAMBA_UTIL_CORE_ONLY
27 #include "charset/charset.h"
28 #else
29 #include "charset_compat.h"
30 #endif
31 #include "substitute.h"
33 /**
34 * @file
35 * @brief Substitute utilities.
36 **/
38 /**
39 Substitute a string for a pattern in another string. Make sure there is
40 enough room!
42 This routine looks for pattern in s and replaces it with
43 insert. It may do multiple replacements or just one.
45 Any of " ; ' $ or ` in the insert string are replaced with _
46 if len==0 then the string cannot be extended. This is different from the old
47 use of len==0 which was for no length checks to be done.
48 **/
50 static void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
51 bool remove_unsafe_characters, bool replace_once,
52 bool allow_trailing_dollar)
54 char *p;
55 size_t ls, lp, li, i;
57 if (!insert || !pattern || !*pattern || !s)
58 return;
60 ls = strlen(s);
61 lp = strlen(pattern);
62 li = strlen(insert);
64 if (len == 0)
65 len = ls + 1; /* len is number of *bytes* */
67 while (lp <= ls && (p = strstr_m(s,pattern))) {
68 if (ls + li - lp >= len) {
69 DBG_ERR("ERROR: string overflow by "
70 "%zu in string_sub(%.50s, %zu)\n",
71 ls + li - lp + 1 - len,
72 pattern,
73 len);
74 break;
76 if (li != lp) {
77 memmove(p+li,p+lp,strlen(p+lp)+1);
79 for (i=0;i<li;i++) {
80 switch (insert[i]) {
81 case '$':
82 /* allow a trailing $
83 * (as in machine accounts) */
84 if (allow_trailing_dollar && (i == li - 1 )) {
85 p[i] = insert[i];
86 break;
88 FALL_THROUGH;
89 case '`':
90 case '"':
91 case '\'':
92 case ';':
93 case '%':
94 case '\r':
95 case '\n':
96 if ( remove_unsafe_characters ) {
97 p[i] = '_';
98 /* yes this break should be here
99 * since we want to fall throw if
100 * not replacing unsafe chars */
101 break;
103 FALL_THROUGH;
104 default:
105 p[i] = insert[i];
108 s = p + li;
109 ls = ls + li - lp;
111 if (replace_once)
112 break;
116 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
118 string_sub2( s, pattern, insert, len, true, false, false );
122 Similar to string_sub() but allows for any character to be substituted.
123 Use with caution!
124 if len==0 then the string cannot be extended. This is different from the old
125 use of len==0 which was for no length checks to be done.
128 _PUBLIC_ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
130 char *p;
131 size_t ls,lp,li;
133 if (!insert || !pattern || !s)
134 return;
136 ls = strlen(s);
137 lp = strlen(pattern);
138 li = strlen(insert);
140 if (!*pattern)
141 return;
143 if (len == 0)
144 len = ls + 1; /* len is number of *bytes* */
146 while (lp <= ls && (p = strstr_m(s,pattern))) {
147 if (ls + li - lp >= len) {
148 DBG_ERR("ERROR: string overflow by "
149 "%zu in all_string_sub(%.50s, %zu)\n",
150 ls + li - lp + 1 - len,
151 pattern,
152 len);
153 break;
155 if (li != lp) {
156 memmove(p+li,p+lp,strlen(p+lp)+1);
158 memcpy(p, insert, li);
159 s = p + li;
160 ls = ls + li - lp;
165 * Internal guts of talloc_string_sub and talloc_all_string_sub.
166 * talloc version of string_sub2.
169 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
170 const char *pattern,
171 const char *insert,
172 bool remove_unsafe_characters,
173 bool replace_once,
174 bool allow_trailing_dollar)
176 char *p, *in;
177 char *s;
178 char *string;
179 ssize_t ls,lp,li,ld, i;
181 if (!insert || !pattern || !*pattern || !src) {
182 return NULL;
185 string = talloc_strdup(mem_ctx, src);
186 if (string == NULL) {
187 DEBUG(0, ("talloc_string_sub2: "
188 "talloc_strdup failed\n"));
189 return NULL;
192 s = string;
194 in = talloc_strdup(mem_ctx, insert);
195 if (!in) {
196 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
197 talloc_free(string);
198 return NULL;
200 ls = (ssize_t)strlen(s);
201 lp = (ssize_t)strlen(pattern);
202 li = (ssize_t)strlen(insert);
203 ld = li - lp;
205 for (i=0;i<li;i++) {
206 switch (in[i]) {
207 case '$':
208 /* allow a trailing $
209 * (as in machine accounts) */
210 if (allow_trailing_dollar && (i == li - 1 )) {
211 break;
214 FALL_THROUGH;
215 case '`':
216 case '"':
217 case '\'':
218 case ';':
219 case '%':
220 case '\r':
221 case '\n':
222 if (remove_unsafe_characters) {
223 in[i] = '_';
224 break;
227 FALL_THROUGH;
228 default:
229 /* ok */
230 break;
234 while ((p = strstr_m(s,pattern))) {
235 if (ld > 0) {
236 int offset = PTR_DIFF(s,string);
237 string = (char *)talloc_realloc_size(mem_ctx, string,
238 ls + ld + 1);
239 if (!string) {
240 DEBUG(0, ("talloc_string_sub: out of "
241 "memory!\n"));
242 TALLOC_FREE(in);
243 return NULL;
245 p = string + offset + (p - s);
247 if (li != lp) {
248 memmove(p+li,p+lp,strlen(p+lp)+1);
250 memcpy(p, in, li);
251 s = p + li;
252 ls += ld;
254 if (replace_once) {
255 break;
258 TALLOC_FREE(in);
259 return string;
262 /* Same as string_sub, but returns a talloc'ed string */
264 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
265 const char *src,
266 const char *pattern,
267 const char *insert)
269 return talloc_string_sub2(mem_ctx, src, pattern, insert,
270 true, false, false);
273 char *talloc_all_string_sub(TALLOC_CTX *ctx,
274 const char *src,
275 const char *pattern,
276 const char *insert)
278 return talloc_string_sub2(ctx, src, pattern, insert,
279 false, false, false);