diff options
| -rw-r--r-- | irc.c | 54 | ||||
| -rw-r--r-- | tests/check_irc.c | 4 | 
2 files changed, 28 insertions, 30 deletions
| @@ -296,9 +296,8 @@ void irc_process( irc_t *irc )  		{  			char conv[IRC_MAX_LINE+1]; -			/* [WvG] Because irc_tokenize splits at every newline, the lines[] list -			    should end with an empty string. This is why this actually works. -			    Took me a while to figure out, Maurits. :-P */ +			/* [WvG] If the last line isn't empty, it's an incomplete line and we +			   should wait for the rest to come in before processing it. */  			if( lines[i+1] == NULL )  			{  				temp = g_strdup( lines[i] ); @@ -368,42 +367,41 @@ void irc_process( irc_t *irc )     contains an incomplete line at the end, ends with an empty string. */  char **irc_tokenize( char *buffer )  { -	int i, j; +	int i, j, n = 3;  	char **lines; -	/* Count the number of elements we're gonna need. */ -	for( i = 0, j = 1; buffer[i] != '\0'; i ++ ) -	{ -		if( buffer[i] == '\n' ) -			if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) -				j ++; -	} -	 -	/* Allocate j+1 elements. */ -	lines = g_new( char *, j + 1 ); -	 -	/* NULL terminate our list. */  -	lines[j] = NULL; +	/* Allocate n+1 elements. */ +	lines = g_new( char *, n + 1 );  	lines[0] = buffer; -	/* Split the buffer in several strings, using \r\n as our seperator, where \r is optional. -	 * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too.  -	 */ -	for( i = 0, j = 0; buffer[i] != '\0'; i ++) +	/* Split the buffer in several strings, and accept any kind of line endings, +	 * knowing that ERC on Windows may send something interesting like \r\r\n, +	 * and surely there must be clients that think just \n is enough... */ +	for( i = 0, j = 0; buffer[i] != '\0'; i ++ )  	{ -		if( buffer[i] == '\n' ) +		if( buffer[i] == '\r' || buffer[i] == '\n' )  		{ -			buffer[i] = '\0'; +			while( buffer[i] == '\r' || buffer[i] == '\n' ) +				buffer[i++] = '\0'; -			if( i > 0 && buffer[i-1] == '\r' ) -				buffer[i-1] = '\0'; -			if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) -				lines[++j] = buffer + i + 1; +			lines[++j] = buffer + i; +			 +			if( j >= n ) +			{ +				n *= 2; +				lines = g_renew( char *, lines, n + 1 ); +			} + +			if( buffer[i] == '\0' ) +				break;  		}  	} -	return( lines ); +	/* NULL terminate our list. */  +	lines[++j] = NULL; +	 +	return lines;  }  /* Split an IRC-style line into little parts/arguments. */ diff --git a/tests/check_irc.c b/tests/check_irc.c index c1cf05a5..66fe0021 100644 --- a/tests/check_irc.c +++ b/tests/check_irc.c @@ -36,8 +36,8 @@ START_TEST(test_login)  	irc = irc_new(g_io_channel_unix_get_fd(ch1)); -	fail_unless(g_io_channel_write_chars(ch2, "NICK bla\r\n" -			"USER a a a a\r\n", -1, NULL, NULL) == G_IO_STATUS_NORMAL); +	fail_unless(g_io_channel_write_chars(ch2, "NICK bla\r\r\n" +			"USER a a a a\n", -1, NULL, NULL) == G_IO_STATUS_NORMAL);  	fail_unless(g_io_channel_flush(ch2, NULL) == G_IO_STATUS_NORMAL);  	g_main_iteration(FALSE); | 
