1/* 2 * log-escape.c : Functions for escaping log items 3 * copied from Apache httpd 4 * 5 * ==================================================================== 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 * ==================================================================== 22 * Licensed to the Apache Software Foundation (ASF) under one 23 * or more contributor license agreements. See the NOTICE file 24 * distributed with this work for additional information 25 * regarding copyright ownership. The ASF licenses this file 26 * to you under the Apache License, Version 2.0 (the 27 * "License"); you may not use this file except in compliance 28 * with the License. You may obtain a copy of the License at 29 * 30 * http://www.apache.org/licenses/LICENSE-2.0 31 * 32 * Unless required by applicable law or agreed to in writing, 33 * software distributed under the License is distributed on an 34 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 35 * KIND, either express or implied. See the License for the 36 * specific language governing permissions and limitations 37 * under the License. 38 * ==================================================================== 39 */ 40 41 42#include <apr.h> 43#define APR_WANT_STRFUNC 44#include <apr_want.h> 45#include "server.h" 46#include "svn_ctype.h" 47 48/* copied from httpd-2.2.4/server/util.c */ 49/* c2x takes an unsigned, and expects the caller has guaranteed that 50 * 0 <= what < 256... which usually means that you have to cast to 51 * unsigned char first, because (unsigned)(char)(x) first goes through 52 * signed extension to an int before the unsigned cast. 53 * 54 * The reason for this assumption is to assist gcc code generation -- 55 * the unsigned char -> unsigned extension is already done earlier in 56 * both uses of this code, so there's no need to waste time doing it 57 * again. 58 */ 59static const char c2x_table[] = "0123456789abcdef"; 60 61/* copied from httpd-2.2.4/server/util.c */ 62static APR_INLINE unsigned char *c2x(unsigned what, unsigned char prefix, 63 unsigned char *where) 64{ 65#if APR_CHARSET_EBCDIC 66 what = apr_xlate_conv_byte(ap_hdrs_to_ascii, (unsigned char)what); 67#endif /*APR_CHARSET_EBCDIC*/ 68 *where++ = prefix; 69 *where++ = c2x_table[what >> 4]; 70 *where++ = c2x_table[what & 0xf]; 71 return where; 72} 73 74/* copied from httpd-2.2.4/server/util.c */ 75apr_size_t escape_errorlog_item(char *dest, const char *source, 76 apr_size_t buflen) 77{ 78 unsigned char *d, *ep; 79 const unsigned char *s; 80 81 if (!source || !buflen) { /* be safe */ 82 return 0; 83 } 84 85 d = (unsigned char *)dest; 86 s = (const unsigned char *)source; 87 ep = d + buflen - 1; 88 89 for (; d < ep && *s; ++s) { 90 91 /* httpd-2.2.4/server/util.c has this: 92 if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) { 93 which does this same check with a fast lookup table. Well, 94 mostly the same; we don't escape quotes, as that does. 95 */ 96 if (*s && ( !svn_ctype_isprint(*s) 97 || *s == '\\' 98 || svn_ctype_iscntrl(*s))) { 99 *d++ = '\\'; 100 if (d >= ep) { 101 --d; 102 break; 103 } 104 105 switch(*s) { 106 case '\b': 107 *d++ = 'b'; 108 break; 109 case '\n': 110 *d++ = 'n'; 111 break; 112 case '\r': 113 *d++ = 'r'; 114 break; 115 case '\t': 116 *d++ = 't'; 117 break; 118 case '\v': 119 *d++ = 'v'; 120 break; 121 case '\\': 122 *d++ = *s; 123 break; 124 case '"': /* no need for this in error log */ 125 d[-1] = *s; 126 break; 127 default: 128 if (d >= ep - 2) { 129 ep = --d; /* break the for loop as well */ 130 break; 131 } 132 c2x(*s, 'x', d); 133 d += 3; 134 } 135 } 136 else { 137 *d++ = *s; 138 } 139 } 140 *d = '\0'; 141 142 return (d - (unsigned char *)dest); 143} 144