s3:printing: Allow to run samba-bgqd as a standalone systemd service
[Samba.git] / lib / util / util_str_escape.c
blob8f1f34912ee6929011e468713f8043235da7ea5f
1 /*
2 Samba string escaping routines
4 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "replace.h"
21 #include "lib/util/debug.h"
22 #include "lib/util/util_str_escape.h"
26 * Calculate the encoded length of a character for log_escape
29 static size_t encoded_length(unsigned char c)
31 if (c != '\\' && c > 0x1F) {
32 return 1;
33 } else {
34 switch (c) {
35 case '\a':
36 case '\b':
37 case '\f':
38 case '\n':
39 case '\r':
40 case '\t':
41 case '\v':
42 case '\\':
43 return 2; /* C escape sequence */
44 default:
45 return 4; /* hex escape \xhh */
51 * Escape any control characters in the inputs to prevent them from
52 * interfering with the log output.
54 char *log_escape(TALLOC_CTX *frame, const char *in)
56 size_t size = 0; /* Space to allocate for the escaped data */
57 char *encoded = NULL; /* The encoded string */
58 const char *c;
59 char *e;
61 if (in == NULL) {
62 return NULL;
65 /* Calculate the size required for the escaped array */
66 c = in;
67 while (*c) {
68 size += encoded_length( *c);
69 c++;
71 size++;
73 encoded = talloc_array( frame, char, size);
74 if (encoded == NULL) {
75 DBG_ERR( "Out of memory allocating encoded string\n");
76 return NULL;
79 c = in;
80 e = encoded;
81 while (*c) {
82 if (*c != '\\' && (unsigned char)(*c) > 0x1F) {
83 *e++ = *c++;
84 } else {
85 switch (*c) {
86 case '\a':
87 *e++ = '\\';
88 *e++ = 'a';
89 break;
90 case '\b':
91 *e++ = '\\';
92 *e++ = 'b';
93 break;
94 case '\f':
95 *e++ = '\\';
96 *e++ = 'f';
97 break;
98 case '\n':
99 *e++ = '\\';
100 *e++ = 'n';
101 break;
102 case '\r':
103 *e++ = '\\';
104 *e++ = 'r';
105 break;
106 case '\t':
107 *e++ = '\\';
108 *e++ = 't';
109 break;
110 case '\v':
111 *e++ = '\\';
112 *e++ = 'v';
113 break;
114 case '\\':
115 *e++ = '\\';
116 *e++ = '\\';
117 break;
118 default:
119 snprintf(e, 5, "\\x%02hhX", (unsigned char)(*c));
120 e += 4;
122 c++;
125 *e = '\0';
126 return encoded;