torture3: Fix CID 1435119 Error handling issues (CHECKED_RETURN)
[samba.git] / source3 / lib / substitute_generic.c
1 /*
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4
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     2006
9    Copyright (C) Jeremy Allison  1992-2007
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26
27 void fstring_sub(char *s,const char *pattern,const char *insert)
28 {
29         string_sub(s, pattern, insert, sizeof(fstring));
30 }
31
32 /**
33  Similar to string_sub2, but it will accept only allocated strings
34  and may realloc them so pay attention at what you pass on no
35  pointers inside strings, no const may be passed
36  as string.
37 **/
38
39 char *realloc_string_sub2(char *string,
40                         const char *pattern,
41                         const char *insert,
42                         bool remove_unsafe_characters,
43                         bool allow_trailing_dollar)
44 {
45         char *p, *in;
46         char *s;
47         ssize_t ls,lp,li,ld, i;
48
49         if (!insert || !pattern || !*pattern || !string || !*string)
50                 return NULL;
51
52         s = string;
53
54         in = talloc_strdup(talloc_tos(), insert);
55         if (!in) {
56                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
57                 return NULL;
58         }
59         ls = (ssize_t)strlen(s);
60         lp = (ssize_t)strlen(pattern);
61         li = (ssize_t)strlen(insert);
62         ld = li - lp;
63         for (i=0;i<li;i++) {
64                 switch (in[i]) {
65                         case '$':
66                                 /* allow a trailing $
67                                  * (as in machine accounts) */
68                                 if (allow_trailing_dollar && (i == li - 1 )) {
69                                         break;
70                                 }
71                                 FALL_THROUGH;
72                         case '`':
73                         case '"':
74                         case '\'':
75                         case ';':
76                         case '%':
77                         case '\r':
78                         case '\n':
79                                 if ( remove_unsafe_characters ) {
80                                         in[i] = '_';
81                                         break;
82                                 }
83                                 FALL_THROUGH;
84                         default:
85                                 /* ok */
86                                 break;
87                 }
88         }
89
90         while ((p = strstr_m(s,pattern))) {
91                 if (ld > 0) {
92                         int offset = PTR_DIFF(s,string);
93                         string = talloc_realloc(NULL, string, char, ls + ld + 1);
94                         if (!string) {
95                                 DEBUG(0, ("realloc_string_sub: "
96                                         "out of memory!\n"));
97                                 talloc_free(in);
98                                 return NULL;
99                         }
100                         p = string + offset + (p - s);
101                 }
102                 if (li != lp) {
103                         memmove(p+li,p+lp,strlen(p+lp)+1);
104                 }
105                 memcpy(p, in, li);
106                 s = p + li;
107                 ls += ld;
108         }
109         talloc_free(in);
110         return string;
111 }
112
113 char *realloc_string_sub(char *string,
114                         const char *pattern,
115                         const char *insert)
116 {
117         return realloc_string_sub2(string, pattern, insert, true, false);
118 }