You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Rodent of Unusual Size <co...@decus.org> on 1997/05/02 18:18:34 UTC

[PATCH] (post 1.2?) make_html_safe

>From the fingers of Dean Gaudet flowed the following:
>
>  * Ken's [PATCH] PR#501: mod_status doesn't escape printed URLs
>    [Dean would like to see us write a general "escape ascii text" function
>    so that it could be used by mod_status, mod_info, mod_dir, etc. rather
>    than fix this one bug at a time.]

    So.. how long have you been speaking of yourself in the third
    person?  What seems to be troubling you? <g>

    Here you are.. complete with comments.  BTW, is there any particular
    reason there isn't a util.h containing the prototypes?

    #ken    :-)}

Index: util.c
===================================================================
RCS file: /export/home/cvs/apache/src/util.c,v
retrieving revision 1.52
diff -c -r1.52 util.c
*** util.c	1997/04/12 04:24:59	1.52
--- util.c	1997/05/02 16:09:03
***************
*** 65,70 ****
--- 65,149 ----
      "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
  };
  
+ /*
+  * Make an ASCII string HTML-safe by escaping problematic characters
+  * ('<', '>', '&').  To enhance this list, modify the two following static
+  * declarations.  MAKE SURE THE COUNTS MATCH!  Note that this currently only
+  * works for characters that fit within sizeof(char).
+  */
+ 
+ #define DANGEROUS_CHAR_COUNT 3
+ static const char ichars[DANGEROUS_CHAR_COUNT]
+     = {'<', '>', '&'};
+ static const char *rstrings[DANGEROUS_CHAR_COUNT]
+     = {"&lt;", "&gt;", "&amp;"};
+ 
+ char *make_html_safe (pool *p, const char *input) {
+     char *output = "";
+     int i, bad_ch;
+     char *cpos[DANGEROUS_CHAR_COUNT];
+     char *frog1 = pstrdup (p, input);
+     char *frog2;
+     char *eos_pos = strchr (frog1, '\0');
+ 
+     /*
+      * Walk forward through the string until we come to the end.  Simple, eh?
+      */
+     while (frog1 < eos_pos) {
+ 	frog2 = eos_pos;
+ 	/*
+ 	 * Look for the first questionable character, because we only walk
+ 	 * through the string once.
+ 	 */
+ 	for (i = 0; i < DANGEROUS_CHAR_COUNT; i++) {
+ 	    /*
+ 	     * Look for the current character.
+ 	     */
+ 	    cpos[i] = strchr (frog1, ichars[i]);
+ 	    /*
+ 	     * If we found it, and it occurs earlier in the string than any
+ 	     * others we've found so far, make a note of it.
+ 	     */
+ 	    if ((cpos[i] != NULL) && (cpos[i] < frog2)) {
+ 		bad_ch = i;
+ 		frog2 = cpos[bad_ch];
+ 	    }
+ 	}
+ 	/*
+ 	 * frog2 is now a pointer to either the first dangerous character or
+ 	 * the end-of-string.  Mark this position as the end-of-string, so we
+ 	 * can copy everything up to this point into the output.  If no
+ 	 * characters were found, we're already at the EOS, so this is
+ 	 * essentially a no-op.
+ 	 */
+ 	*frog2 = '\0';
+ 	/*
+ 	 * Copy the fragment up to this point.
+ 	 */
+ 	output = pstrcat (p, output, frog1, NULL);
+ 	/*
+ 	 * If we found a character, add its HTML representation to the output
+ 	 * in its place. 
+ 	 */
+ 	if (frog2 < eos_pos) {
+ 	    output = pstrcat (p, output, rstrings[bad_ch], NULL);
+ 	}
+ 	/*
+ 	 * Otherwise, we've reached the real end of the string, and we're
+ 	 * done.
+ 	 */
+ 	else {
+ 	    break;
+ 	}
+ 	/*
+ 	 * Advance the start-point to just after the character we found, and
+ 	 * go back through the loop.
+ 	 */
+ 	frog1 = ++frog2;
+     }
+     return output;
+ }
+ 
  char *get_time() {
      time_t t;
      char *time_string;

Re: [PATCH] (post 1.2?) make_html_safe

Posted by Dean Gaudet <dg...@arctic.org>.
On Fri, 2 May 1997, Rodent of Unusual Size wrote:
>     So.. how long have you been speaking of yourself in the third
>     person?  What seems to be troubling you? <g>

snicker

>     Here you are.. complete with comments.  BTW, is there any particular
>     reason there isn't a util.h containing the prototypes?

Kind of a memory intensive implementation ;)  It turns out that
escape_html() already does what I want.

Even escape_html is memory intensive though when used like this
if you've got, say 1000 children (I've got two servers like this --
it's quite painful looking at /status already).  But anyhow, this does
fix the bug.

Dean

Index: mod_status.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_status.c,v
retrieving revision 1.46
diff -c -3 -r1.46 mod_status.c
*** mod_status.c	1997/04/24 23:35:23	1.46
--- mod_status.c	1997/05/04 19:41:28
***************
*** 497,503 ****
  		    format_byte_out(r,bytes);
  		    rputs(")\n",r);
  		    rprintf(r," <i>%s {%s}</i><br>\n\n",
! 			    score_record.client, score_record.request);
  		}
  		else /* !no_table_report */
  		{
--- 497,504 ----
  		    format_byte_out(r,bytes);
  		    rputs(")\n",r);
  		    rprintf(r," <i>%s {%s}</i><br>\n\n",
! 			    score_record.client,
! 			    escape_html(r->pool, score_record.request));
  		}
  		else /* !no_table_report */
  		{
***************
*** 553,559 ****
  			(float)bytes/MBYTE);
  		    rprintf(r,"<td>%s<td nowrap>%s<td nowrap>%s</tr>\n\n",
  			    score_record.client, score_record.vhost,
! 			    score_record.request);
  		}	/* no_table_report */
  	    }		/* !short_report */
  	}		/* if (<active child>) */
--- 554,560 ----
  			(float)bytes/MBYTE);
  		    rprintf(r,"<td>%s<td nowrap>%s<td nowrap>%s</tr>\n\n",
  			    score_record.client, score_record.vhost,
! 			    escape_html(r->pool, score_record.request));
  		}	/* no_table_report */
  	    }		/* !short_report */
  	}		/* if (<active child>) */