]> granicus.if.org Git - apache/blobdiff - server/gen_test_char.c
Merge r1741310, r1741461 from trunk:
[apache] / server / gen_test_char.c
index f3f23c527fce1b07ecb6cd61a52fab5317d11091..e25238f31b2f20261708a271f55b218a7cb10292 100644 (file)
@@ -1,70 +1,46 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
- * reserved.
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Apache" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- * Portions of this software are based upon public domain software
- * originally written at the National Center for Supercomputing Applications,
- * University of Illinois, Urbana-Champaign.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
+#ifdef CROSS_COMPILE
+
+#define apr_isalnum(c) (isalnum(((unsigned char)(c))))
+#define apr_isalpha(c) (isalpha(((unsigned char)(c))))
+#define apr_iscntrl(c) (iscntrl(((unsigned char)(c))))
+#define apr_isprint(c) (isprint(((unsigned char)(c))))
+#include <ctype.h>
+#define APR_HAVE_STDIO_H 1
+#define APR_HAVE_STRING_H 1
+
+#else
+
 #include "apr.h"
 #include "apr_lib.h"
 
+#endif
+
+#if defined(WIN32) || defined(OS2)
+#define NEED_ENHANCED_ESCAPES
+#endif
+
 #if APR_HAVE_STDIO_H
 #include <stdio.h>
 #endif
-
-/* we need some of the portability definitions... for strchr */
-#include "httpd.h"
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
 
 /* A bunch of functions in util.c scan strings looking for certain characters.
  * To make that more efficient we encode a lookup table.
@@ -73,6 +49,9 @@
 #define T_ESCAPE_PATH_SEGMENT (0x02)
 #define T_OS_ESCAPE_PATH      (0x04)
 #define T_HTTP_TOKEN_STOP     (0x08)
+#define T_ESCAPE_LOGITEM      (0x10)
+#define T_ESCAPE_FORENSIC     (0x20)
+#define T_ESCAPE_URLENCODED   (0x40)
 
 int main(int argc, char *argv[])
 {
@@ -85,26 +64,44 @@ int main(int argc, char *argv[])
            "#define T_ESCAPE_PATH_SEGMENT  (%u)\n"
            "#define T_OS_ESCAPE_PATH       (%u)\n"
            "#define T_HTTP_TOKEN_STOP      (%u)\n"
+           "#define T_ESCAPE_LOGITEM       (%u)\n"
+           "#define T_ESCAPE_FORENSIC      (%u)\n"
+           "#define T_ESCAPE_URLENCODED    (%u)\n"
            "\n"
-           "static const unsigned char test_char_table[256] = {\n"
-           "    0,",
+           "static const unsigned char test_char_table[256] = {",
            T_ESCAPE_SHELL_CMD,
            T_ESCAPE_PATH_SEGMENT,
            T_OS_ESCAPE_PATH,
-           T_HTTP_TOKEN_STOP);
-
-    /* we explicitly dealt with NUL above
-     * in case some strchr() do bogosity with it */
+           T_HTTP_TOKEN_STOP,
+           T_ESCAPE_LOGITEM,
+           T_ESCAPE_FORENSIC,
+           T_ESCAPE_URLENCODED);
 
-    for (c = 1; c < 256; ++c) {
+    for (c = 0; c < 256; ++c) {
         flags = 0;
         if (c % 20 == 0)
             printf("\n    ");
 
         /* escape_shell_cmd */
-        if (strchr("&;`'\"|*?~<>^()[]{}$\\\n", c)) {
+#ifdef NEED_ENHANCED_ESCAPES
+        /* Win32/OS2 have many of the same vulnerable characters
+         * as Unix sh, plus the carriage return and percent char.
+         * The proper escaping of these characters varies from unix
+         * since Win32/OS2 use carets or doubled-double quotes,
+         * and neither lf nor cr can be escaped.  We escape unix
+         * specific as well, to assure that cross-compiled unix
+         * applications behave similiarly when invoked on win32/os2.
+         *
+         * Rem please keep in-sync with apr's list in win32/filesys.c
+         */
+        if (c && strchr("&;`'\"|*?~<>^()[]{}$\\\n\r%", c)) {
             flags |= T_ESCAPE_SHELL_CMD;
         }
+#else
+        if (c && strchr("&;`'\"|*?~<>^()[]{}$\\\n", c)) {
+            flags |= T_ESCAPE_SHELL_CMD;
+        }
+#endif
 
         if (!apr_isalnum(c) && !strchr("$-_.+!*'(),:@&=~", c)) {
             flags |= T_ESCAPE_PATH_SEGMENT;
@@ -114,13 +111,33 @@ int main(int argc, char *argv[])
             flags |= T_OS_ESCAPE_PATH;
         }
 
-        /* these are the "tspecials" from RFC2068 */
-        if (apr_iscntrl(c) || strchr(" \t()<>@,;:\\/[]?={}", c)) {
+        if (!apr_isalnum(c) && !strchr(".-*_ ", c)) {
+            flags |= T_ESCAPE_URLENCODED;
+        }
+
+        /* these are the "tspecials" (RFC2068) or "separators" (RFC2616) */
+        if (c && (apr_iscntrl(c) || strchr(" \t()<>@,;:\\\"/[]?={}", c))) {
             flags |= T_HTTP_TOKEN_STOP;
         }
 
-        printf("%u%c", flags, (c < 255) ? ',' : ' ');
+        /* For logging, escape all control characters,
+         * double quotes (because they delimit the request in the log file)
+         * backslashes (because we use backslash for escaping)
+         * and 8-bit chars with the high bit set
+         */
+        if (c && (!apr_isprint(c) || c == '"' || c == '\\' || apr_iscntrl(c))) {
+            flags |= T_ESCAPE_LOGITEM;
+        }
 
+        /* For forensic logging, escape all control characters, top bit set,
+         * :, | (used as delimiters) and % (used for escaping).
+         */
+        if (!apr_isprint(c) || c == ':' || c == '|' || c == '%'
+            || apr_iscntrl(c) || !c) {
+            flags |= T_ESCAPE_FORENSIC;
+        }
+
+        printf("%u%c", flags, (c < 255) ? ',' : ' ');
     }
 
     printf("\n};\n");