syslog: parse the port with atoi_short()

The hand rolled loop was here because atoi_short() reported "no digits"
but not overflow, so 65540 would have wrapped to 4 and opened a
connection to a port nobody asked for. #326 gave it the same bound this
loop was carrying, so the reason is gone.

Zero still covers all three ways to be wrong, except that "no digits"
and overflow now come back as a zero return and port zero as a zero
value, so both are tested.

Three xdata scratch variables go with the loop.
This commit is contained in:
d00f committed 2026-08-30 22:38:31 +02:00
1 parent 4db1ccbbd9
commit e50d3c6950
1 file changed
+6 -28
+6 -28
View File
@@ -65,11 +65,8 @@ __xdata char save_cmd;
__xdata uint8_t ip[4];
/* Scratch for parse_syslog()'s port parser, in xdata: locals here would take
* internal RAM the linker has none of. */
__xdata uint16_t syslog_port_scratch;
__xdata uint8_t syslog_port_idx;
__xdata uint8_t syslog_port_digit;
/* Scratch for parse_syslog(), in xdata: a local here would take internal RAM
* the linker has none of. */
__xdata uint8_t syslog_port_was_on;
// These variables combined create a Fixed-capacity vector/bounded buffer.
@@ -1453,28 +1450,9 @@ void parse_syslog(void)
itoa_short(syslog_state.server_port); write_char('\n');
return;
}
/* Parsed here rather than with atoi_short(), which reports "no
* digits" but not overflow - 65540 would quietly wrap to 4 and we
* would open a connection to a port nobody asked for. Checking
* before each multiply keeps this in 16-bit arithmetic. */
syslog_port_scratch = 0;
syslog_port_idx = cmd_words_b[2];
for (;;) {
syslog_port_digit = cmd_buffer[syslog_port_idx];
if (syslog_port_digit < '0' || syslog_port_digit > '9')
break;
syslog_port_digit -= '0';
if (syslog_port_scratch > 6553
|| (syslog_port_scratch == 6553 && syslog_port_digit > 5)) {
syslog_port_scratch = 0; /* too large - reject below */
break;
}
syslog_port_scratch = syslog_port_scratch * 10 + syslog_port_digit;
syslog_port_idx++;
}
/* Zero covers all three ways to be wrong: no digits at all, a value
* past 65535, and an explicit "0", which is not a port either. */
if (!syslog_port_scratch) {
/* atoi_short() returns zero for no digits and for a value past
* 65535; port zero is not a port either, so both tests are needed. */
if (!atoi_short(cmd_words_b[2]) || !atoi_results_short) {
print_string("Invalid port\n");
return;
}
@@ -1485,7 +1463,7 @@ void parse_syslog(void)
if (syslog_port_was_on)
syslog_stop();
print_string("Setting new syslog port.\n");
syslog_state.server_port = syslog_port_scratch;
syslog_state.server_port = atoi_results_short;
if (syslog_port_was_on)
syslog_start();
}