Ticket #536: mod_ssi_recursion-1.4.15.patch
| File mod_ssi_recursion-1.4.15.patch, 12.4 kB (added by dustin@…, 16 months ago) |
|---|
-
src/mod_ssi.c
# HG changeset patch # User Dustin Sallings <dustin@spy.net> # Date 1178910589 25200 # Node ID 228071f87c8e346c3e6e3a1d7542650a01d415dd # Parent ea8607208d0e0278392e07debbb31bbbadb48cb3 patch queue: mod_ssi_recursion diff -r ea8607208d0e -r 228071f87c8e src/mod_ssi.c
a b 36 36 #include <sys/filio.h> 37 37 #endif 38 38 39 #define DEFAULT_MAX_SSI_RECURSION 25 40 39 41 /* init the plugin data */ 40 42 INIT_FUNC(mod_ssi_init) { 41 43 plugin_data *p; … … 94 96 #endif 95 97 96 98 config_values_t cv[] = { 97 { "ssi.extension", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ 98 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } 99 { "ssi.extension", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ 100 { "ssi.max_recursion", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ 101 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } 99 102 }; 100 103 101 104 if (!p) return HANDLER_ERROR; … … 107 110 108 111 s = calloc(1, sizeof(plugin_config)); 109 112 s->ssi_extension = array_init(); 113 s->ssi_max_recursion = DEFAULT_MAX_SSI_RECURSION; 110 114 111 115 cv[0].destination = s->ssi_extension; 116 cv[1].destination = &(s->ssi_max_recursion); 112 117 113 118 p->config_storage[i] = s; 114 119 … … 150 155 151 156 /** 152 157 * 153 * the next two functions are take from fcgi.c158 * the next two functions are take from fcgi.c 154 159 * 155 160 */ 156 161 … … 214 219 ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_SOFTWARE"), PACKAGE_NAME"/"PACKAGE_VERSION); 215 220 ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_NAME"), 216 221 #ifdef HAVE_IPV6 217 inet_ntop(srv_sock->addr.plain.sa_family,218 srv_sock->addr.plain.sa_family == AF_INET6 ?219 (const void *) &(srv_sock->addr.ipv6.sin6_addr) :220 (const void *) &(srv_sock->addr.ipv4.sin_addr),221 b2, sizeof(b2)-1)222 inet_ntop(srv_sock->addr.plain.sa_family, 223 srv_sock->addr.plain.sa_family == AF_INET6 ? 224 (const void *) &(srv_sock->addr.ipv6.sin6_addr) : 225 (const void *) &(srv_sock->addr.ipv4.sin_addr), 226 b2, sizeof(b2)-1) 222 227 #else 223 inet_ntoa(srv_sock->addr.ipv4.sin_addr)224 #endif 225 );228 inet_ntoa(srv_sock->addr.ipv4.sin_addr) 229 #endif 230 ); 226 231 ssi_env_add(p->ssi_cgi_env, CONST_STRING("GATEWAY_INTERFACE"), "CGI/1.1"); 227 232 228 233 ltostr(buf, 229 234 #ifdef HAVE_IPV6 230 ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)235 ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port) 231 236 #else 232 ntohs(srv_sock->addr.ipv4.sin_port)233 #endif 234 );237 ntohs(srv_sock->addr.ipv4.sin_port) 238 #endif 239 ); 235 240 236 241 ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_PORT"), buf); 237 242 238 243 ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_ADDR"), 239 inet_ntop_cache_get_ip(srv, &(con->dst_addr)));244 inet_ntop_cache_get_ip(srv, &(con->dst_addr))); 240 245 241 246 if (con->authed_user->used) { 242 247 ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_USER"), 243 con->authed_user->ptr);248 con->authed_user->ptr); 244 249 } 245 250 246 251 if (con->request.content_length > 0) { … … 286 291 return 0; 287 292 } 288 293 294 URIHANDLER_FUNC(mod_ssi_physical_path); 295 289 296 static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, 290 const char **l, size_t n) {297 const char **l, size_t n) { 291 298 size_t i, ssicmd = 0; 292 299 char buf[255]; 293 300 buffer *b = NULL; … … 298 305 SSI_CONFIG, SSI_PRINTENV, SSI_SET, SSI_IF, SSI_ELIF, 299 306 SSI_ELSE, SSI_ENDIF, SSI_EXEC } type; 300 307 } ssicmds[] = { 301 { "echo", SSI_ECHO },308 { "echo", SSI_ECHO }, 302 309 { "include", SSI_INCLUDE }, 303 310 { "flastmod", SSI_FLASTMOD }, 304 { "fsize", SSI_FSIZE },311 { "fsize", SSI_FSIZE }, 305 312 { "config", SSI_CONFIG }, 306 313 { "printenv", SSI_PRINTENV }, 307 { "set", SSI_SET },308 { "if", SSI_IF },309 { "elif", SSI_ELIF },310 { "endif", SSI_ENDIF },311 { "else", SSI_ELSE },312 { "exec", SSI_EXEC },314 { "set", SSI_SET }, 315 { "if", SSI_IF }, 316 { "elif", SSI_ELIF }, 317 { "endif", SSI_ENDIF }, 318 { "else", SSI_ELSE }, 319 { "exec", SSI_EXEC }, 313 320 314 321 { NULL, SSI_UNSET } 315 322 }; … … 333 340 enum { SSI_ECHO_UNSET, SSI_ECHO_DATE_GMT, SSI_ECHO_DATE_LOCAL, SSI_ECHO_DOCUMENT_NAME, SSI_ECHO_DOCUMENT_URI, 334 341 SSI_ECHO_LAST_MODIFIED, SSI_ECHO_USER_NAME } type; 335 342 } echovars[] = { 336 { "DATE_GMT", SSI_ECHO_DATE_GMT },343 { "DATE_GMT", SSI_ECHO_DATE_GMT }, 337 344 { "DATE_LOCAL", SSI_ECHO_DATE_LOCAL }, 338 345 { "DOCUMENT_NAME", SSI_ECHO_DOCUMENT_NAME }, 339 346 { "DOCUMENT_URI", SSI_ECHO_DOCUMENT_URI }, 340 347 { "LAST_MODIFIED", SSI_ECHO_LAST_MODIFIED }, 341 { "USER_NAME", SSI_ECHO_USER_NAME },348 { "USER_NAME", SSI_ECHO_USER_NAME }, 342 349 343 350 { NULL, SSI_ECHO_UNSET } 344 351 }; … … 347 354 const char *var; 348 355 enum { SSI_ENC_UNSET, SSI_ENC_URL, SSI_ENC_NONE, SSI_ENC_ENTITY } type; 349 356 } encvars[] = { 350 { "url", SSI_ENC_URL },351 { "none", SSI_ENC_NONE },352 { "entity", SSI_ENC_ENTITY },357 { "url", SSI_ENC_URL }, 358 { "none", SSI_ENC_NONE }, 359 { "entity", SSI_ENC_ENTITY }, 353 360 354 361 { NULL, SSI_ENC_UNSET } 355 362 }; … … 546 553 } 547 554 548 555 if (0 == stat(p->stat_fn->ptr, &st)) { 556 buffer *tmp = NULL; 549 557 time_t t = st.st_mtime; 550 558 551 559 switch (ssicmd) { … … 574 582 } 575 583 break; 576 584 case SSI_INCLUDE: 577 chunkqueue_append_file(con->write_queue, p->stat_fn, 0, st.st_size); 585 /* do recursive SSI expansion */ 586 587 /* prevents infinite loop */ 588 if (buffer_is_equal(con->physical.path, p->stat_fn)) { 589 buffer_copy_string(srv->tmp_buf, "<!-- your include directives create an infinite loop; aborting -->"); 590 chunkqueue_append_buffer(con->write_queue, srv->tmp_buf); 591 break; 592 } 593 594 /* only allow predefined recursion depth */ 595 if (con->loops_per_request > p->conf.ssi_max_recursion) { 596 buffer_copy_string(srv->tmp_buf, "<!-- your include directives recurse deeper than pre-defined max_recursion; aborting -->"); 597 chunkqueue_append_buffer(con->write_queue, srv->tmp_buf); 598 break; 599 } 600 601 tmp = buffer_init(); 602 /* save path of current document */ 603 buffer_copy_string_buffer(tmp, con->physical.path); 604 /* next sub-document to parse */ 605 buffer_copy_string_buffer(con->physical.path, p->stat_fn); 606 if (mod_ssi_physical_path(srv,con,p) != HANDLER_FINISHED) { 607 /* the document was not processed, so write it as is */ 608 chunkqueue_append_file(con->write_queue, con->physical.path, 0, st.st_size); 609 } 610 /* restore saved path */ 611 buffer_copy_string_buffer(con->physical.path, tmp); 612 buffer_free(tmp); 578 613 break; 579 614 } 580 615 } else { … … 795 830 } 796 831 797 832 if ((!p->if_is_false) && 798 ((p->if_is_false_level == 0) ||799 (p->if_level < p->if_is_false_level))) {833 ((p->if_is_false_level == 0) || 834 (p->if_level < p->if_is_false_level))) { 800 835 switch (ssi_eval_expr(srv, con, p, expr)) { 801 836 case -1: 802 837 case 0: … … 818 853 819 854 if (p->if_is_false) { 820 855 if ((p->if_level == p->if_is_false_level) && 821 (p->if_is_false_endif == 0)) {856 (p->if_is_false_endif == 0)) { 822 857 p->if_is_false = 0; 823 858 } 824 859 } else { … … 852 887 853 888 if (p->if_level == p->if_is_false_level) { 854 889 if ((p->if_is_false) && 855 (p->if_is_false_endif == 0)) {890 (p->if_is_false_endif == 0)) { 856 891 switch (ssi_eval_expr(srv, con, p, expr)) { 857 892 case -1: 858 893 case 0: … … 896 931 897 932 static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p) { 898 933 stream s; 899 #ifdef HAVE_PCRE_H934 #ifdef HAVE_PCRE_H 900 935 int i, n; 901 936 902 937 #define N 10 … … 922 957 /** 923 958 * <!--#element attribute=value attribute=value ... --> 924 959 * 925 * config DONE926 * errmsg-- missing927 * sizefmtDONE928 * timefmtDONE929 * echo DONE930 * varDONE931 * encoding-- missing932 * exec DONE933 * cgi-- never934 * cmdDONE935 * fsize DONE936 * fileDONE937 * virtualDONE938 * flastmod DONE939 * fileDONE940 * virtualDONE941 * include DONE942 * fileDONE943 * virtualDONE944 * printenv DONE945 * set DONE946 * varDONE947 * valueDONE960 * config DONE 961 * errmsg -- missing 962 * sizefmt DONE 963 * timefmt DONE 964 * echo DONE 965 * var DONE 966 * encoding -- missing 967 * exec DONE 968 * cgi -- never 969 * cmd DONE 970 * fsize DONE 971 * file DONE 972 * virtual DONE 973 * flastmod DONE 974 * file DONE 975 * virtual DONE 976 * include DONE 977 * file DONE 978 * virtual DONE 979 * printenv DONE 980 * set DONE 981 * var DONE 982 * value DONE 948 983 * 949 * if DONE950 * elif DONE951 * else DONE952 * endif DONE984 * if DONE 985 * elif DONE 986 * else DONE 987 * endif DONE 953 988 * 954 989 * 955 990 * expressions 956 * AND, OR DONE957 * comp DONE958 * ${...} -- missing959 * $... DONE960 * '...' DONE961 * ( ... ) DONE991 * AND, OR DONE 992 * comp DONE 993 * ${...} -- missing 994 * $... DONE 995 * '...' DONE 996 * ( ... ) DONE 962 997 * 963 998 * 964 999 * 965 1000 * ** all DONE ** 966 1001 * DATE_GMT 967 * The current date in Greenwich Mean Time.1002 * The current date in Greenwich Mean Time. 968 1003 * DATE_LOCAL 969 * The current date in the local time zone.1004 * The current date in the local time zone. 970 1005 * DOCUMENT_NAME 971 * The filename (excluding directories) of the document requested by the user.1006 * The filename (excluding directories) of the document requested by the user. 972 1007 * DOCUMENT_URI 973 * The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document.1008 * The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document. 974 1009 * LAST_MODIFIED 975 * The last modification date of the document requested by the user.1010 * The last modification date of the document requested by the user. 976 1011 * USER_NAME 977 * Contains the owner of the file which included it.1012 * Contains the owner of the file which included it. 978 1013 * 979 1014 */ 980 1015 #ifdef HAVE_PCRE_H … … 1023 1058 plugin_config *s = p->config_storage[0]; 1024 1059 1025 1060 PATCH(ssi_extension); 1061 PATCH(ssi_max_recursion); 1026 1062 1027 1063 /* skip the first, the global context */ 1028 1064 for (i = 1; i < srv->config_context->used; i++) { … … 1039 1075 if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.extension"))) { 1040 1076 PATCH(ssi_extension); 1041 1077 } 1078 if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.max_recursion"))) { 1079 PATCH(ssi_max_recursion); 1080 } 1042 1081 } 1043 1082 } 1044 1083 … … 1052 1091 1053 1092 if (con->physical.path->used == 0) return HANDLER_GO_ON; 1054 1093 1094 con->loops_per_request++; 1095 1055 1096 mod_ssi_patch_connection(srv, con, p); 1056 1097 1057 1098 for (k = 0; k < p->conf.ssi_extension->used; k++) { … … 1078 1119 /* this function is called at dlopen() time and inits the callbacks */ 1079 1120 1080 1121 int mod_ssi_plugin_init(plugin *p) { 1081 p->version = LIGHTTPD_VERSION_ID;1082 p->name = buffer_init_string("ssi");1083 1084 p->init = mod_ssi_init;1122 p->version = LIGHTTPD_VERSION_ID; 1123 p->name = buffer_init_string("ssi"); 1124 1125 p->init = mod_ssi_init; 1085 1126 p->handle_subrequest_start = mod_ssi_physical_path; 1086 1127 p->set_defaults = mod_ssi_set_defaults; 1087 p->cleanup = mod_ssi_free;1088 1089 p->data = NULL;1128 p->cleanup = mod_ssi_free; 1129 1130 p->data = NULL; 1090 1131 1091 1132 return 0; 1092 1133 } -
src/mod_ssi.h
diff -r ea8607208d0e -r 228071f87c8e src/mod_ssi.h
a b 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 {

