mailarchive of the ptxdist mailing list
 help / color / mirror / Atom feed
From: Michael Olbrich <m.olbrich@pengutronix.de>
To: ptxdist@pengutronix.de
Subject: Re: [ptxdist] [PATCH] add some patches with fixes, partly queued upstream
Date: Wed, 19 Mar 2014 10:49:21 +0100	[thread overview]
Message-ID: <20140319094921.GH5223@pengutronix.de> (raw)
In-Reply-To: <1395220750-21683-1-git-send-email-post@lespocky.de>

On Wed, Mar 19, 2014 at 10:19:09AM +0100, Alexander Dahl wrote:
> Upstream migrated the old code base to github in 2011:
> https://github.com/rafaelsteil/libcgi – I got the old ptxdist patches
> merged in 2012 and two fixes for mem leakes as well. Today I made pull
> requests for Michael's patch from last year and another fix of mine from
> today. However I doubt the maintainer will do another release soon or
> even at all, so I add my patches here, too. I'm sorry, I squeezed the
> ptxdist patches into one upstream, so Robert lost his credit there, but
> this is not topic of this series discussion. ;-)

Can you replace our patches with whatever was applied upstream? That will
make it easier in the future if we ever get a release.
And mark them as upstream (like patches/opkg-utils-r4747/series for
example).

Michael

> Signed-off-by: Alexander Dahl <post@lespocky.de>
> ---
>  ...ling-whitespace-my-editor-would-do-this-a.patch | 1334 ++++++++++++++++++++
>  ...-allocated-by-unescape_special_chars-afte.patch |   64 +
>  ...-allocated-for-reading-and-parsing-POST-d.patch |   32 +
>  .../0014-FILE-requires-including-stdio.patch       |   21 +
>  ...pe-by-optimizing-hextable-init-and-access.patch |   93 ++
>  patches/libcgi-1.0/series                          |    7 +-
>  6 files changed, 1550 insertions(+), 1 deletion(-)
>  create mode 100644 patches/libcgi-1.0/0011-remove-trailing-whitespace-my-editor-would-do-this-a.patch
>  create mode 100644 patches/libcgi-1.0/0012-free-memory-allocated-by-unescape_special_chars-afte.patch
>  create mode 100644 patches/libcgi-1.0/0013-free-memory-allocated-for-reading-and-parsing-POST-d.patch
>  create mode 100644 patches/libcgi-1.0/0014-FILE-requires-including-stdio.patch
>  create mode 100644 patches/libcgi-1.0/0015-fix-unescape-by-optimizing-hextable-init-and-access.patch
> 
> diff --git a/patches/libcgi-1.0/0011-remove-trailing-whitespace-my-editor-would-do-this-a.patch b/patches/libcgi-1.0/0011-remove-trailing-whitespace-my-editor-would-do-this-a.patch
> new file mode 100644
> index 0000000..cb0383c
> --- /dev/null
> +++ b/patches/libcgi-1.0/0011-remove-trailing-whitespace-my-editor-would-do-this-a.patch
> @@ -0,0 +1,1334 @@
> +From: Alexander Dahl <post@lespocky.de>
> +Date: Wed, 24 Oct 2012 11:20:24 +0200
> +Subject: [PATCH] remove trailing whitespace (my editor would do this all the
> + time)
> +
> +---
> + src/base64.c  |   60 ++++++++++++++---------------
> + src/cgi.c     |   62 +++++++++++++++---------------
> + src/cgi.h     |    8 ++--
> + src/cookie.c  |   20 +++++-----
> + src/error.c   |    2 +-
> + src/general.c |   50 ++++++++++++------------
> + src/list.c    |   24 ++++++------
> + src/md5.c     |    6 +--
> + src/session.c |  118 ++++++++++++++++++++++++++++-----------------------------
> + src/string.c  |   74 ++++++++++++++++++------------------
> + 10 files changed, 212 insertions(+), 212 deletions(-)
> +
> +diff --git a/src/base64.c b/src/base64.c
> +index a6e5d5a..9231f84 100644
> +--- a/src/base64.c
> ++++ b/src/base64.c
> +@@ -1,6 +1,6 @@
> + /*
> + 	LibCGI base64 manipulation functions is extremly based on the work of Bob Tower,
> +-	from its projec http://base64.sourceforge.net. The functions were a bit modicated. 
> ++	from its projec http://base64.sourceforge.net. The functions were a bit modicated.
> + 	Above is the MIT license from b64.c original code:
> + 
> + LICENCE:        Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc.
> +@@ -46,19 +46,19 @@ void encodeblock( unsigned char in[3], unsigned char out[4], int len )
> + }
> + 
> + void decodeblock( unsigned char in[4], unsigned char out[3] )
> +-{   
> ++{
> + 	out[0] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
> + 	out[1] = (unsigned char ) (in[1] << 4 | in[2] >> 2);
> + 	out[2] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
> + }
> + 
> +-/** 
> ++/**
> + * @ingroup libcgi_string
> + */
> + 
> + /**
> + * Encodes a given tring to its base64 form.
> +-* 
> ++*
> + * @param *str String to convert
> + * @return Base64 encoded String
> + * @see str_base64_decode
> +@@ -69,84 +69,84 @@ char *str_base64_encode(char *str)
> + 	unsigned int i, len, blocksout = 0, linesize = strlen(str);
> + 	char *tmp = str;
> + 	char *result = (char *)malloc((linesize + 3 - linesize % 3) * 4 / 3 + 1);
> +-	
> ++
> + 	if (!result)
> + 		libcgi_error(E_MEMORY, "Failed to alloc memory at base64.c");
> +-		
> ++
> + 	while (*tmp) {
> + 		len = 0;
> + 
> + 		for( i = 0; i < 3; i++ ) {
> + 			in[i] = (unsigned char)(*tmp);
> +-			
> ++
> + 			if (*tmp)
> + 				len++;
> + 			else
> + 				in[i] = 0;
> +-			
> ++
> + 			tmp++;
> + 		}
> +-		
> ++
> + 		if( len ) {
> + 			encodeblock( in, out, len);
> +-		
> +-			for( i = 0; i < 4; i++ ) 
> ++
> ++			for( i = 0; i < 4; i++ )
> + 				result[blocksout++] = out[i];
> +-		}		
> ++		}
> + 	}
> +-	
> ++
> + 	result[blocksout] = '\0';
> + 	return result;
> + }
> + 
> +-/** 
> ++/**
> + * @ingroup libcgi_string
> + */
> + 
> + /**
> + * Decode a base64 encoded string.
> +-* 
> ++*
> + * @param *str Encoded String to decode
> + * @return The decoded string
> + * @see str_base64_encode
> + **/
> + char *str_base64_decode(char *str)
> +-{	
> ++{
> + 	unsigned char in[4], out[3], v;
> + 	unsigned int i, len, pos = 0;
> + 	char *tmp = str;
> +-	
> ++
> + 	char *result = (char *)malloc(strlen(str) + 1);
> + 	if (!result)
> + 		libcgi_error(E_MEMORY, "Failed to alloc memory at base64.c");
> +-		
> ++
> + 	while(*tmp) {
> + 		for( len = 0, i = 0; i < 4 && *tmp; i++ ) {
> + 			v = 0;
> +-			
> +-			while(*tmp && v == 0 ) {			
> +-				v = (unsigned char)(*tmp);				
> +-				v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]);				
> +-				
> ++
> ++			while(*tmp && v == 0 ) {
> ++				v = (unsigned char)(*tmp);
> ++				v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]);
> ++
> + 				if( v )
> + 					v = (unsigned char) ((v == '$') ? 0 : v - 61);
> +-					
> ++
> + 				tmp++;
> + 			}
> +-			
> ++
> + 			if(*tmp) {
> + 				len++;
> +-				
> +-				if( v ) 
> ++
> ++				if( v )
> + 					in[i] = (unsigned char) (v - 1);
> + 			}
> +-			else 
> ++			else
> + 				in[i] = 0;
> + 		}
> +-		
> ++
> + 		if(len) {
> + 			decodeblock( in, out );
> +-			
> ++
> + 			for( i = 0; i < len - 1; i++ )
> + 				result[pos++] = out[i];
> + 		}
> +diff --git a/src/cgi.c b/src/cgi.c
> +index eca9ac2..e9d76ae 100644
> +--- a/src/cgi.c
> ++++ b/src/cgi.c
> +@@ -27,7 +27,7 @@
> + #include "cgi.h"
> + #include "error.h"
> + 
> +-// Whow... if hextable array has a length less than 256, 
> ++// Whow... if hextable array has a length less than 256,
> + // the cgi_unescape_special_chars function will fail.  And I don't know why
> + static int hextable[256];
> + 
> +@@ -61,13 +61,13 @@ formvars *process_data(char *query, formvars **start, formvars **last, const cha
> + 	aux = query;
> + 	while (*query) {
> + 		position = 0;
> +-				
> ++
> + 		data = (formvars *)malloc(sizeof(formvars));
> + 		if (!data)
> + 			libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
> +-			
> +-		memset(data, 0, sizeof(formvars));							
> +-		
> ++
> ++		memset(data, 0, sizeof(formvars));
> ++
> + 		// Scans the string for the next 'delim' character
> + 		while (*aux && (*aux != delim)) {
> + 			position++;
> +@@ -86,7 +86,7 @@ formvars *process_data(char *query, formvars **start, formvars **last, const cha
> + 
> + 		strncpy(data->name, query, position);
> + 		data->name[position] = '\0';
> +-		
> ++
> + 		query = aux;
> + 		position = 0;
> + 		while (*aux && (*aux != sep)) {
> +@@ -97,27 +97,27 @@ formvars *process_data(char *query, formvars **start, formvars **last, const cha
> + 					position++;
> + 				}
> + 			}
> +-			else			
> ++			else
> + 				position++;
> +-				
> ++
> + 			aux++;
> + 			i++;
> + 		}
> +-				
> ++
> + 		if (*aux) {
> + 			aux++;
> + 			i++;
> + 		}
> +-		
> ++
> + 		data->value = (char *)malloc(position+1);
> + 		if (data->value == NULL)
> + 			libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
> + 
> + 		strncpy(data->value, cgi_unescape_special_chars(query), position);
> + 		data->value[position] = '\0';
> +-		
> ++
> + 		slist_add(data, start, last);
> +-		
> ++
> + 		query = aux;
> + 	}
> + 
> +@@ -134,8 +134,8 @@ formvars *process_data(char *query, formvars **start, formvars **last, const cha
> + /**
> + * Process HTML form or URL data.
> + * Used to retrieve GET or POST data. It handles automaticaly the correct REQUEST_METHOD, so you don't need to afraid about it.
> +-* @return Returns the contents of URL or FORM into a formvars variable, or NULL if FALSE. Most of time, you 
> +-* don't need any variable to store the form data, because is used an internal variable to manipulate the contents. 
> ++* @return Returns the contents of URL or FORM into a formvars variable, or NULL if FALSE. Most of time, you
> ++* don't need any variable to store the form data, because is used an internal variable to manipulate the contents.
> + * @see cgi_init, cgi_init_headers
> + **/
> + formvars *cgi_process_form()
> +@@ -146,7 +146,7 @@ formvars *cgi_process_form()
> + 
> + 	// When METHOD has no contents, the default action is to process it as GET method
> + 	if (method == NULL || !strcasecmp("GET", method)) {
> +-		char *dados; 
> ++		char *dados;
> + 		dados =	getenv("QUERY_STRING");
> + 
> + 		// Sometimes, GET comes with not any data
> +@@ -222,7 +222,7 @@ int cgi_include(const char *filename)
> + 
> + 		return 0;
> + 	}
> +-	
> ++
> +  	while (fgets(buffer, 255, inc))
> + 		printf("%s", buffer);
> + 
> +@@ -250,7 +250,7 @@ void cgi_init_headers()
> + * @param name Form variable name
> + * @return Form variable contents
> + * @see cgi_param
> +-* 
> ++*
> + * Example:
> + * For example, if in your HTML you have something like<br>
> + *  <br>
> +@@ -262,7 +262,7 @@ void cgi_init_headers()
> + * </pre>
> + *       <br>
> + * then, to retrieve all values, you can make a code like<br><br>
> +-* 
> ++*
> + * \code
> + * // ...
> + * char *data;
> +@@ -296,13 +296,13 @@ char *cgi_param_multiple(const char *name)
> + }
> + 
> + /**
> +-*  Recirects to the specified url. 
> ++*  Recirects to the specified url.
> + * Remember that you cannot send any header before this function, or it will not work.
> + * <b>Note:</b><br>
> + * LibCGI does not implement RFC 2396 to make the lib simple and quick. You should be sure
> +-* to pass a correct URI to this function. 
> ++* to pass a correct URI to this function.
> + * @param url url to redirect the browser
> +-* 
> ++*
> + * \code
> + * cgi_redirect("http://wwww.linux.org");
> + * \endcode
> +@@ -347,7 +347,7 @@ void init_hex_table()
> + }
> + 
> + /**
> +-*  Main cgi function. 
> ++*  Main cgi function.
> + *  Configures all (most?) we need to  get cgi library working correctly. It MUST be called before
> + *  any other cgi function.
> + *  @see cgi_end, cgi_process_form, cgi_init_headers
> +@@ -360,7 +360,7 @@ int cgi_init()
> + 	// cause problems with session's. Note that, when you want
> + 	// to use session within your program, you need  cgi_get_cookies()
> + 	// before session_start(), otherwise we will get some problems... :)
> +-	// Calling this function here is the best way. Trust me :)	
> ++	// Calling this function here is the best way. Trust me :)
> + 	cgi_get_cookies();
> + 
> + 	return 1;
> +@@ -377,7 +377,7 @@ void cgi_end()
> + 
> + 	formvars_last = NULL;
> + 
> +-	if (sess_list_start) 
> ++	if (sess_list_start)
> + 		slist_free(&sess_list_start);
> + 
> + 	if (cookies_start)
> +@@ -414,7 +414,7 @@ char *cgi_unescape_special_chars(char *str)
> + 			tmp[pos] = ' ';
> + 		else
> + 			tmp[pos] = str[i];
> +-		
> ++
> + 		pos++;
> + 	}
> + 
> +@@ -464,21 +464,21 @@ char *cgi_escape_special_chars(char *str)
> + 
> + /**
> + * Gets the of HTML or URL variable indicated by 'name'
> +-* @param name Form Variable name 
> ++* @param name Form Variable name
> + * @see cgi_param_multiple,  cgi_process_form, cgi_init
> +-* 
> ++*
> + * \code
> + * // ...
> + * char *contents;
> +-* 
> ++*
> + * cgi_init();
> + * cgi_process_form();
> + * cgi_init_headers();
> +-* 
> ++*
> + * contents = cgi_param("foo");
> +-* 
> ++*
> + * puts(contents);
> +-* 
> ++*
> + * // ...
> + * \endcode
> + **/
> +diff --git a/src/cgi.h b/src/cgi.h
> +index 9812e7a..731735d 100644
> +--- a/src/cgi.h
> ++++ b/src/cgi.h
> +@@ -28,7 +28,7 @@ extern "C" {
> + 
> + // general purpose linked list. Actualy isn't very portable
> + // because uses only 'name' and 'value' variables to store data.
> +-// Problably, in a future release, this will be replaced by 
> ++// Problably, in a future release, this will be replaced by
> + // another type of struct
> + typedef struct formvarsA {
> +         char *name;
> +@@ -86,7 +86,7 @@ extern int slist_delete(char *name, formvars **start, formvars **last);
> + extern char *slist_item(const char *name, formvars *start);
> + 
> + extern void slist_free(formvars **start);
> +- 
> ++
> + // Session stuff
> + // We can use this variable to get the error message from a ( possible ) session error
> + // Use it togheter with session_lasterror
> +@@ -98,7 +98,7 @@ extern formvars *sess_list_start;
> + 
> + extern char SESSION_SAVE_PATH[255];
> + extern char SESSION_COOKIE_NAME[50];
> +- 
> ++
> + extern void cgi_session_set_max_idle_time(unsigned long seconds);
> + extern int cgi_session_destroy();
> + extern int cgi_session_register_var(const char *name, const char *value);
> +@@ -109,7 +109,7 @@ extern int cgi_session_start();
> + extern void cgi_session_cookie_name(const char *cookie_name);
> + extern char *cgi_session_var(const char *name);
> + extern void cgi_session_save_path(const char *path);
> +- 
> ++
> + #ifdef __cplusplus
> + }
> + #endif
> +diff --git a/src/cookie.c b/src/cookie.c
> +index a116503..e9dee9e 100644
> +--- a/src/cookie.c
> ++++ b/src/cookie.c
> +@@ -41,24 +41,24 @@ extern int cgi_display_errors;
> + */
> + 
> + /**
> +-* Send a cookie to the client. 
> ++* Send a cookie to the client.
> + * @param name Cookie name
> + * @param value Cookie value
> +-* @param max_age  Cookie time life, in seconds. A value equal to 0 ( zero ) means to discard the cookie when the session is done. 
> ++* @param max_age  Cookie time life, in seconds. A value equal to 0 ( zero ) means to discard the cookie when the session is done.
> + * @param path Cookie path at the server
> + * @param domain Domain where cookie will work :)
> + * @param secure Secure or not
> + * @see cgi_cookie_value
> +-* 
> ++*
> + * \code
> + * cgi_add_cookie("mycookie", "mycookie value", 0, 0, 0, 0);
> +-* \endcode  
> ++* \endcode
> + **/
> +-int cgi_add_cookie(const char *name, 
> +-	const char *value, 
> ++int cgi_add_cookie(const char *name,
> ++	const char *value,
> + 	const char *max_age,
> +-	const char *path, 
> +-	const char *domain, 
> ++	const char *path,
> ++	const char *domain,
> + 	const int secure)
> + {
> + 	if (headers_initialized)
> +@@ -81,7 +81,7 @@ int cgi_add_cookie(const char *name,
> + 
> + formvars *cgi_get_cookies()
> + {
> +-	register formvars *data;	
> ++	register formvars *data;
> + 	register size_t position;
> + 	char *cookies, *aux;
> + 
> +@@ -117,7 +117,7 @@ formvars *cgi_get_cookies()
> + 			position = strlen(cookies);
> + 		}
> + 		else {
> +-			while (*aux++ != ';') 
> ++			while (*aux++ != ';')
> + 				position++;
> + 			// Eliminate the blank space after ';'
> + 			aux++;
> +diff --git a/src/error.c b/src/error.c
> +index 5d2da12..2f48b3b 100644
> +--- a/src/error.c
> ++++ b/src/error.c
> +@@ -21,7 +21,7 @@ void libcgi_error(int error_code, const char *msg, ...)
> + 		return;
> + 
> + 	cgi_init_headers();
> +-	va_start(arguments, msg);	
> ++	va_start(arguments, msg);
> + 
> + 	printf("<b>%s</b>: ", libcgi_error_type[error_code]);
> + 	vprintf(msg, arguments);
> +diff --git a/src/general.c b/src/general.c
> +index ad3435c..9662ece 100644
> +--- a/src/general.c
> ++++ b/src/general.c
> +@@ -49,7 +49,7 @@ static int ncodes = sizeof(he) / sizeof(struct iso8859_15);
> + 
> + /**************************************************************
> + 						GENERAL GROUP
> +-***************************************************************/	
> ++***************************************************************/
> + /** @defgroup libcgi_general General purpose
> + * @{
> + */
> +@@ -59,42 +59,42 @@ static int ncodes = sizeof(he) / sizeof(struct iso8859_15);
> + * like '&lt' and '&gt'
> + * @param str String containing code to parse
> + * @return The new string
> +-* @author Robert Csok <rcsok@gmx.de> 
> ++* @author Robert Csok <rcsok@gmx.de>
> + */
> + // This one needs the struct and ncodes above.
> +-// ncodes is the number of elements in the struct. 
> ++// ncodes is the number of elements in the struct.
> + char *htmlentities(const char *str)
> + {
> + 	char *buf;
> + 	int siz, len, i = 0, j;
> + 
> + 	siz = strlen(str) + 1;
> +-	
> +-	buf = (char *)malloc(siz);	
> ++
> ++	buf = (char *)malloc(siz);
> + 	if (!buf)
> + 		libcgi_error(E_MEMORY, "Failed to alloc memory at htmlentities, cgi.c");
> +-	
> ++
> + 	for (; *str; str++, i++)  {
> + 		for (j = 0; j < ncodes; j++) {
> + 			if (*str == he[j].code) {
> + 				len = strlen(he[j].html) - 1;
> +-				
> +-				buf = realloc(buf, siz += len);	
> ++
> ++				buf = realloc(buf, siz += len);
> + 				if (!buf)
> + 					libcgi_error(E_MEMORY, "Failed to alloc memory at htmlentities, cgi.c");
> +-				
> ++
> + 				strcpy(buf + i, he[j].html);
> + 				i += len;
> + 				break;
> + 			}
> + 		}
> +-			
> +-		if (j == ncodes) 
> ++
> ++		if (j == ncodes)
> + 			buf[i] = *str;
> + 	}
> +-	
> ++
> + 	buf[i] = '\0';
> +-	return buf;	
> ++	return buf;
> + }
> + 
> + /**
> +@@ -102,23 +102,23 @@ char *htmlentities(const char *str)
> + * @param filename Filename to open
> + * @param total Integer variable passed as reference, which will store the total of items
> + * @return Returns the file in an array. Each element of the array corresponds to a line in the file.
> +-* 
> ++*
> + * \code
> + * char **lines;
> + * unsigned int total, i;
> +-*  
> ++*
> + * lines = file("filename.ext", &total);
> +-*    
> ++*
> + * printf("Total of lines: %u\n", total);
> +-*    
> ++*
> + * for (i = 0; i < total; i++)
> + *	printf("[%u] %s\n", i, lines[i]);
> +-*     
> ++*
> + * for (i = 0; i < total; i++) {
> + * 	if (lines[i])
> + *		 free(lines[i]);
> + * }
> +-* \endcode	  
> ++* \endcode
> + */
> + char **file(const char *filename, unsigned int *total)
> + {
> +@@ -138,7 +138,7 @@ char **file(const char *filename, unsigned int *total)
> + 	// initial line length
> + 	columms = 100;
> + 
> +-	// How many characteres in the line 
> ++	// How many characteres in the line
> + 	char_count = 1;
> + 
> + 	i = 0;
> +@@ -148,9 +148,9 @@ char **file(const char *filename, unsigned int *total)
> + 	if (!str)
> + 		libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
> + 
> +-	// Allocate initial memory to buf variable. It is the one 
> ++	// Allocate initial memory to buf variable. It is the one
> + 	// that will contain the chars of the lines
> +-	// By default, we're allocating 80 chars.. if more is needed, 
> ++	// By default, we're allocating 80 chars.. if more is needed,
> + 	// then we'll realloc()
> + 	buf = (char *)malloc(columms);
> + 	if (buf == NULL)
> +@@ -158,8 +158,8 @@ char **file(const char *filename, unsigned int *total)
> + 
> + 	while (!feof(fp)) {
> + 		ch = fgetc(fp);
> +-		
> +-		// The next while() loop is  to get all contents of actual line 
> ++
> ++		// The next while() loop is  to get all contents of actual line
> + 		while ((ch != '\n') && (ch != EOF)) {
> + 			// Increments the character counter
> + 			char_count++;
> +@@ -201,7 +201,7 @@ char **file(const char *filename, unsigned int *total)
> + 	fclose(fp);
> + 
> + 	*total = lines - 1;
> +-	return str;	
> ++	return str;
> + }
> + 
> + /**
> +diff --git a/src/list.c b/src/list.c
> +index 8bd68f7..423f28b 100644
> +--- a/src/list.c
> ++++ b/src/list.c
> +@@ -26,15 +26,15 @@
> + #include "error.h"
> + #include "cgi.h"
> + 
> +-// Add a new item to the list 
> ++// Add a new item to the list
> + void slist_add(formvars *item, formvars **start, formvars **last)
> + {
> + 	// if *start is empty, then our list is also empty. So, the only
> + 	// task to do is fill the variables *start and *last with the data pointed by item
> +-	// *start contains the firts item in the list, and we need *last to know the 
> ++	// *start contains the firts item in the list, and we need *last to know the
> + 	// end of the list
> + 	if (!*start) {
> +-		// item->next needs to be NULL, otherwise we never will 
> ++		// item->next needs to be NULL, otherwise we never will
> + 		// find the end of list
> + 		item->next = NULL;
> + 
> +@@ -59,8 +59,8 @@ void slist_add(formvars *item, formvars **start, formvars **last)
> + 
> + // Delete from list the item pointed by name
> + 
> +-// This code is a bit complicated, and I needed some 
> +-// long hours to terminate it. In a future release, 
> ++// This code is a bit complicated, and I needed some
> ++// long hours to terminate it. In a future release,
> + // I will explain the algorithm better
> + int slist_delete(char *name, formvars **start, formvars **last)
> + {
> +@@ -68,7 +68,7 @@ int slist_delete(char *name, formvars **start, formvars **last)
> + 	// *prior will store the prior item relacted to actual in the loop
> + 	formvars *begin, *prior;
> + 
> +-	// Before of all, is more simple to check if the item 
> ++	// Before of all, is more simple to check if the item
> + 	// to delete is in the next item. If true, we don't need
> + 	// to enter in the loop
> + 	if (!strcasecmp((*start)->name, name)) {
> +@@ -76,8 +76,8 @@ int slist_delete(char *name, formvars **start, formvars **last)
> + 		*start = (*start)->next;
> + 
> + 		// if start is null, then we haven't more itens
> +-		// in the list.. 
> +-		if (!*start) 
> ++		// in the list..
> ++		if (!*start)
> + 			*last = NULL;
> + 
> + 		return 1 ;
> +@@ -86,7 +86,7 @@ int slist_delete(char *name, formvars **start, formvars **last)
> + 	// Stores the start of the list
> + 	begin = *start;
> + 
> +-	// Stays in the loop while the item to be deleted 
> ++	// Stays in the loop while the item to be deleted
> + 	// is not found
> + 	while (*start) {
> + 		// Stores the prior item of the list
> +@@ -98,13 +98,13 @@ int slist_delete(char *name, formvars **start, formvars **last)
> + 		// the next item is the one to be deleted???
> + 		if (!strcasecmp((*start)->next->name, name)) {
> + 			// Before, check if the item that will be deleted
> +-			// is the last... if true, then the next item need to 
> ++			// is the last... if true, then the next item need to
> + 			// contain null ( the end of list ), and the actual
> + 			// value is changed with the value of the prior variable
> + 			if ((*start)->next == *last) {
> + 				(*start)->next = NULL;
> + 				*last = prior;
> +-			}			
> ++			}
> + 			else
> + 				// otherwise... well
> + 				// the item that will be deleted is pointed
> +@@ -157,7 +157,7 @@ char *slist_item(const char *name, formvars *start)
> + 	begin = start;
> + 
> + 	while (begin) {
> +-		if (!strcasecmp(begin->name, name)) 
> ++		if (!strcasecmp(begin->name, name))
> + 			return (!begin->value[0] ? NULL : begin->value);
> + 
> + 		begin = begin->next;
> +diff --git a/src/md5.c b/src/md5.c
> +index 44a1de2..56cf5c0 100644
> +--- a/src/md5.c
> ++++ b/src/md5.c
> +@@ -59,7 +59,7 @@ typedef struct MD5Context MD5_CTX;
> + 
> + /**
> + * Converts a string to MD5 format.
> +-* 
> ++*
> + * @param str String to convert to MD5 hash
> + * @return MD5 hash code
> + **/
> +@@ -82,7 +82,7 @@ char *md5(const char *str)
> + 
> + 	// finally, here is a final string encrypted in hex float format
> + 	MD5Final(md, &context);
> +-	
> ++
> + 	// here, the loop is less than 32 because a md5 string can content
> + 	// just 32 bytes
> + 	for(i = 0; i < 32; i++) {
> +@@ -206,7 +206,7 @@ MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
> + }
> + 
> + /*
> +- * Final wrapup - pad to 64-byte boundary with the bit pattern 
> ++ * Final wrapup - pad to 64-byte boundary with the bit pattern
> +  * 1 0* (64-bit count of bits processed, MSB-first)
> +  */
> + void
> +diff --git a/src/session.c b/src/session.c
> +index a9d2ef1..4d96c3e 100644
> +--- a/src/session.c
> ++++ b/src/session.c
> +@@ -26,7 +26,7 @@
> +  *****************************************************
> + */
> + 
> +-/** 
> ++/**
> + * @defgroup libcgi_session Session Handling
> + *   One of the most diferencials of LibCGI is its support to sessions, a mechanism that permits
> + *   the application to keep variables trough the user's session, when he is visiting your website.
> +@@ -35,9 +35,9 @@
> + * <tr>
> + * <td>
> + * 	Session functions are easy to use and understand, and probably you'll want to take a closer
> +-* 	look at <i>cgi_session_save_path()</i> and <i>cgi_session_cookie_name()</i> functions. These functions, 
> ++* 	look at <i>cgi_session_save_path()</i> and <i>cgi_session_cookie_name()</i> functions. These functions,
> + * 	let the programmer to set the directory where session files will
> +-* 	be saved in the hard disk and the cookie name to the session, respectively. 
> ++* 	be saved in the hard disk and the cookie name to the session, respectively.
> + * 	<br><br>
> + * 	As the CGI is running on the webserver which a common user, it have full access to its respective session
> + * 	file. But the most big problem is that you may
> +@@ -102,7 +102,7 @@ const char *session_error_message[] = {
> +  	"Session variable not registered",
> +  	"Failed to open session file for manipulation"
> + };
> +- 
> ++
> + 
> + // cgi.c
> + extern int headers_initialized;
> +@@ -142,9 +142,9 @@ void sess_generate_id()
> + 	sess_fname = (char *)malloc(save_path_len + SESS_ID_LEN + 1);
> + 	if (!sess_fname)
> + 		libcgi_error(E_MEMORY, "File %s, line %s", __FILE__, __LINE__);
> +-		
> +-	for (i = 0; i < SESS_ID_LEN; i++) 
> +-		sess_id[i] = table[rand()%len];	
> ++
> ++	for (i = 0; i < SESS_ID_LEN; i++)
> ++		sess_id[i] = table[rand()%len];
> + 	sess_id[SESS_ID_LEN] = '\0';
> + 
> + 	snprintf(sess_fname, (SESS_ID_LEN + save_path_len + 1), "%s%s%s", SESSION_SAVE_PATH, SESSION_FILE_PREFIX, sess_id);
> +@@ -155,10 +155,10 @@ int sess_create_file()
> + {
> + 	// timeval, gettimeofday are used togheter with srand() function
> + 	struct timeval tv;
> +-	
> ++
> + 	gettimeofday(&tv, NULL);
> + 	srand(tv.tv_sec * tv.tv_usec * 100000);
> +-	
> ++
> + 	sess_generate_id();
> + 	sess_file = fopen(sess_fname, "w");
> + 	if (!sess_file) {
> +@@ -168,16 +168,16 @@ int sess_create_file()
> + 
> + 		return 0;
> + 	}
> +-	
> ++
> + 	// Changes file permission to 0600
> + 	chmod(sess_fname, S_IRUSR|S_IWUSR);
> + 	fclose(sess_file);
> + 
> + 	return 1;
> +-}	
> ++}
> + 
> +-/** 
> +-* Destroys the session. 
> ++/**
> ++* Destroys the session.
> + * Destroys the current opened session, including all data.
> + * After session_destroy() was called, is not more
> + * possible to use session functions before an another
> +@@ -193,10 +193,10 @@ int cgi_session_destroy()
> + 		sess_finitialized = 0;
> + 		slist_free(&sess_list_start);
> + 
> +-		// hhhmmm.. 
> +-		if (headers_initialized) 
> ++		// hhhmmm..
> ++		if (headers_initialized)
> + 			libcgi_error(E_WARNING, "Headers alreay sent. session_destroy() can't fully unregister the session");
> +-		else 
> ++		else
> + 			cgi_add_cookie(SESSION_COOKIE_NAME, "", 0, 0, 0, 0);
> + 
> + 		return 1;
> +@@ -213,9 +213,9 @@ int cgi_session_destroy()
> + int sess_file_rewrite()
> + {
> + 	formvars *data;
> +-	
> ++
> + 	cgi_init_headers();
> +-	
> ++
> + 	// Rewrites all data to session file
> + 	sess_file = fopen(sess_fname, "w");
> + 
> +@@ -226,7 +226,7 @@ int sess_file_rewrite()
> + 
> + 		return 0;
> + 	}
> +-	
> ++
> + 	data = sess_list_start;
> + 
> + 	if (data != NULL) {
> +@@ -260,10 +260,10 @@ char *cgi_session_var(const char *var_name)
> + 
> + /**
> + * Defines the name of the cookie that LibCGI will use to store session's ID.
> +-* This function works like cgi_session_save_path(). 
> +-* This functionality let you to use  different names for each site, but remember, you cannot 
> +-* use multiple session for the same application yet. 
> +-* 
> ++* This function works like cgi_session_save_path().
> ++* This functionality let you to use  different names for each site, but remember, you cannot
> ++* use multiple session for the same application yet.
> ++*
> + * @param cookie_name Name of the cookie to create
> + * @see cgi_session_save_path()
> + * @note This function must be called before cgi_session_start()
> +@@ -276,23 +276,23 @@ void cgi_session_cookie_name(const char *cookie_name)
> + /**
> + * Defines where session control files will be saved.
> + * If in the your CGI you don't make a call to cgi_session_save_path(), LibCGI will
> +-* use the default value, which is "/tmp/". To see how to modify the value, see the following example. 
> ++* use the default value, which is "/tmp/". To see how to modify the value, see the following example.
> + * <br>Just note you need to add '/' at the end of the directory name
> + * \code
> + * // your_cgi.c
> +-* // Set "session_files" directory under your CGI directory as the path 
> ++* // Set "session_files" directory under your CGI directory as the path
> + * // which LibCGI will use to store session files.
> +-* 
> ++*
> + * cgi_session_save_path("session_files/");
> + *  \endcode
> +-*  
> +-*  Note that using this form, LibCGI will search for "session_files" directory using relative path 
> ++*
> ++*  Note that using this form, LibCGI will search for "session_files" directory using relative path
> + *  to your cgi application. For example, if your CGI script is located at
> + *  /usr/local/httpd/web/your_name/cgi-bin/ directory, and you use the above declaration, the files for the session will be
> +-* stored at  /usr/local/httpd/web/your_name/cgi-bin/session_files directory. 
> ++* stored at  /usr/local/httpd/web/your_name/cgi-bin/session_files directory.
> + * Resuming, the path is relative to where your application resides. <br><br>And remember, LibCGI \b does \b not
> +-* create the directory for you. 
> +-* 
> ++* create the directory for you.
> ++*
> + * @param path Path, relative or absolute
> + * @see cgi_session_cookie_name
> + * @note This function must be called before cgi_session_start()
> +@@ -313,12 +313,12 @@ void cgi_session_save_path(const char *path)
> + int cgi_session_register_var(const char *name, const char *value)
> + {
> + 	formvars *data;
> +-	
> ++
> + 	if (!sess_initialized) {
> + 		session_lasterror = SESS_NOT_INITIALIZED;
> + 
> + 		libcgi_error(E_WARNING, session_error_message[session_lasterror]);
> +-		
> ++
> + 		return 0;
> + 	}
> + 
> +@@ -328,14 +328,14 @@ int cgi_session_register_var(const char *name, const char *value)
> + 			session_lasterror = SESS_OPEN_FILE;
> + 
> + 			libcgi_error(E_WARNING, session_error_message[session_lasterror]);
> +-			
> ++
> + 			return 0;
> + 		}
> +-		
> ++
> + 		data = (formvars *)malloc(sizeof(formvars));
> + 		if (!data)
> + 			libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
> +-		
> ++
> + 		data->name = (char *)malloc(strlen(name) + 1);
> + 		if (!data->name)
> + 			libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
> +@@ -350,10 +350,10 @@ int cgi_session_register_var(const char *name, const char *value)
> + 
> + 		strncpy(data->name, name, strlen(name));
> + 		data->name[strlen(name)] = '\0';
> +-		
> ++
> + 		strncpy(data->value, value, strlen(value));
> + 		data->value[strlen(value)] = '\0';
> +-		
> ++
> + 		if (!sess_list_last)
> + 			fprintf(sess_file, "%s=%s", name, value);
> + 		else
> +@@ -381,12 +381,12 @@ int cgi_session_alter_var(const char *name, const char *new_value)
> + {
> + 	register formvars *data;
> + 	unsigned int value_len;
> +-	
> ++
> + 	data = sess_list_start;
> + 	while (data) {
> + 		if (!strcmp(data->name, name)) {
> + 			value_len = strlen(new_value) + 1;
> +-			
> ++
> + 			if (value_len > strlen(data->value)) {
> + 				data->value = realloc(data->value, value_len+1);
> + 				if (!data->value)
> +@@ -396,7 +396,7 @@ int cgi_session_alter_var(const char *name, const char *new_value)
> + 
> + 			strncpy(data->value, new_value, value_len);
> + 			data->value[value_len] = '\0';
> +-			
> ++
> + 			sess_file_rewrite();
> + 
> + 			return 1;
> +@@ -404,9 +404,9 @@ int cgi_session_alter_var(const char *name, const char *new_value)
> + 
> + 		data = data->next;
> + 	}
> +-	
> ++
> + 	session_lasterror = SESS_VAR_NOT_REGISTERED;
> +-	
> ++
> + 	return 0;
> + }
> + 
> +@@ -437,7 +437,7 @@ int cgi_session_unregister_var(char *name)
> + 		session_lasterror = SESS_NOT_INITIALIZED;
> + 
> + 		libcgi_error(E_WARNING, session_error_message[session_lasterror]);
> +-		
> ++
> + 		return 0;
> + 	}
> + 
> +@@ -449,7 +449,7 @@ int cgi_session_unregister_var(char *name)
> + 		return 0;
> + 	}
> + 
> +-	if (!sess_file_rewrite()) 
> ++	if (!sess_file_rewrite())
> + 		return 0;
> + 
> + 	return 1;
> +@@ -457,7 +457,7 @@ int cgi_session_unregister_var(char *name)
> + 
> + /**
> + * Starts a new session.
> +-* This function is responsible for starting and creating a new 
> ++* This function is responsible for starting and creating a new
> + * session. It must be called before any other session function,
> + * and every time before any HTML header has sent.
> + * @see session_destroy()
> +@@ -472,13 +472,13 @@ int cgi_session_start()
> + 		session_lasterror = SESS_STARTED;
> + 
> + 		libcgi_error(E_WARNING, session_error_message[session_lasterror]);
> +-		
> ++
> + 		return 0;
> + 	}
> +-	
> ++
> + 	if (headers_initialized) {
> + 		session_lasterror = SESS_HEADERS_SENT;
> +-		
> ++
> + 		libcgi_error(E_WARNING, session_error_message[session_lasterror]);
> + 
> + 		return 0;
> +@@ -487,7 +487,7 @@ int cgi_session_start()
> + 	// Get the session ID
> + 	sid = cgi_cookie_value(SESSION_COOKIE_NAME);
> + 
> +-	// If there isn't a session ID, we need to create one 
> ++	// If there isn't a session ID, we need to create one
> + 	if (sid == NULL) {
> + 		if (sess_create_file()) {
> + 			cgi_add_cookie(SESSION_COOKIE_NAME, sess_id, 0, 0, 0, 0);
> +@@ -502,17 +502,17 @@ int cgi_session_start()
> + 	// Make sure the file exists
> + 	else {
> + 		save_path_len = strlen(SESSION_SAVE_PATH) + strlen(SESSION_FILE_PREFIX);
> +-		
> ++
> + 		sess_fname = (char *)malloc(save_path_len + SESS_ID_LEN + 1);
> + 		if (!sess_fname)
> + 			libcgi_error(E_MEMORY, "File %s, line %s", __FILE__, __LINE__);
> +-	
> ++
> + 		snprintf(sess_fname, (SESS_ID_LEN + save_path_len + 1), "%s%s%s", SESSION_SAVE_PATH, SESSION_FILE_PREFIX, sid);
> + 		sess_fname[SESS_ID_LEN + save_path_len] = '\0';
> +-		
> +-		errno = 0;		
> ++
> ++		errno = 0;
> + 		fp = fopen(sess_fname, "r");
> +-		if (errno == ENOENT) { 
> ++		if (errno == ENOENT) {
> + 			// The file doesn't exists. Create a new session
> + 			if (sess_create_file()) {
> + 				cgi_add_cookie(SESSION_COOKIE_NAME, sess_id, 0, 0, 0, 0);
> +@@ -532,15 +532,15 @@ int cgi_session_start()
> + 	sess_id[SESS_ID_LEN] = '\0';
> + 
> + 	// Now we need to read all the file contents
> +-	// This is a temporary solution, I'll try to 
> ++	// This is a temporary solution, I'll try to
> + 	// make a faster implementation
> + 	stat(sess_fname, &st);
> + 	buf = (char *)malloc(st.st_size + 2);
> + 	if (!buf)
> + 		libcgi_error(E_MEMORY, "File %s, line %s", __FILE__, __LINE__);
> +-		
> ++
> + 	fgets(buf, st.st_size+1, fp);
> +-		
> ++
> + 	if (buf != NULL && strlen(buf) > 1)
> + 		process_data(buf, &sess_list_start, &sess_list_last, '=', ';');
> + 
> +@@ -551,6 +551,6 @@ int cgi_session_start()
> + 	return 1;
> + }
> + 
> +-/** 
> ++/**
> + * @}
> + */
> +diff --git a/src/string.c b/src/string.c
> +index 3dc437f..e2bba97 100644
> +--- a/src/string.c
> ++++ b/src/string.c
> +@@ -31,7 +31,7 @@
> + /*********************************************************
> + * 					STRING GROUP
> + *********************************************************/
> +-/** 
> ++/**
> + * @defgroup libcgi_string Strings
> + * General string manipulation and utilities functions
> + * @{
> +@@ -40,12 +40,12 @@
> + /**
> + * Same to addslashes(), except that this one only do the action while 'n' is great than 0.
> + * @param s String to parse
> +-* @param n Number of characters to work with. 
> ++* @param n Number of characters to work with.
> + * @see addslashes()
> + * \code
> + * char *name = "My test string is called \"foobar\"";
> + * puts(name); // will display My test string is called "foobar"
> +-* 
> ++*
> + * name = addnslashes(name, 31);
> + * puts(name); // will display My test string is called \"foobar"
> + * \endcode
> +@@ -81,7 +81,7 @@ char *addnslashes(char *s, int n)
> + 	return tmp;
> + }
> + 
> +-/** 
> ++/**
> + * Add slashes to a string when necessary.
> + * Adds a '\' in every quote ( " ), apostrophe ( ' ) or  backslash ( \ )
> + * It's useful when working with databases, for example, because
> +@@ -93,7 +93,7 @@ char *addnslashes(char *s, int n)
> + * \code
> + * char *name = "My test string is called \"foobar\"";
> + * puts(name); // will display My test string is called "foobar"
> +-* 
> ++*
> + * name = addslashes(name);
> + * puts(name); // will display My test string is called \"foobar\"
> + * \endcode
> +@@ -131,7 +131,7 @@ char *stripnslashes(char *s, int n)
> + 		return NULL;
> + 
> + 	while (*s) {
> +-		if ((n-- > 0) && (*s == '\\')) 
> ++		if ((n-- > 0) && (*s == '\\'))
> + 			s++;
> + 		tmp[j++] = *s++;
> + 	}
> +@@ -233,10 +233,10 @@ void trim(char *str)
> + * Copy part of a string.
> + * Copy  count characters from src, starting from start
> + * @param src String to copy from
> +-* @param start Initial offset 
> ++* @param start Initial offset
> + * @param count Number of chars to copy
> + * @return The new string
> +-* 
> ++*
> + * \code
> + * char *part, *str = "Test one, test two";
> + * part = substr(str, 1, 5);
> +@@ -265,12 +265,12 @@ char *substr(char *src, const int start, const int count)
> + *  and storing the total of pieces in total
> + * @param src String to parse
> + * @param token Character delimiter to search.
> +-* @param total An integer variable passed as reference, which stores the total of 
> ++* @param total An integer variable passed as reference, which stores the total of
> + * itens of the array
> + * @return The array, where each item is one separeted by token
> +-* 
> ++*
> + * \code
> +-*  
> ++*
> + *  char **pieces;
> + *  char *name = "This,is,a,string,of,test";
> + *  int total, i;
> +@@ -280,14 +280,14 @@ char *substr(char *src, const int start, const int count)
> + * \endcode
> + **/
> + char **explode(char *src, const char *token, int *total)
> +-{	
> ++{
> + 	char **str;
> + 	register int i, j, count, item, start;
> + 	int len;
> + 
> + 	if (!src || !token) {
> + 		*total = 0;
> +-		
> ++
> + 		return NULL;
> + 	}
> + 
> +@@ -348,7 +348,7 @@ char **explode(char *src, const char *token, int *total)
> + 
> + /**
> + * Replace characteres in a string, but not more than 'n'.
> +-*  Replace all occourences of *delim on *src with characteres pointed by *with, 
> ++*  Replace all occourences of *delim on *src with characteres pointed by *with,
> + *  stopping after 'n' char.
> + *  @param *src String to parse
> + *  @param *delim Character to search that will be replaced
> +@@ -356,7 +356,7 @@ char **explode(char *src, const char *token, int *total)
> + *  @param n Maximum number of chars to parse
> + *  @return The new string
> + *  @see str_replace
> +-*  
> ++*
> + *  \code
> + *  char *linux = "Linux C";
> + *  linux = str_nreplace(linux, "C", "Cool", strlen(linux));
> +@@ -414,7 +414,7 @@ char *str_nreplace(char *src, const char *delim, const char *with, int n)
> + /**
> + * Replace characteres in a string.
> + *  Replace all occourences of *delim on *src with characteres pointed by *with.
> +-*  The problem with the folowing code is that the function only searches for the 
> ++*  The problem with the folowing code is that the function only searches for the
> + *  first caracter of *delim, ingoring the rest. Other problem is speed relacioned:
> + *  note that the function ever compare the length of *with to do the correct action.
> + *  @param src String to parse
> +@@ -422,7 +422,7 @@ char *str_nreplace(char *src, const char *delim, const char *with, int n)
> + *  @param with String to replace with
> + *  @return The new string
> + *  @see str_nreplace
> +-*  
> ++*
> + *  \code
> + *  char *linux = "Linux C";
> + *  linux = str_replace(linux, "C", "Cool");
> +@@ -454,14 +454,14 @@ char *replace(char *str, const char *delim, const char *with)
> + int strnpos(char *s, char *ch, unsigned int count)
> + {
> + 	register unsigned int pos = 0, i;
> +-	
> ++
> + 	for (i = 0; i <= count && *s; i++) {
> + 		if (*s++ == *ch)
> + 			return pos;
> +-		
> ++
> + 		pos++;
> + 	}
> +-	
> ++
> + 	return -1;
> + }
> + 
> +@@ -485,13 +485,13 @@ int strpos(char *s, char *ch)
> + *  @param count Number of characteres to delete
> + *  @return The new string
> + *  @see strndel()
> +-* 
> ++*
> + *  \code
> + *  *txt = "Some text to test anything";
> + *  puts(txt);
> + *  txt = strdel(txt, 2, 8);
> + *  puts(txt);
> +-* \endcode   
> ++* \endcode
> + **/
> + char *strdel(char *s, int start, int count)
> + {
> +@@ -508,7 +508,7 @@ char *strdel(char *s, int start, int count)
> + 		libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
> + 
> + 	for (i = 0; i < len; i++) {
> +-		if ((i >= start) && (i < (start+count))) 
> ++		if ((i >= start) && (i < (start+count)))
> + 			s++;
> + 		else
> + 			tmp[contador++] = *s++;
> +@@ -536,37 +536,37 @@ char *recvline(FILE *s)
> + 	size_t siz = 0;
> + 
> + 	for (; (ch = fgetc(s)) != EOF; i++) {
> +-		if (i == siz) 
> ++		if (i == siz)
> + 			buf = realloc(buf, siz += BUFSIZ);
> +-			
> ++
> + 		buf[i] = ch;
> +-		
> ++
> + 		if (buf[i] == '\n') {
> + 			buf[i] = '\0';
> +-			
> +-			if (i > 0 && buf[i-1] == '\r') 
> ++
> ++			if (i > 0 && buf[i-1] == '\r')
> + 				buf[i-1] = '\0';
> +-				
> ++
> + 			return buf;
> + 		}
> + 	}
> +-	
> ++
> + 	if (i > 0) {
> + 		if (i == siz) buf = realloc(buf, siz + 1);
> + 			buf[i] = '\0';
> +-			
> ++
> + 		return buf;
> + 	}
> +-	
> ++
> + 	return NULL;
> + }
> + 
> + /**
> + * Makes a string.
> + * Works like printf(), with the difference
> +-* that it returns a string that is the 
> ++* that it returns a string that is the
> + * concatenation of the values passed as parameter.
> +-* 
> ++*
> + * @param *s Inicial String and optionally formatation parameters ( just %s is allowed )
> + * @return The new String
> + * \code
> +@@ -599,7 +599,7 @@ char *make_string(char *s, ...)
> + 					break;
> + 			}
> + 		}
> +-		
> ++
> + 		str++;
> + 	}
> + 
> +@@ -628,13 +628,13 @@ char *strcat_ex(const char *str1, const char *str2)
> + 	len = strlen(str1) + strlen(str2);
> + 
> + 	new_str = (char *)malloc((len + 1) * sizeof(char*));
> +-	if (!new_str) 
> ++	if (!new_str)
> + 		libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
> + 
> + 	sprintf(new_str, "%s%s", str1, str2);
> + 
> + 	new_str[len] = '\0';
> +-	
> ++
> + 	return new_str;
> + }
> + 
> diff --git a/patches/libcgi-1.0/0012-free-memory-allocated-by-unescape_special_chars-afte.patch b/patches/libcgi-1.0/0012-free-memory-allocated-by-unescape_special_chars-afte.patch
> new file mode 100644
> index 0000000..184601d
> --- /dev/null
> +++ b/patches/libcgi-1.0/0012-free-memory-allocated-by-unescape_special_chars-afte.patch
> @@ -0,0 +1,64 @@
> +From: Alexander Dahl <post@lespocky.de>
> +Date: Wed, 24 Oct 2012 11:31:10 +0200
> +Subject: [PATCH] free memory allocated by unescape_special_chars() after not
> + needed anymore, should fix #3
> +
> +---
> + src/cgi.c    |    6 ++++--
> + src/cookie.c |    7 +++++--
> + 2 files changed, 9 insertions(+), 4 deletions(-)
> +
> +diff --git a/src/cgi.c b/src/cgi.c
> +index e9d76ae..461eba3 100644
> +--- a/src/cgi.c
> ++++ b/src/cgi.c
> +@@ -51,7 +51,7 @@ extern formvars *cookie_end;
> + formvars *process_data(char *query, formvars **start, formvars **last, const char delim, const char sep)
> + {
> + 	register size_t position = 0, total_len = 0, i = 0;
> +-	char *aux;
> ++	char *aux, *str_unesc;
> + 	formvars *data;
> + 
> + 	if (query == NULL)
> +@@ -113,8 +113,10 @@ formvars *process_data(char *query, formvars **start, formvars **last, const cha
> + 		if (data->value == NULL)
> + 			libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__);
> + 
> +-		strncpy(data->value, cgi_unescape_special_chars(query), position);
> ++		str_unesc = cgi_unescape_special_chars(query);
> ++		strncpy(data->value, str_unesc, position);
> + 		data->value[position] = '\0';
> ++		free(str_unesc);
> + 
> + 		slist_add(data, start, last);
> + 
> +diff --git a/src/cookie.c b/src/cookie.c
> +index e9dee9e..6e84c81 100644
> +--- a/src/cookie.c
> ++++ b/src/cookie.c
> +@@ -83,12 +83,13 @@ formvars *cgi_get_cookies()
> + {
> + 	register formvars *data;
> + 	register size_t position;
> +-	char *cookies, *aux;
> ++	char *cookies, *aux, *str_unesc;
> + 
> + 	if ((cookies = getenv("HTTP_COOKIE")) == NULL)
> + 		return NULL;
> + 
> +-	cookies = cgi_unescape_special_chars(cookies);
> ++	str_unesc = cgi_unescape_special_chars(cookies);
> ++	cookies = str_unesc;
> + 	aux = cookies;
> + 
> + 	while (cookies) {
> +@@ -135,6 +136,8 @@ formvars *cgi_get_cookies()
> + 		cookies = aux;
> + 	}
> + 
> ++	free(str_unesc);
> ++
> + 	return cookies_start;
> + }
> + 
> diff --git a/patches/libcgi-1.0/0013-free-memory-allocated-for-reading-and-parsing-POST-d.patch b/patches/libcgi-1.0/0013-free-memory-allocated-for-reading-and-parsing-POST-d.patch
> new file mode 100644
> index 0000000..bf6d1da
> --- /dev/null
> +++ b/patches/libcgi-1.0/0013-free-memory-allocated-for-reading-and-parsing-POST-d.patch
> @@ -0,0 +1,32 @@
> +From: Alexander Dahl <post@lespocky.de>
> +Date: Wed, 24 Oct 2012 12:48:36 +0200
> +Subject: [PATCH] free memory allocated for reading and parsing POST data
> + after copying to slist, should fix #2
> +
> +---
> + src/cgi.c |    5 ++++-
> + 1 file changed, 4 insertions(+), 1 deletion(-)
> +
> +diff --git a/src/cgi.c b/src/cgi.c
> +index 461eba3..99563ad 100644
> +--- a/src/cgi.c
> ++++ b/src/cgi.c
> +@@ -161,6 +161,7 @@ formvars *cgi_process_form()
> + 		char *post_data;
> + 		char *tmp_data;
> + 		int content_length;
> ++		formvars *ret;
> + 
> + 		tmp_data = getenv("CONTENT_LENGTH");
> + 		if (tmp_data == NULL)
> +@@ -175,7 +176,9 @@ formvars *cgi_process_form()
> + 		fread(post_data, content_length, 1, stdin);
> + 		post_data[content_length] = '\0';
> + 
> +-		return process_data(post_data, &formvars_start, &formvars_last, '=', '&');
> ++		ret = process_data(post_data, &formvars_start, &formvars_last, '=', '&');
> ++		free(post_data);
> ++		return ret;
> + 	}
> + 
> + 	return NULL;
> diff --git a/patches/libcgi-1.0/0014-FILE-requires-including-stdio.patch b/patches/libcgi-1.0/0014-FILE-requires-including-stdio.patch
> new file mode 100644
> index 0000000..4588a8f
> --- /dev/null
> +++ b/patches/libcgi-1.0/0014-FILE-requires-including-stdio.patch
> @@ -0,0 +1,21 @@
> +From: Alexander Dahl <post@lespocky.de>
> +Date: Tue, 6 Nov 2012 14:22:58 +0100
> +Subject: [PATCH] FILE requires including stdio
> +
> +---
> + src/cgi.h |    2 ++
> + 1 file changed, 2 insertions(+)
> +
> +diff --git a/src/cgi.h b/src/cgi.h
> +index 731735d..7cd5a17 100644
> +--- a/src/cgi.h
> ++++ b/src/cgi.h
> +@@ -21,6 +21,8 @@
> + #ifndef _CGI_H
> + #define _CGI_H	1
> + 
> ++#include <stdio.h>
> ++
> + #ifdef __cplusplus
> + extern "C" {
> + #endif
> diff --git a/patches/libcgi-1.0/0015-fix-unescape-by-optimizing-hextable-init-and-access.patch b/patches/libcgi-1.0/0015-fix-unescape-by-optimizing-hextable-init-and-access.patch
> new file mode 100644
> index 0000000..f7c1c40
> --- /dev/null
> +++ b/patches/libcgi-1.0/0015-fix-unescape-by-optimizing-hextable-init-and-access.patch
> @@ -0,0 +1,93 @@
> +From: Alexander Dahl <post@lespocky.de>
> +Date: Tue, 18 Mar 2014 11:28:49 +0100
> +Subject: [PATCH] fix unescape by optimizing hextable init and access
> +
> +int size is reduced to 1 byte, table length is truncated to only
> +accessed bytes, and access is limited to only the hex digit characters
> +by replacing isalnum() with isxdigit() in cgi_unescape_special_chars().
> +This actually fixes a bug in decoding if one of the hex digits after the
> +'%' was another character than a to f!
> +---
> + src/cgi.c |   55 ++++++++++++++++++++++++++++---------------------------
> + 1 file changed, 28 insertions(+), 27 deletions(-)
> +
> +diff --git a/src/cgi.c b/src/cgi.c
> +index 99563ad..5d9ffc0 100644
> +--- a/src/cgi.c
> ++++ b/src/cgi.c
> +@@ -27,9 +27,7 @@
> + #include "cgi.h"
> + #include "error.h"
> + 
> +-// Whow... if hextable array has a length less than 256,
> +-// the cgi_unescape_special_chars function will fail.  And I don't know why
> +-static int hextable[256];
> ++static unsigned char hextable['f'+1];
> + 
> + int headers_initialized = 0;
> + 
> +@@ -326,29 +324,32 @@ void cgi_redirect(char *url)
> + // Original idea from cgic library
> + void init_hex_table()
> + {
> +-	memset(hextable, 0, 255);
> +-
> +-	hextable['1'] = 1;
> +-	hextable['2'] = 2;
> +-	hextable['3'] = 3;
> +-	hextable['4'] = 4;
> +-	hextable['5'] = 5;
> +-	hextable['6'] = 6;
> +-	hextable['7'] = 7;
> +-	hextable['8'] = 8;
> +-	hextable['9'] = 9;
> +-	hextable['a'] = 10;
> +-	hextable['b'] = 11;
> +-	hextable['c'] = 12;
> +-	hextable['d'] = 13;
> +-	hextable['e'] = 14;
> +-	hextable['f'] = 15;
> +-	hextable['A'] = 10;
> +-	hextable['B'] = 11;
> +-	hextable['C'] = 12;
> +-	hextable['D'] = 13;
> +-	hextable['E'] = 14;
> +-	hextable['F'] = 15;
> ++	memset(hextable, 0, 'f'+1);
> ++
> ++	hextable['0'] = 0x0;	/* 48 */
> ++	hextable['1'] = 0x1;	/* 49 */
> ++	hextable['2'] = 0x2;	/* 50 */
> ++	hextable['3'] = 0x3;	/* 51 */
> ++	hextable['4'] = 0x4;	/* 52 */
> ++	hextable['5'] = 0x5;	/* 53 */
> ++	hextable['6'] = 0x6;	/* 54 */
> ++	hextable['7'] = 0x7;	/* 55 */
> ++	hextable['8'] = 0x8;	/* 56 */
> ++	hextable['9'] = 0x9;	/* 57 */
> ++
> ++	hextable['A'] = 0xA;	/* 65 */
> ++	hextable['B'] = 0xB;	/* 66 */
> ++	hextable['C'] = 0xC;	/* 67 */
> ++	hextable['D'] = 0xD;	/* 68 */
> ++	hextable['E'] = 0xE;	/* 69 */
> ++	hextable['F'] = 0xF;	/* 70 */
> ++
> ++	hextable['a'] = 0xa;	/* 97 */
> ++	hextable['b'] = 0xb;	/* 98 */
> ++	hextable['c'] = 0xc;	/* 99 */
> ++	hextable['d'] = 0xd;	/* 100 */
> ++	hextable['e'] = 0xe;	/* 101 */
> ++	hextable['f'] = 0xf;	/* 102 */
> + }
> + 
> + /**
> +@@ -411,7 +412,7 @@ char *cgi_unescape_special_chars(char *str)
> + 		// hexa code. Converting a hexadecimal code to their decimal is easy:
> + 		// The first character needs to be multiplied by 16 ( << 4 ), and the another
> + 		// one we just get the value from hextable variable
> +-		if ((str[i] == '%') && isalnum(str[i+1]) && isalnum(str[i+2])) {
> ++		if ((str[i] == '%') && isxdigit(str[i+1]) && isxdigit(str[i+2])) {
> + 			tmp[pos] = (hextable[(unsigned char) str[i+1]] << 4) + hextable[(unsigned char) str[i+2]];
> + 			i += 2;
> + 		}
> diff --git a/patches/libcgi-1.0/series b/patches/libcgi-1.0/series
> index 529f9e1..36b35c3 100644
> --- a/patches/libcgi-1.0/series
> +++ b/patches/libcgi-1.0/series
> @@ -10,4 +10,9 @@
>  0008-use-install-instead-of-cp.patch
>  0009-use-standard-directory-names.patch
>  0010-make-the-library-filename-match-its-soname.patch
> -# 40c8e50df2a8d8dccb4118e5323311d2  - git-ptx-patches magic
> +0011-remove-trailing-whitespace-my-editor-would-do-this-a.patch
> +0012-free-memory-allocated-by-unescape_special_chars-afte.patch
> +0013-free-memory-allocated-for-reading-and-parsing-POST-d.patch
> +0014-FILE-requires-including-stdio.patch
> +0015-fix-unescape-by-optimizing-hextable-init-and-access.patch
> +# a45ad2beb1e5e20d274ad9cc2dba2cd7  - git-ptx-patches magic
> -- 
> 1.7.10.4
> 
> 
> -- 
> ptxdist mailing list
> ptxdist@pengutronix.de

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

-- 
ptxdist mailing list
ptxdist@pengutronix.de

  reply	other threads:[~2014-03-19  9:49 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-19  9:19 Alexander Dahl
2014-03-19  9:49 ` Michael Olbrich [this message]
2014-03-19 10:28   ` Alexander Dahl
2014-03-21 13:35   ` Alexander Dahl
2014-03-24  8:41     ` Michael Olbrich
2014-04-02 14:10       ` [ptxdist] [PATCH] libcgi: " Alexander Dahl
2014-04-04  9:58         ` Michael Olbrich
2014-03-19  9:49 ` [ptxdist] [PATCH] " Alexander Dahl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140319094921.GH5223@pengutronix.de \
    --to=m.olbrich@pengutronix.de \
    --cc=ptxdist@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox