Line data Source code
1 : /*
2 : Samba string escaping routines
3 :
4 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017
5 :
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.
10 :
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.
15 :
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/>.
18 : */
19 :
20 : #include "replace.h"
21 : #include "system/locale.h"
22 : #include "lib/util/debug.h"
23 : #include "lib/util/util_str_escape.h"
24 :
25 :
26 : /*
27 : * Calculate the encoded length of a character for log_escape
28 : *
29 : */
30 1148 : static size_t encoded_length(unsigned char c)
31 : {
32 1148 : if (c != '\\' && !iscntrl(c)) {
33 1148 : return 1;
34 : } else {
35 0 : switch (c) {
36 0 : case '\a':
37 : case '\b':
38 : case '\f':
39 : case '\n':
40 : case '\r':
41 : case '\t':
42 : case '\v':
43 : case '\\':
44 0 : return 2; /* C escape sequence */
45 0 : default:
46 0 : return 4; /* hex escape \xhh */
47 : }
48 : }
49 : }
50 :
51 : /*
52 : * Escape any control characters in the inputs to prevent them from
53 : * interfering with the log output.
54 : */
55 100 : char *log_escape(TALLOC_CTX *frame, const char *in)
56 : {
57 100 : size_t size = 0; /* Space to allocate for the escaped data */
58 100 : char *encoded = NULL; /* The encoded string */
59 : const char *c;
60 : char *e;
61 :
62 100 : if (in == NULL) {
63 0 : return NULL;
64 : }
65 :
66 : /* Calculate the size required for the escaped array */
67 100 : c = in;
68 1348 : while (*c) {
69 1148 : size += encoded_length( *c);
70 1148 : c++;
71 : }
72 100 : size++;
73 :
74 100 : encoded = talloc_array( frame, char, size);
75 100 : if (encoded == NULL) {
76 0 : DBG_ERR( "Out of memory allocating encoded string");
77 0 : return NULL;
78 : }
79 :
80 100 : c = in;
81 100 : e = encoded;
82 1348 : while (*c) {
83 1148 : if (*c != '\\' && !iscntrl((unsigned char)(*c))) {
84 1148 : *e++ = *c++;
85 : } else {
86 0 : switch (*c) {
87 0 : case '\a':
88 0 : *e++ = '\\';
89 0 : *e++ = 'a';
90 0 : break;
91 0 : case '\b':
92 0 : *e++ = '\\';
93 0 : *e++ = 'b';
94 0 : break;
95 0 : case '\f':
96 0 : *e++ = '\\';
97 0 : *e++ = 'f';
98 0 : break;
99 0 : case '\n':
100 0 : *e++ = '\\';
101 0 : *e++ = 'n';
102 0 : break;
103 0 : case '\r':
104 0 : *e++ = '\\';
105 0 : *e++ = 'r';
106 0 : break;
107 0 : case '\t':
108 0 : *e++ = '\\';
109 0 : *e++ = 't';
110 0 : break;
111 0 : case '\v':
112 0 : *e++ = '\\';
113 0 : *e++ = 'v';
114 0 : break;
115 0 : case '\\':
116 0 : *e++ = '\\';
117 0 : *e++ = '\\';
118 0 : break;
119 0 : default:
120 0 : snprintf(e, 5, "\\x%02X", *c);
121 0 : e += 4;
122 : }
123 0 : c++;
124 : }
125 : }
126 100 : *e = '\0';
127 100 : return encoded;
128 : }
|