diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index decfeb68..2e23ade8 100644 --- a/src/ngircd/conn.c +++ b/src/ngircd/conn.c @@ -1238,7 +1238,7 @@ static void Handle_Buffer(CONN_ID Idx) { #ifndef STRICT_RFC - char *ptr1, *ptr2; + char *ptr1, *ptr2, *first_eol; #endif char *ptr; size_t len, delta; @@ -1280,19 +1280,28 @@ Handle_Buffer(CONN_ID Idx) ptr = strstr(array_start(&My_Connections[Idx].rbuf), "\r\n"); #ifndef STRICT_RFC - if (!ptr) { - /* Check for non-RFC-compliant request (only CR or - * LF)? Unfortunately, there are quite a few clients - * out there that do this -- incl. "mIRC" :-( */ - delta = 1; - ptr1 = strchr(array_start(&My_Connections[Idx].rbuf), '\r'); - ptr2 = strchr(array_start(&My_Connections[Idx].rbuf), '\n'); + /* Check for non-RFC-compliant request (only CR or LF)? + * Unfortunately, there are quite a few clients out there + * that do this -- e. g. mIRC, BitchX, and Trillian :-( */ + ptr1 = strchr(array_start(&My_Connections[Idx].rbuf), '\r'); + 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) - ptr = ptr1 > ptr2 ? ptr2 : ptr1; - else if (ptr1) - ptr = ptr1; - else if (ptr2) - ptr = ptr2; + ptr = ptr1 < ptr2 ? ptr1 : ptr2; + else + ptr = ptr1 ? ptr1 : ptr2; + delta = 1; } #endif diff --git a/src/ngircd/parse.c b/src/ngircd/parse.c index 00ae3cd7..24de2bc8 100644 --- a/src/ngircd/parse.c +++ b/src/ngircd/parse.c @@ -340,12 +340,20 @@ Validate_Command( UNUSED CONN_ID Idx, UNUSED REQUEST *Req, bool *Closed ) static bool Validate_Args(CONN_ID Idx, REQUEST *Req, bool *Closed) { +#ifdef STRICT_RFC int i; +#endif assert( Idx >= 0 ); assert( Req != NULL ); *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++) { if (strchr(Req->argv[i], '\r') || strchr(Req->argv[i], '\n')) { Log(LOG_ERR, @@ -357,6 +365,8 @@ Validate_Args(CONN_ID Idx, REQUEST *Req, bool *Closed) return false; } } +#endif + return true; } /* Validate_Args */