This source file includes following definitions.
- str_escape
- str_unescape
- str_shell_escape
- str_glob_escape
- str_regex_escape
- str_shell_unescape
- str_glob_unescape
- str_regex_unescape
- str_is_char_escaped
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #include <config.h>
28
29 #include "lib/global.h"
30 #include "lib/strutil.h"
31
32
33
34
35
36
37
38
39
40
41
42 static const char ESCAPE_SHELL_CHARS[] = " !#$%()&{}[]`?|<>;*\\\"'";
43 static const char ESCAPE_REGEX_CHARS[] = "^!#$%()&{}[]`?|<>;*+.\\";
44 static const char ESCAPE_GLOB_CHARS[] = "$*\\?";
45
46
47
48
49
50
51
52
53
54 char *
55 str_escape (const char *src, const ssize_t src_len, const char *escaped_chars,
56 const gboolean escape_non_printable)
57 {
58 GString *ret;
59
60
61 if (src == NULL)
62 return NULL;
63
64 if (*src == '\0')
65 return strdup ("");
66
67 ret = g_string_new ("");
68
69 const size_t src_len1 = src_len < 0 ? strlen (src) : (size_t) src_len;
70
71 for (size_t curr_index = 0; curr_index < src_len1; curr_index++)
72 {
73 if (escape_non_printable)
74 {
75 switch (src[curr_index])
76 {
77 case '\n':
78 g_string_append (ret, "\\n");
79 continue;
80 case '\t':
81 g_string_append (ret, "\\t");
82 continue;
83 case '\b':
84 g_string_append (ret, "\\b");
85 continue;
86 case '\0':
87 g_string_append (ret, "\\0");
88 continue;
89 default:
90 break;
91 }
92 }
93
94 if (strchr (escaped_chars, (int) src[curr_index]))
95 g_string_append_c (ret, '\\');
96
97 g_string_append_c (ret, src[curr_index]);
98 }
99 return g_string_free (ret, FALSE);
100 }
101
102
103
104 char *
105 str_unescape (const char *src, const ssize_t src_len, const char *unescaped_chars,
106 const gboolean unescape_non_printable)
107 {
108 GString *ret;
109 size_t curr_index;
110
111 if (src == NULL)
112 return NULL;
113
114 if (*src == '\0')
115 return strdup ("");
116
117 ret = g_string_sized_new (16);
118
119 const size_t src_len1 = src_len < 0 ? strlen (src) : (size_t) src_len;
120
121 for (curr_index = 0; curr_index < src_len1 - 1; curr_index++)
122 {
123 if (src[curr_index] != '\\')
124 {
125 g_string_append_c (ret, src[curr_index]);
126 continue;
127 }
128
129 curr_index++;
130
131 if (unescaped_chars == ESCAPE_SHELL_CHARS && src[curr_index] == '$')
132 {
133
134 g_string_append_c (ret, '\\');
135 }
136 else
137 {
138 if (unescape_non_printable)
139 {
140 switch (src[curr_index])
141 {
142 case 'n':
143 g_string_append_c (ret, '\n');
144 continue;
145 case 't':
146 g_string_append_c (ret, '\t');
147 continue;
148 case 'b':
149 g_string_append_c (ret, '\b');
150 continue;
151 case '0':
152 g_string_append_c (ret, '\0');
153 continue;
154 default:
155 break;
156 }
157 }
158
159 if (strchr (unescaped_chars, (int) src[curr_index]) == NULL)
160 g_string_append_c (ret, '\\');
161 }
162
163 g_string_append_c (ret, src[curr_index]);
164 }
165 g_string_append_c (ret, src[curr_index]);
166
167 return g_string_free (ret, FALSE);
168 }
169
170
171
172
173
174
175
176
177
178
179
180
181 char *
182 str_shell_escape (const char *src)
183 {
184 return str_escape (src, -1, ESCAPE_SHELL_CHARS, FALSE);
185 }
186
187
188
189 char *
190 str_glob_escape (const char *src)
191 {
192 return str_escape (src, -1, ESCAPE_GLOB_CHARS, TRUE);
193 }
194
195
196
197 char *
198 str_regex_escape (const char *src)
199 {
200 return str_escape (src, -1, ESCAPE_REGEX_CHARS, TRUE);
201 }
202
203
204
205
206
207
208
209
210
211
212
213
214 char *
215 str_shell_unescape (const char *text)
216 {
217 return str_unescape (text, -1, ESCAPE_SHELL_CHARS, TRUE);
218 }
219
220
221
222 char *
223 str_glob_unescape (const char *text)
224 {
225 return str_unescape (text, -1, ESCAPE_GLOB_CHARS, TRUE);
226 }
227
228
229 char *
230 str_regex_unescape (const char *text)
231 {
232 return str_unescape (text, -1, ESCAPE_REGEX_CHARS, TRUE);
233 }
234
235
236
237
238
239
240
241
242
243
244
245
246 gboolean
247 str_is_char_escaped (const char *start, const char *current)
248 {
249 int num_esc = 0;
250
251 if (start == NULL || current == NULL || current <= start)
252 return FALSE;
253
254 current--;
255 while (current >= start && *current == '\\')
256 {
257 num_esc++;
258 current--;
259 }
260 return (gboolean) num_esc % 2;
261 }
262
263