Skip to content
Snippets Groups Projects
Commit dde30738 authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

Move telnet_expand() into SyncTERM proper.

This allows ensuring we don't expand CRLF into CRLFLF.  This is
usually harmless, but there's no real need to put up with it in
a program with a single thread using the expand function.
parent 19cfb320
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,7 @@
/* $Id: conn_telnet.c,v 1.18 2020/05/03 20:12:42 deuce Exp $ */
#include <stdbool.h>
#include <stdlib.h>
#include "gen_defs.h"
......@@ -19,6 +20,65 @@
extern int telnet_log_level;
/*****************************************************************************/
// Escapes Telnet IACs in 'inbuf' by doubling the IAC char
// 'result' may point to either inbuf (if there were no IACs) or outbuf
// Returns the final byte count of the result
/*****************************************************************************/
size_t st_telnet_expand(const uchar* inbuf, size_t inlen, uchar* outbuf, size_t outlen, BOOL expand_cr, uchar** result)
{
static bool last_was_lf = false;
BYTE* first_iac = (BYTE*)memchr(inbuf, TELNET_IAC, inlen);
BYTE* first_cr=NULL;
if (inlen == 0) {
if (result != NULL)
*result = (uchar *)inbuf;
return 0;
}
if (last_was_lf && inbuf[0] == '\n') {
inbuf++;
inlen--;
}
last_was_lf = false;
if (expand_cr)
first_cr = (BYTE*)memchr(inbuf, '\r', inlen);
else
last_was_lf = false;
if (first_iac == NULL && first_cr == NULL) { /* Nothing to expand */
if (result != NULL)
*result = (uchar*)inbuf;
return inlen;
}
size_t o;
if(first_iac != NULL && (first_cr == NULL || first_iac < first_cr))
o = first_iac - inbuf;
else
o = first_cr - inbuf;
memcpy(outbuf, inbuf, o);
for (size_t i = o; i < inlen && o < outlen; i++) {
if (inbuf[i] == '\n' && last_was_lf)
continue;
last_was_lf = false;
if(inbuf[i] == TELNET_IAC)
outbuf[o++] = TELNET_IAC;
if(o >= outlen)
break;
outbuf[o++] = inbuf[i];
if(expand_cr && inbuf[i] == '\r' && o < outlen) {
last_was_lf = true;
outbuf[o++] = '\n'; // See RFC5198
}
}
if(result != NULL)
*result = outbuf;
return o;
}
void *telnet_rx_parse_cb(const void *buf, size_t inlen, size_t *olen)
{
// telnet_interpret() can add up to one byte to inbuf ('\r')
......@@ -36,7 +96,7 @@ void *telnet_tx_parse_cb(const void *buf, size_t len, size_t *olen)
void *ret = malloc(len * 2);
void *parsed;
*olen = telnet_expand(buf, len, ret, len * 2
*olen = st_telnet_expand(buf, len, ret, len * 2
,telnet_local_option[TELNET_BINARY_TX]!=TELNET_DO, (BYTE **)&parsed);
if (parsed != ret)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment