#! /bin/sh /usr/share/dpatch/dpatch-run
## 008_make_include_safe by Adam Conrad <adconrad@0c3.net>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Avoid including dpkg droppings in globbed includes.

@DPATCH@
--- a/server/config.c
+++ b/server/config.c
@@ -34,6 +34,7 @@
 #include "apr_portable.h"
 #include "apr_file_io.h"
 #include "apr_fnmatch.h"
+#include "apr_lib.h"
 
 #define APR_WANT_STDIO
 #define APR_WANT_STRFUNC
@@ -1543,6 +1544,30 @@
     return strcmp(f1->fname,f2->fname);
 }
 
+static int fname_valid(const char *fname) {
+    const unsigned char *c = fname;
+    unsigned char bad_dpkg[] = "*.dpkg*";
+
+    if (!apr_isalnum(*c)) {
+        return 0;
+    }
+    ++c;
+    
+    
+    while (*c) {
+        if (!apr_isalnum(*c) && *c!='_' && *c!='-' && *c!='.') {
+            return 0;
+        }
+        ++c;
+    }
+
+    if (!apr_fnmatch(bad_dpkg, fname, 0)) {
+        return 0;
+    }
+
+    return 1;
+}
+
 static const char *process_resource_config_nofnmatch(server_rec *s,
                                                      const char *fname,
                                                      ap_directive_t **conftree,
@@ -1586,7 +1611,8 @@
         while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) {
             /* strip out '.' and '..' */
             if (strcmp(dirent.name, ".")
-                && strcmp(dirent.name, "..")) {
+                && strcmp(dirent.name, "..")
+                && fname_valid(dirent.name)) {
                 fnew = (fnames *) apr_array_push(candidates);
                 fnew->fname = ap_make_full_path(p, path, dirent.name);
             }
@@ -1714,7 +1740,8 @@
             if (strcmp(dirent.name, ".")
                 && strcmp(dirent.name, "..")
                 && (apr_fnmatch(pattern, dirent.name,
-                                APR_FNM_PERIOD) == APR_SUCCESS)) {
+                                APR_FNM_PERIOD) == APR_SUCCESS)
+                && fname_valid(dirent.name)) {
                 fnew = (fnames *) apr_array_push(candidates);
                 fnew->fname = ap_make_full_path(p, path, dirent.name);
             }
