Skip to content
This repository was archived by the owner on Nov 27, 2024. It is now read-only.

Commit fb21d99

Browse files
author
Sean Middleditch
authored
Merge pull request #37 from charlesUnixPro/master
Fix telnet->q allocator to function as documented.
2 parents 153ee61 + 299c45a commit fb21d99

File tree

1 file changed

+30
-15
lines changed

1 file changed

+30
-15
lines changed

libtelnet.c

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ struct telnet_t {
103103
/* current subnegotiation telopt */
104104
unsigned char sb_telopt;
105105
/* length of RFC1143 queue */
106-
unsigned char q_size;
106+
unsigned int q_size;
107+
/* number of entries in RFC1143 queue */
108+
unsigned int q_cnt;
107109
};
108110

109111
/* RFC1143 option negotiation state */
@@ -129,6 +131,9 @@ static const size_t _buffer_sizes[] = { 0, 512, 2048, 8192, 16384, };
129131
static const size_t _buffer_sizes_count = sizeof(_buffer_sizes) /
130132
sizeof(_buffer_sizes[0]);
131133

134+
/* RFC1143 option negotiation state table allocation quantum */
135+
#define Q_BUFFER_GROWTH_QUANTUM 4
136+
132137
/* error generation function */
133138
static telnet_error_t _error(telnet_t *telnet, unsigned line,
134139
const char* func, telnet_error_t err, int fatal, const char *fmt,
@@ -262,7 +267,7 @@ static INLINE int _check_telopt(telnet_t *telnet, unsigned char telopt,
262267
if (telnet->telopts == 0)
263268
return 0;
264269

265-
/* loop unti found or end marker (us and him both 0) */
270+
/* loop until found or end marker (us and him both 0) */
266271
for (i = 0; telnet->telopts[i].telopt != -1; ++i) {
267272
if (telnet->telopts[i].telopt == telopt) {
268273
if (us && telnet->telopts[i].us == TELNET_WILL)
@@ -285,7 +290,7 @@ static INLINE telnet_rfc1143_t _get_rfc1143(telnet_t *telnet,
285290
int i;
286291

287292
/* search for entry */
288-
for (i = 0; i != telnet->q_size; ++i) {
293+
for (i = 0; i != telnet->q_cnt; ++i) {
289294
if (telnet->q[i].telopt == telopt) {
290295
return telnet->q[i];
291296
}
@@ -304,7 +309,7 @@ static INLINE void _set_rfc1143(telnet_t *telnet, unsigned char telopt,
304309
int i;
305310

306311
/* search for entry */
307-
for (i = 0; i != telnet->q_size; ++i) {
312+
for (i = 0; i != telnet->q_cnt; ++i) {
308313
if (telnet->q[i].telopt == telopt) {
309314
telnet->q[i].state = Q_MAKE(us,him);
310315
if (telopt != TELNET_TELOPT_BINARY)
@@ -325,17 +330,26 @@ static INLINE void _set_rfc1143(telnet_t *telnet, unsigned char telopt,
325330
* to the number of enabled options for most simple code, and it
326331
* allows for an acceptable number of reallocations for complex code.
327332
*/
328-
if ((qtmp = (telnet_rfc1143_t *)realloc(telnet->q,
329-
sizeof(telnet_rfc1143_t) * (telnet->q_size + 4))) == 0) {
330-
_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
331-
"realloc() failed: %s", strerror(errno));
332-
return;
333+
334+
/* Did we reach the end of the table? */
335+
if (telnet->q_cnt >= telnet->q_size) {
336+
/* Expand the size */
337+
if ((qtmp = (telnet_rfc1143_t *)realloc(telnet->q,
338+
sizeof(telnet_rfc1143_t) *
339+
(telnet->q_size + Q_BUFFER_GROWTH_QUANTUM))) == 0) {
340+
_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
341+
"realloc() failed: %s", strerror(errno));
342+
return;
343+
}
344+
memset(&qtmp[telnet->q_size], 0, sizeof(telnet_rfc1143_t) *
345+
Q_BUFFER_GROWTH_QUANTUM);
346+
telnet->q = qtmp;
347+
telnet->q_size += Q_BUFFER_GROWTH_QUANTUM;
333348
}
334-
memset(&qtmp[telnet->q_size], 0, sizeof(telnet_rfc1143_t) * 4);
335-
telnet->q = qtmp;
336-
telnet->q[telnet->q_size].telopt = telopt;
337-
telnet->q[telnet->q_size].state = Q_MAKE(us, him);
338-
telnet->q_size += 4;
349+
/* Add entry to end of table */
350+
telnet->q[telnet->q_cnt].telopt = telopt;
351+
telnet->q[telnet->q_cnt].state = Q_MAKE(us, him);
352+
++telnet->q_cnt;
339353
}
340354

341355
/* send negotiation bytes */
@@ -909,8 +923,9 @@ void telnet_free(telnet_t *telnet) {
909923
/* free RFC1143 queue */
910924
if (telnet->q) {
911925
free(telnet->q);
912-
telnet->q = 0;
926+
telnet->q = NULL;
913927
telnet->q_size = 0;
928+
telnet->q_cnt = 0;
914929
}
915930

916931
/* free the telnet structure itself */

0 commit comments

Comments
 (0)