brian 96/12/08 20:54:24
Modified: src mod_include.c Log: Reviewed by: lotsa folks... Obtained from: Howard Fear, Alexei Kosut 1) The patch that I submitted a couple of days ago which recieved one +1 and fizzled. Fixes an ommision that caused include variables to not be parsed in config errmsg directives. Potential incompatibilites are the same as the extensions of mod_include generally. [Howard Fear] 2) Patch submitted by Ben Yoshino <[EMAIL PROTECTED]> to allow backslash quoting of characters that would otherwise be taken as value terminators. Ex: <!--exec cmd="echo \"hello, world\"" --> Potential incompatibilities only to people who carelessly throw around '\'s. [Howard Fear] 3) Patch to fix the other part of the problem report submitted by Ben Yoshino <[EMAIL PROTECTED]>. I took that approach outlined in my email this morning and added a flag to parse_string to pass the variable name through on the exec cmd directive when the variable hasn't been defined. It will still substitute a null value for all other directives. It will also substitute a null value if the variable has been defined with a null value: <!--#if expr="$notset" --> # substitutes null (if fails) <!--#exec cmd="echo '$notset'" --> # echo '$notset' <!--#set var="notset" value="" --> <!--#exec cmd="echo '$notset'" --> # echo '' I believe that this approach minimizes the potential incompatibilties for current ssi and xssi users. [Howard Fear] 4) Patch to fix compiler warnings reported by [EMAIL PROTECTED] Changes are cosmetic and shouldn't effect logic. [Howard Fear] 5) Remove HAVE_POSIX_REGEX cruft [Alexei Kosut, Rasmus Lerdorf Revision Changes Path 1.18 +39 -35 apache/src/mod_include.c Index: mod_include.c =================================================================== RCS file: /export/home/cvs/apache/src/mod_include.c,v retrieving revision 1.17 retrieving revision 1.18 diff -C3 -r1.17 -r1.18 *** mod_include.c 1996/12/01 20:29:05 1.17 --- mod_include.c 1996/12/09 04:54:22 1.18 *************** *** 66,76 **** #include "http_log.h" #include "http_main.h" #include "util_script.h" - #ifdef HAVE_POSIX_REGEX - #include <regex.h> - #else - #include "regex.h" - #endif #define STARTING_SEQUENCE "<!--#" #define ENDING_SEQUENCE "-->" --- 66,71 ---- *************** *** 309,315 **** t[tagbuf_len - 1] = '\0'; return NULL; } ! if (c == term) break; *(t++) = c; } *t = '\0'; --- 304,316 ---- t[tagbuf_len - 1] = '\0'; return NULL; } ! /* Want to accept \" as a valid character within a string. */ ! if (c == '\\') { ! *(t++) = c; /* Add backslash */ ! GET_CHAR(in,c,NULL,p); ! if (c == term) /* Only if */ ! *(--t) = c; /* Replace backslash ONLY for terminator */ ! } else if (c == term) break; *(t++) = c; } *t = '\0'; *************** *** 341,347 **** /* * Do variable substitution on strings */ ! void parse_string(request_rec *r, char *in, char *out, int length) { char ch; char *next = out; --- 342,349 ---- /* * Do variable substitution on strings */ ! void parse_string(request_rec *r, char *in, char *out, int length, ! int leave_name) { char ch; char *next = out; *************** *** 385,399 **** in++; } - /* Leave single dollar signs like the shell does */ val = (char *)NULL; ! if (*var == '\0') { ! if (strcmp(vtext, "$") == 0) { ! var[0]='$', var[1]='\0'; ! val = &var[0]; ! } ! } else ! val = table_get (r->subprocess_env, &var[0]); while ((val != (char *)NULL) && (*val != '\0')) { *next++ = *val++; if (++numchars == (length -1)) break; --- 387,400 ---- in++; } val = (char *)NULL; ! if (var[0] == '\0') { ! val = &vtext[0]; ! } else { ! val = table_get (r->subprocess_env, &var[0]); ! if (!val && leave_name) ! val = &vtext[0]; ! } while ((val != (char *)NULL) && (*val != '\0')) { *next++ = *val++; if (++numchars == (length -1)) break; *************** *** 459,465 **** request_rec *rr=NULL; char *error_fmt = NULL; ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN); if (tag[0] == 'f') { /* be safe; only files in this directory or below allowed */ char tmp[MAX_STRING_LEN+2]; --- 460,466 ---- request_rec *rr=NULL; char *error_fmt = NULL; ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); if (tag[0] == 'f') { /* be safe; only files in this directory or below allowed */ char tmp[MAX_STRING_LEN+2]; *************** *** 603,609 **** if(!(tag_val = get_tag (r->pool, in, tag, MAX_STRING_LEN, 1))) return 1; if(!strcmp(tag,"cmd")) { ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN); if(include_cmd(parsed_string, r) == -1) { log_printf(r->server, "unknown parameter %s to tag include in %s", tag, r->filename); --- 604,610 ---- if(!(tag_val = get_tag (r->pool, in, tag, MAX_STRING_LEN, 1))) return 1; if(!strcmp(tag,"cmd")) { ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 1); if(include_cmd(parsed_string, r) == -1) { log_printf(r->server, "unknown parameter %s to tag include in %s", tag, r->filename); *************** *** 613,619 **** chdir_file(r->filename); } else if(!strcmp(tag,"cgi")) { ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN); if(include_cgi(parsed_string, r) == -1) { log_printf(r->server, "invalid CGI ref %s in %s",tag_val,file); rputs(error, r); --- 614,620 ---- chdir_file(r->filename); } else if(!strcmp(tag,"cgi")) { ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); if(include_cgi(parsed_string, r) == -1) { log_printf(r->server, "invalid CGI ref %s in %s",tag_val,file); rputs(error, r); *************** *** 664,681 **** while(1) { if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 0))) return 1; ! if(!strcmp(tag,"errmsg")) ! strcpy(error,tag_val); ! else if(!strcmp(tag,"timefmt")) { time_t date = r->request_time; ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN); strcpy(tf,parsed_string); table_set (env, "DATE_LOCAL", ht_time(r->pool,date,tf,0)); table_set (env, "DATE_GMT", ht_time(r->pool,date,tf,1)); table_set (env, "LAST_MODIFIED", ht_time(r->pool,r->finfo.st_mtime,tf,0)); } else if(!strcmp(tag,"sizefmt")) { ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN); decodehtml(parsed_string); if(!strcmp(parsed_string,"bytes")) *sizefmt = SIZEFMT_BYTES; --- 665,683 ---- while(1) { if(!(tag_val = get_tag(r->pool, in, tag, MAX_STRING_LEN, 0))) return 1; ! if(!strcmp(tag,"errmsg")) { ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); ! strcpy(error,parsed_string); ! } else if(!strcmp(tag,"timefmt")) { time_t date = r->request_time; ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); strcpy(tf,parsed_string); table_set (env, "DATE_LOCAL", ht_time(r->pool,date,tf,0)); table_set (env, "DATE_GMT", ht_time(r->pool,date,tf,1)); table_set (env, "LAST_MODIFIED", ht_time(r->pool,r->finfo.st_mtime,tf,0)); } else if(!strcmp(tag,"sizefmt")) { ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); decodehtml(parsed_string); if(!strcmp(parsed_string,"bytes")) *sizefmt = SIZEFMT_BYTES; *************** *** 751,768 **** else if(!strcmp(tag,"done")) return 0; else { ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN); if(!find_file(r,"fsize",tag,parsed_string,&finfo,error)) { if(sizefmt == SIZEFMT_KMG) { send_size(finfo.st_size, r); } else { int l,x; ! #if defined(BSD) && BSD > 199305 sprintf(tag,"%qd",finfo.st_size); ! #else sprintf(tag,"%ld",finfo.st_size); ! #endif l = strlen(tag); /* grrr */ for(x=0;x<l;x++) { if(x && (!((l-x) % 3))) { --- 753,770 ---- else if(!strcmp(tag,"done")) return 0; else { ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); if(!find_file(r,"fsize",tag,parsed_string,&finfo,error)) { if(sizefmt == SIZEFMT_KMG) { send_size(finfo.st_size, r); } else { int l,x; ! #if defined(BSD) && BSD > 199305 sprintf(tag,"%qd",finfo.st_size); ! #else sprintf(tag,"%ld",finfo.st_size); ! #endif l = strlen(tag); /* grrr */ for(x=0;x<l;x++) { if(x && (!((l-x) % 3))) { *************** *** 789,795 **** else if(!strcmp(tag,"done")) return 0; else { ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN); if(!find_file(r,"flastmod",tag,parsed_string,&finfo,error)) rputs(ht_time(r->pool, finfo.st_mtime, tf, 0), r); } --- 791,797 ---- else if(!strcmp(tag,"done")) return 0; else { ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); if(!find_file(r,"flastmod",tag,parsed_string,&finfo,error)) rputs(ht_time(r->pool, finfo.st_mtime, tf, 0), r); } *************** *** 806,812 **** if (regex_error) { regerror(regex_error, &compiled, err_string, (size_t)MAX_STRING_LEN); log_printf(r->server, ! "unable to compile pattern %s [%s]", rexp, &err_string); return -1; } regex_error = regexec(&compiled, string, 0, (regmatch_t *)NULL, 0); --- 808,814 ---- if (regex_error) { regerror(regex_error, &compiled, err_string, (size_t)MAX_STRING_LEN); log_printf(r->server, ! "unable to compile pattern %s [%s]", rexp, err_string); return -1; } regex_error = regexec(&compiled, string, 0, (regmatch_t *)NULL, 0); *************** *** 1186,1192 **** #ifdef DEBUG_INCLUDE rputs(" Evaluate string\n", r); #endif ! parse_string(r, current->token.value, buffer, MAX_STRING_LEN); strncpy(current->token.value, buffer, MAX_STRING_LEN-1); current->value = (current->token.value[0] != '\0'); current->done = 1; --- 1188,1194 ---- #ifdef DEBUG_INCLUDE rputs(" Evaluate string\n", r); #endif ! parse_string(r, current->token.value, buffer, MAX_STRING_LEN, 0); strncpy(current->token.value, buffer, MAX_STRING_LEN-1); current->value = (current->token.value[0] != '\0'); current->done = 1; *************** *** 1209,1215 **** switch(current->left->token.type) { case token_string: parse_string(r, current->left->token.value, ! buffer, MAX_STRING_LEN); strncpy(current->left->token.value, buffer, MAX_STRING_LEN-1); current->left->done = 1; --- 1211,1217 ---- switch(current->left->token.type) { case token_string: parse_string(r, current->left->token.value, ! buffer, MAX_STRING_LEN, 0); strncpy(current->left->token.value, buffer, MAX_STRING_LEN-1); current->left->done = 1; *************** *** 1223,1229 **** switch(current->right->token.type) { case token_string: parse_string(r, current->right->token.value, ! buffer, MAX_STRING_LEN); strncpy(current->right->token.value, buffer, MAX_STRING_LEN-1); current->right->done = 1; --- 1225,1231 ---- switch(current->right->token.type) { case token_string: parse_string(r, current->right->token.value, ! buffer, MAX_STRING_LEN, 0); strncpy(current->right->token.value, buffer, MAX_STRING_LEN-1); current->right->done = 1; *************** *** 1264,1272 **** rputs(error, r); goto RETURN; } ! parse_string(r, current->left->token.value, buffer, MAX_STRING_LEN); strncpy(current->left->token.value, buffer, MAX_STRING_LEN-1); ! parse_string(r, current->right->token.value, buffer, MAX_STRING_LEN); strncpy(current->right->token.value, buffer, MAX_STRING_LEN-1); if (current->right->token.value[0] == '/') { int len; --- 1266,1276 ---- rputs(error, r); goto RETURN; } ! parse_string(r, current->left->token.value, ! buffer, MAX_STRING_LEN, 0); strncpy(current->left->token.value, buffer, MAX_STRING_LEN-1); ! parse_string(r, current->right->token.value, ! buffer, MAX_STRING_LEN, 0); strncpy(current->right->token.value, buffer, MAX_STRING_LEN-1); if (current->right->token.value[0] == '/') { int len; *************** *** 1493,1499 **** rputs(error, r); return -1; } ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN); table_set (r->subprocess_env, var, parsed_string); } } --- 1497,1503 ---- rputs(error, r); return -1; } ! parse_string(r, tag_val, parsed_string, MAX_STRING_LEN, 0); table_set (r->subprocess_env, var, parsed_string); } }