Репозиторий ALT Linux backports/2.4
Последнее обновление: 9 июля 2008 | Пакетов: 497 | Посещений: 1575172
 поиск   регистрация   авторизация 
 
Группа :: Система/Серверы
Пакет: apache

 Главная   Изменения   Спек   Патчи   Загрузить   Bugs and FR 

Патч: apache-1.3.41-unloop-rewrite.patch


diff -Naur apache_1.3.41-orig/src/modules/standard/mod_rewrite.c apache_1.3.41/src/modules/standard/mod_rewrite.c
--- apache_1.3.41-orig/src/modules/standard/mod_rewrite.c	2006-07-27 20:09:03 +0300
+++ apache_1.3.41/src/modules/standard/mod_rewrite.c	2008-03-31 19:33:24 +0300
@@ -62,6 +62,17 @@
 static LONG locking_sem = 0;
 #endif
 
+#ifndef REWRITE_MAX_RULES
+#define REWRITE_MAX_RULES 300
+#endif
+#ifndef REWRITE_MAX_REDIRECTS
+#define REWRITE_MAX_REDIRECTS 50
+#endif
+
+#define REWRITE_FIXUP_NOTE "rewrite_fixup_redirect"
+
+int redirect_count;		/* Счетчик циклов для fixup */
+
 /*
 ** +-------------------------------------------------------+
 ** |                                                       |
@@ -1345,6 +1356,34 @@
         return FORBIDDEN;
     }
 
+    /* Проверим и установим флаг первого запроса */
+    {
+    	request_rec *q;
+    	int note_found = 0;
+    	for (q = r; q != NULL; q = q->prev) {
+    		if( ap_table_get(q->notes, REWRITE_FIXUP_NOTE) != NULL ) {
+				note_found = 1;
+				break;
+    		}
+        }
+		ap_table_set(r->notes, REWRITE_FIXUP_NOTE, "OK");
+		
+	    if( !note_found ) {
+			redirect_count = REWRITE_MAX_REDIRECTS;
+			rewritelog(r, 3, "setting redirect count notice" );
+        }
+    }
+
+    /* Проверим количество циклов */
+    if( redirect_count-- <= 0 ) {
+		/* очень много итераций */
+		ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+			"too many rewrite internal redirects: %s", r->uri);
+		return HTTP_INTERNAL_SERVER_ERROR;
+	}
+
+	rewritelog(r, 3, "internal redirect count: %d", redirect_count );
+	
     /*
      *  remember the current filename before rewriting for later check
      *  to prevent deadlooping because of internal redirects
@@ -1359,6 +1398,13 @@
     if (rulestatus) {
         unsigned skip;
 
+		if (strlen(r->filename) > 20 &&
+			strncmp(r->filename, "too_many_iterations:", 20) == 0) {
+			/* очень много итераций */
+			ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+				"too many rewrite rules (possible loop): %s", r->uri);
+			return HTTP_INTERNAL_SERVER_ERROR;
+        } else
         if (strlen(r->filename) > 6 &&
             strncmp(r->filename, "proxy:", 6) == 0) {
             /* it should go on as an internal proxy request */
@@ -1671,6 +1717,7 @@
     int changed;
     int rc;
     int s;
+    int loopcount = REWRITE_MAX_RULES;
 
     /*
      *  Iterate over all existing rules
@@ -1679,6 +1726,13 @@
     changed = 0;
     loop:
     for (i = 0; i < rewriterules->nelts; i++) {
+    	if( loopcount-- <= 0 ) {
+			rewritelog(r, 2, "too many iterations '%s'", r->filename);
+			r->filename = ap_pstrcat(r->pool, "too_many_iterations:", r->filename, NULL);
+			changed = ACTION_NORMAL;
+			break;
+    	}
+    	
         p = &entries[i];
 
         /*
 
design & coding: Vladimir Lettiev aka crux © 2004-2005