Merge the svnserve-logging branch, in its entirety, to trunk, using the
[svn.git] / subversion / svnserve / log-escape.c
blob171ef6e8599e432e696f7bf13e2cfdd3074ddc4a
1 /*
2 * log-escape.c : Functions for escaping log items
3 * copied from Apache httpd
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * ====================================================================
23 * Copyright (c) 2008 CollabNet. All rights reserved.
25 * This software is licensed as described in the file COPYING, which
26 * you should have received as part of this distribution. The terms
27 * are also available at http://subversion.tigris.org/license-1.html.
28 * If newer versions of this license are posted there, you may use a
29 * newer version instead, at your option.
31 * This software consists of voluntary contributions made by many
32 * individuals. For exact contribution history, see the revision
33 * history and logs, available at http://subversion.tigris.org/.
34 * ====================================================================
38 #include <apr.h>
39 #include <apr_lib.h>
40 #define APR_WANT_STRFUNC
41 #include <apr_want.h>
43 /* copied from httpd-2.2.4/server/util.c */
44 /* c2x takes an unsigned, and expects the caller has guaranteed that
45 * 0 <= what < 256... which usually means that you have to cast to
46 * unsigned char first, because (unsigned)(char)(x) first goes through
47 * signed extension to an int before the unsigned cast.
49 * The reason for this assumption is to assist gcc code generation --
50 * the unsigned char -> unsigned extension is already done earlier in
51 * both uses of this code, so there's no need to waste time doing it
52 * again.
54 static const char c2x_table[] = "0123456789abcdef";
56 /* copied from httpd-2.2.4/server/util.c */
57 static APR_INLINE unsigned char *c2x(unsigned what, unsigned char prefix,
58 unsigned char *where)
60 #if APR_CHARSET_EBCDIC
61 what = apr_xlate_conv_byte(ap_hdrs_to_ascii, (unsigned char)what);
62 #endif /*APR_CHARSET_EBCDIC*/
63 *where++ = prefix;
64 *where++ = c2x_table[what >> 4];
65 *where++ = c2x_table[what & 0xf];
66 return where;
69 /* copied from httpd-2.2.4/server/util.c */
70 apr_size_t escape_errorlog_item(char *dest, const char *source,
71 apr_size_t buflen)
73 unsigned char *d, *ep;
74 const unsigned char *s;
76 if (!source || !buflen) { /* be safe */
77 return 0;
80 d = (unsigned char *)dest;
81 s = (const unsigned char *)source;
82 ep = d + buflen - 1;
84 for (; d < ep && *s; ++s) {
86 /* httpd-2.2.4/server/util.c has this:
87 if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) {
88 which does this same check with a fast lookup table. Well,
89 mostly the same; we don't escape quotes, as that does.
91 if (*s && (!apr_isprint(*s) || *s == '\\' || apr_iscntrl(*s))) {
92 *d++ = '\\';
93 if (d >= ep) {
94 --d;
95 break;
98 switch(*s) {
99 case '\b':
100 *d++ = 'b';
101 break;
102 case '\n':
103 *d++ = 'n';
104 break;
105 case '\r':
106 *d++ = 'r';
107 break;
108 case '\t':
109 *d++ = 't';
110 break;
111 case '\v':
112 *d++ = 'v';
113 break;
114 case '\\':
115 *d++ = *s;
116 break;
117 case '"': /* no need for this in error log */
118 d[-1] = *s;
119 break;
120 default:
121 if (d >= ep - 2) {
122 ep = --d; /* break the for loop as well */
123 break;
125 c2x(*s, 'x', d);
126 d += 3;
129 else {
130 *d++ = *s;
133 *d = '\0';
135 return (d - (unsigned char *)dest);