File httpd-2.2.x-bnc729181-CVE-2011-3607-int_overflow.diff of Package apache2

diff -rNU 20 ../httpd-2.2.21-o/server/util.c ./server/util.c
--- ../httpd-2.2.21-o/server/util.c	2011-05-19 04:17:37.000000000 +0200
+++ ./server/util.c	2012-02-14 01:49:36.000000000 +0100
@@ -349,72 +349,80 @@
  * passed ap_regexec(). pmatch should not be greater than the maximum number
  * of subexpressions - i.e. one more than the re_nsub member of ap_regex_t.
  *
  * input should be the string with the $-expressions, source should be the
  * string that was matched against.
  *
  * It returns the substituted string, or NULL on error.
  *
  * Parts of this code are based on Henry Spencer's regsub(), from his
  * AT&T V8 regexp package.
  */
 
 AP_DECLARE(char *) ap_pregsub(apr_pool_t *p, const char *input,
                               const char *source, size_t nmatch,
                               ap_regmatch_t pmatch[])
 {
     const char *src = input;
     char *dest, *dst;
     char c;
     size_t no;
-    int len;
+    apr_size_t len;
 
     if (!source)
         return NULL;
     if (!nmatch)
         return apr_pstrdup(p, src);
 
     /* First pass, find the size */
 
     len = 0;
 
     while ((c = *src++) != '\0') {
         if (c == '&')
             no = 0;
         else if (c == '$' && apr_isdigit(*src))
             no = *src++ - '0';
         else
             no = 10;
 
         if (no > 9) {                /* Ordinary character. */
             if (c == '\\' && (*src == '$' || *src == '&'))
                 src++;
             len++;
         }
         else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) {
+	    if (APR_SIZE_MAX - len <= pmatch[no].rm_eo - pmatch[no].rm_so) {
+		ap_log_error(APLOG_MARK, APLOG_WARNING, APR_ENOMEM, NULL,
+		"integer overflow or out of memory condition." );
+	    }
             len += pmatch[no].rm_eo - pmatch[no].rm_so;
         }
 
     }
 
     dest = dst = apr_pcalloc(p, len + 1);
 
+    if(!dest)
+       return NULL;
+
+
     /* Now actually fill in the string */
 
     src = input;
 
     while ((c = *src++) != '\0') {
         if (c == '&')
             no = 0;
         else if (c == '$' && apr_isdigit(*src))
             no = *src++ - '0';
         else
             no = 10;
 
         if (no > 9) {                /* Ordinary character. */
             if (c == '\\' && (*src == '$' || *src == '&'))
                 c = *src++;
             *dst++ = c;
         }
         else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) {
             len = pmatch[no].rm_eo - pmatch[no].rm_so;
             memcpy(dst, source + pmatch[no].rm_so, len);
openSUSE Build Service is sponsored by