Project

General

Profile

mod_ssi_recursion_1.5.0svn2299.patch

Correct recursion depth limit implementation - Anonymous, 2008-09-02 16:15

View differences:

src/mod_ssi.c 2008-09-02 01:41:35.000000000 +0200
37 37
#include <sys/filio.h>
38 38
#endif
39 39

  
40
#define DEFAULT_MAX_SSI_RECURSION	25
41

  
42
URIHANDLER_FUNC(mod_ssi_physical_path);
43

  
40 44
/* init the plugin data */
41 45
INIT_FUNC(mod_ssi_init) {
42 46
	plugin_data *p;
......
98 102

  
99 103
	config_values_t cv[] = {
100 104
		{ "ssi.extension",              NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
105
		{ "ssi.max_recursion",          NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
101 106
		{ NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
102 107
	};
103 108

  
......
110 115

  
111 116
		s = calloc(1, sizeof(plugin_config));
112 117
		s->ssi_extension  = array_init();
118
		s->ssi_max_recursion  = DEFAULT_MAX_SSI_RECURSION;
113 119

  
114 120
		cv[0].destination = s->ssi_extension;
121
		cv[1].destination = &(s->ssi_max_recursion);
115 122

  
116 123
		p->config_storage[i] = s;
117 124

  
......
577 584
				}
578 585
				break;
579 586
			case SSI_INCLUDE:
580
				chunkqueue_append_file(con->send, p->stat_fn, 0, st.st_size);
587
				if (file_path) {
588
					/* don't process if #include file="..." is used */
589
					chunkqueue_append_file(con->send, p->stat_fn, 0, st.st_size);
590
				} else {
591
					buffer *tmp = NULL;
592
					/* do recursive SSI expansion */
593

  
594
					b = chunkqueue_get_append_buffer(con->send);
595

  
596
					/* prevents simple infinite loop */
597
					if (buffer_is_equal(con->physical.path, p->stat_fn)) {
598
						buffer_copy_string(b, "(error: include directives create an infinite loop)");
599
						break;
600
					}
601

  
602
					/* only allow predefined recursion depth */
603
					if (con->loops_per_request > p->conf.ssi_max_recursion) {
604
						buffer_copy_string(b, "(error: include directives recurse deeper than pre-defined max_recursion)");
605
						break;
606
					}
607

  
608
					tmp = buffer_init();
609
					/* save path of current document */
610
					buffer_copy_string_buffer(tmp, con->physical.path);
611
					/* next sub-document to parse */
612
					buffer_copy_string_buffer(con->physical.path, p->stat_fn);
613
					if (mod_ssi_physical_path(srv,con,p) != HANDLER_FINISHED) {
614
						/* the document was not processed, so write it as is */
615
						chunkqueue_append_file(con->send, con->physical.path, 0, st.st_size);
616
					}
617
					/* restore saved path */
618
					buffer_copy_string_buffer(con->physical.path, tmp);
619
					buffer_free(tmp);
620
				}
581 621
				break;
582 622
			}
583 623
		} else {
......
897 937
	int ovec[N * 3];
898 938
#endif
899 939

  
900
	/* get a stream to the file */
940
	/* for nested requests increase recursion depth */
941
	con->loops_per_request++;
901 942

  
902
	array_reset(p->ssi_vars);
903
	array_reset(p->ssi_cgi_env);
904
	buffer_copy_string_len(p->timefmt, CONST_STR_LEN("%a, %d %b %Y %H:%M:%S %Z"));
905
	p->sizefmt = 0;
906
	build_ssi_cgi_vars(srv, con, p);
943
	/* initialize values only if in the first level of recursion */
944
	if(con->loops_per_request <= 1) {
945
		array_reset(p->ssi_vars);
946
		array_reset(p->ssi_cgi_env);
947
		buffer_copy_string_len(p->timefmt, CONST_STR_LEN("%a, %d %b %Y %H:%M:%S %Z"));
948
		p->sizefmt = 0;
949
		build_ssi_cgi_vars(srv, con, p);
950
	}
907 951
	p->if_is_false = 0;
908 952

  
953
	/* get a stream to the file */
909 954
	if (-1 == stream_open(&s, con->physical.path)) {
910 955
		log_error_write(srv, __FILE__, __LINE__, "sb",
911 956
				"stream-open: ", con->physical.path);
......
1007 1052
	/* reset physical.path */
1008 1053
	buffer_reset(con->physical.path);
1009 1054

  
1055
	/* for nested requests decrease recursion depth afterwards */
1056
	con->loops_per_request--;
1057

  
1010 1058
	return 0;
1011 1059
}
1012 1060

  
......
1015 1063
	plugin_config *s = p->config_storage[0];
1016 1064

  
1017 1065
	PATCH_OPTION(ssi_extension);
1066
	PATCH_OPTION(ssi_max_recursion);
1018 1067

  
1019 1068
	/* skip the first, the global context */
1020 1069
	for (i = 1; i < srv->config_context->used; i++) {
......
1030 1079

  
1031 1080
			if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.extension"))) {
1032 1081
				PATCH_OPTION(ssi_extension);
1082
			} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.max_recursion"))) {
1083
				PATCH_OPTION(ssi_max_recursion);
1033 1084
			}
1034 1085
		}
1035 1086
	}
1036
-- src/mod_ssi.h.orig	2008-09-02 01:10:38.000000000 +0200
1087
++ src/mod_ssi.h	2008-09-02 01:35:06.000000000 +0200
......
15 15

  
16 16
typedef struct {
17 17
	array *ssi_extension;
18
	unsigned short ssi_max_recursion;
18 19
} plugin_config;
19 20

  
20 21
typedef struct {