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