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 3285 : static size_t encoded_length(unsigned char c) 30 : { 31 3285 : if (c != '\\' && c > 0x1F) { 32 2908 : return 1; 33 : } else { 34 11 : 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 3 : default: 45 3 : 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 293 : char *log_escape(TALLOC_CTX *frame, const char *in) 55 : { 56 293 : size_t size = 0; /* Space to allocate for the escaped data */ 57 293 : char *encoded = NULL; /* The encoded string */ 58 33 : const char *c; 59 33 : char *e; 60 : 61 293 : if (in == NULL) { 62 0 : return NULL; 63 : } 64 : 65 : /* Calculate the size required for the escaped array */ 66 260 : c = in; 67 3577 : while (*c) { 68 3285 : size += encoded_length( *c); 69 3285 : c++; 70 : } 71 292 : size++; 72 : 73 292 : encoded = talloc_array( frame, char, size); 74 292 : if (encoded == NULL) { 75 0 : DBG_ERR( "Out of memory allocating encoded string\n"); 76 0 : return NULL; 77 : } 78 : 79 260 : c = in; 80 260 : e = encoded; 81 3577 : while (*c) { 82 3285 : if (*c != '\\' && (unsigned char)(*c) > 0x1F) { 83 3274 : *e++ = *c++; 84 : } else { 85 11 : switch (*c) { 86 1 : case '\a': 87 1 : *e++ = '\\'; 88 1 : *e++ = 'a'; 89 1 : break; 90 1 : case '\b': 91 1 : *e++ = '\\'; 92 1 : *e++ = 'b'; 93 1 : break; 94 1 : case '\f': 95 1 : *e++ = '\\'; 96 1 : *e++ = 'f'; 97 1 : break; 98 1 : case '\n': 99 1 : *e++ = '\\'; 100 1 : *e++ = 'n'; 101 1 : break; 102 1 : case '\r': 103 1 : *e++ = '\\'; 104 1 : *e++ = 'r'; 105 1 : break; 106 1 : case '\t': 107 1 : *e++ = '\\'; 108 1 : *e++ = 't'; 109 1 : break; 110 1 : case '\v': 111 1 : *e++ = '\\'; 112 1 : *e++ = 'v'; 113 1 : break; 114 1 : case '\\': 115 1 : *e++ = '\\'; 116 1 : *e++ = '\\'; 117 1 : break; 118 3 : default: 119 3 : snprintf(e, 5, "\\x%02hhX", (unsigned char)(*c)); 120 3 : e += 4; 121 : } 122 11 : c++; 123 : } 124 : } 125 292 : *e = '\0'; 126 292 : return encoded; 127 : }