mirror of
https://github.com/osmarks/ngircd.git
synced 2025-03-04 08:28:10 +00:00
Allow mixed line terminations (CR+LF/CR/LF) in non-RFC-compliant mode
Up to now ngIRCd accepted CR+LF as well as a single CR or LF in "non RFC compliant" mode (the default). But ngIRCd became confused when it received data containing mixed line endings (e. g. "111\r222\n333\r\n"). This patch enables ngIRCd (in "non RFC compliant" mode) to detect CR+LF, CR, and LF as equally good line termination sequences and to always end the command after the first one detected. Some clients (for exmaple Trilian) are that ... broken to send such mixed line terminations ... First patch proposed by Scott Perry <scperry@ucsd.edu>, Thanks to Ali Shemiran <ashemira@ucsd.edu> for testing!
This commit is contained in:
parent
8644cbf197
commit
a84f7dcee5
@ -1238,7 +1238,7 @@ static void
|
|||||||
Handle_Buffer(CONN_ID Idx)
|
Handle_Buffer(CONN_ID Idx)
|
||||||
{
|
{
|
||||||
#ifndef STRICT_RFC
|
#ifndef STRICT_RFC
|
||||||
char *ptr1, *ptr2;
|
char *ptr1, *ptr2, *first_eol;
|
||||||
#endif
|
#endif
|
||||||
char *ptr;
|
char *ptr;
|
||||||
size_t len, delta;
|
size_t len, delta;
|
||||||
@ -1280,19 +1280,28 @@ Handle_Buffer(CONN_ID Idx)
|
|||||||
ptr = strstr(array_start(&My_Connections[Idx].rbuf), "\r\n");
|
ptr = strstr(array_start(&My_Connections[Idx].rbuf), "\r\n");
|
||||||
|
|
||||||
#ifndef STRICT_RFC
|
#ifndef STRICT_RFC
|
||||||
if (!ptr) {
|
/* Check for non-RFC-compliant request (only CR or LF)?
|
||||||
/* Check for non-RFC-compliant request (only CR or
|
* Unfortunately, there are quite a few clients out there
|
||||||
* LF)? Unfortunately, there are quite a few clients
|
* that do this -- e. g. mIRC, BitchX, and Trillian :-( */
|
||||||
* out there that do this -- incl. "mIRC" :-( */
|
|
||||||
delta = 1;
|
|
||||||
ptr1 = strchr(array_start(&My_Connections[Idx].rbuf), '\r');
|
ptr1 = strchr(array_start(&My_Connections[Idx].rbuf), '\r');
|
||||||
ptr2 = strchr(array_start(&My_Connections[Idx].rbuf), '\n');
|
ptr2 = strchr(array_start(&My_Connections[Idx].rbuf), '\n');
|
||||||
|
if (ptr) {
|
||||||
|
/* Check if there is a single CR or LF _before_ the
|
||||||
|
* corerct CR+LF line terminator: */
|
||||||
|
first_eol = ptr1 < ptr2 ? ptr1 : ptr2;
|
||||||
|
if (first_eol < ptr) {
|
||||||
|
/* Single CR or LF before CR+LF found */
|
||||||
|
ptr = first_eol;
|
||||||
|
delta = 1;
|
||||||
|
}
|
||||||
|
} else if (ptr1 || ptr2) {
|
||||||
|
/* No CR+LF terminated command found, but single
|
||||||
|
* CR or LF found ... */
|
||||||
if (ptr1 && ptr2)
|
if (ptr1 && ptr2)
|
||||||
ptr = ptr1 > ptr2 ? ptr2 : ptr1;
|
ptr = ptr1 < ptr2 ? ptr1 : ptr2;
|
||||||
else if (ptr1)
|
else
|
||||||
ptr = ptr1;
|
ptr = ptr1 ? ptr1 : ptr2;
|
||||||
else if (ptr2)
|
delta = 1;
|
||||||
ptr = ptr2;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -340,12 +340,20 @@ Validate_Command( UNUSED CONN_ID Idx, UNUSED REQUEST *Req, bool *Closed )
|
|||||||
static bool
|
static bool
|
||||||
Validate_Args(CONN_ID Idx, REQUEST *Req, bool *Closed)
|
Validate_Args(CONN_ID Idx, REQUEST *Req, bool *Closed)
|
||||||
{
|
{
|
||||||
|
#ifdef STRICT_RFC
|
||||||
int i;
|
int i;
|
||||||
|
#endif
|
||||||
|
|
||||||
assert( Idx >= 0 );
|
assert( Idx >= 0 );
|
||||||
assert( Req != NULL );
|
assert( Req != NULL );
|
||||||
*Closed = false;
|
*Closed = false;
|
||||||
|
|
||||||
|
#ifdef STRICT_RFC
|
||||||
|
/* CR and LF are never allowed in command parameters.
|
||||||
|
* But since we do accept lines terminated only with CR or LF in
|
||||||
|
* "non-RFC-compliant mode" (besides the correct CR+LF combination),
|
||||||
|
* this check can only trigger in "strict RFC" mode; therefore we
|
||||||
|
* optimize it away otherwise ... */
|
||||||
for (i = 0; i < Req->argc; i++) {
|
for (i = 0; i < Req->argc; i++) {
|
||||||
if (strchr(Req->argv[i], '\r') || strchr(Req->argv[i], '\n')) {
|
if (strchr(Req->argv[i], '\r') || strchr(Req->argv[i], '\n')) {
|
||||||
Log(LOG_ERR,
|
Log(LOG_ERR,
|
||||||
@ -357,6 +365,8 @@ Validate_Args(CONN_ID Idx, REQUEST *Req, bool *Closed)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} /* Validate_Args */
|
} /* Validate_Args */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user