Merge pull request #464 from DrDoof/fix/json-escape

httpd: don't let a quote in a port name break the web page
This commit is contained in:
René van Dorst authored and GitHub committed 2026-09-18 18:40:16 +00:00
commit eaebeba528
3 files changed
+40 -17

No files matched your search

+11 -5
View File
@@ -434,6 +434,14 @@ static void cmd_error(__code const char *msg)
} }
static uint8_t name_char(uint8_t c)
{
if (c < 0x20 || c > 0x7e || c == '"' || c == '\\')
return '.';
return c;
}
// Sets the management MAC from a "mac <aa:bb:cc:dd:ee:ff>" command (or prints // Sets the management MAC from a "mac <aa:bb:cc:dd:ee:ff>" command (or prints
// the current one with a bare "mac"). Refuses blank/multicast/locally // the current one with a bare "mac"). Refuses blank/multicast/locally
// administered/all-zero-OUI addresses so the running MAC stays reachable, and // administered/all-zero-OUI addresses so the running MAC stays reachable, and
@@ -627,7 +635,7 @@ void parse_vlan(void)
*vlan_str++ = hex[(vlan_settings.vlan >> 4) & 0xf] ; *vlan_str++ = hex[(vlan_settings.vlan >> 4) & 0xf] ;
*vlan_str++ = hex[vlan_settings.vlan & 0xf]; *vlan_str++ = hex[vlan_settings.vlan & 0xf];
while(!cmd_is_space_or_nul(pos)) { while(!cmd_is_space_or_nul(pos)) {
uint8_t c = cmd_buffer[pos++]; uint8_t c = name_char(cmd_buffer[pos++]);
write_char(c); write_char(c);
*vlan_str++ = c; *vlan_str++ = c;
} }
@@ -889,7 +897,7 @@ void parse_port(void)
} else if (cmd_compare(2, "name")) { } else if (cmd_compare(2, "name")) {
uint8_t i = 0; uint8_t i = 0;
while ( (i < PORT_NAME_SIZE-1) && (cmd_buffer[cmd_words_b[3] + i] != NUL) ) { while ( (i < PORT_NAME_SIZE-1) && (cmd_buffer[cmd_words_b[3] + i] != NUL) ) {
port_names[phy_settings.port][i] = cmd_buffer[cmd_words_b[3] + i]; port_names[phy_settings.port][i] = name_char(cmd_buffer[cmd_words_b[3] + i]);
i++; i++;
} }
port_names[phy_settings.port][i] = NUL; port_names[phy_settings.port][i] = NUL;
@@ -1831,9 +1839,7 @@ void cmd_parser(void) __banked
uint8_t c = *hp++; uint8_t c = *hp++;
if (c == NUL || c == '\r' || c == '\n') if (c == NUL || c == '\r' || c == '\n')
break; break;
if (c < 0x20 || c > 0x7e || c == '"' || c == '\\') *dst++ = name_char(c);
c = '.';
*dst++ = c;
} }
*dst = NUL; *dst = NUL;
} else { } else {
+23 -11
View File
@@ -70,6 +70,21 @@ void char_to_html(char c)
} }
static void str_x_to_html(__xdata const char *s)
{
while (*s)
outbuf[slen++] = *s++;
}
void json_char_to_html(uint8_t c)
{
if (c < 0x20 || c > 0x7e || c == '"' || c == '\\')
c = '.';
outbuf[slen++] = c;
}
// Convert uint8_t to ascii HEX char. // Convert uint8_t to ascii HEX char.
void byte_to_html(uint8_t val) void byte_to_html(uint8_t val)
{ {
@@ -198,8 +213,8 @@ void send_sfp_info(uint8_t sfp)
if (i < 20 || i >= 60 || (i >= 36 && i < 40)) // Skip Non-ASCII codes if (i < 20 || i >= 60 || (i >= 36 && i < 40)) // Skip Non-ASCII codes
continue; continue;
uint8_t c = sfp_buf[i & 0xf]; uint8_t c = sfp_buf[i & 0xf];
if (c && c != 0xa0) // a0 is the byte read from a non-existant I2C EEPROM if (c)
char_to_html(c); json_char_to_html(c);
} }
} }
@@ -293,7 +308,7 @@ void send_vlan(uint16_t vlan)
dbg_string("VLAN has no name\n"); dbg_string("VLAN has no name\n");
} else { } else {
while(vlan_names[n] && vlan_names[n] != ' ') while(vlan_names[n] && vlan_names[n] != ' ')
char_to_html(vlan_names[n++]); json_char_to_html(vlan_names[n++]);
} }
slen += strtox(outbuf + slen, "\",\"pvid\":\"0x"); slen += strtox(outbuf + slen, "\",\"pvid\":\"0x");
uint16_t pvid_mask = 0; uint16_t pvid_mask = 0;
@@ -825,7 +840,7 @@ void send_status(void)
itoa_html(i); itoa_html(i);
slen += strtox(outbuf + slen, ",\"name\":\""); slen += strtox(outbuf + slen, ",\"name\":\"");
for (uint8_t j = 0; j < PORT_NAME_SIZE && port_names[i][j]; j++) { for (uint8_t j = 0; j < PORT_NAME_SIZE && port_names[i][j]; j++) {
char_to_html(port_names[i][j]); json_char_to_html(port_names[i][j]);
} }
slen += strtox(outbuf + slen, "\""); slen += strtox(outbuf + slen, "\"");
@@ -864,14 +879,11 @@ void send_status(void)
sfp_send_data(sfp, 238, 1); sfp_send_data(sfp, 238, 1);
} }
slen += strtox(outbuf + slen,"\",\"sfp_vendor\":\""); slen += strtox(outbuf + slen,"\",\"sfp_vendor\":\"");
for (uint8_t s = 0; s < 16 && sfp_module_vendor[sfp][s]; s++) str_x_to_html(sfp_module_vendor[sfp]);
outbuf[slen++] = sfp_module_vendor[sfp][s];
slen += strtox(outbuf + slen,"\",\"sfp_model\":\""); slen += strtox(outbuf + slen,"\",\"sfp_model\":\"");
for (uint8_t s = 0; s < 16 && sfp_module_model[sfp][s]; s++) str_x_to_html(sfp_module_model[sfp]);
outbuf[slen++] = sfp_module_model[sfp][s];
slen += strtox(outbuf + slen,"\",\"sfp_serial\":\""); slen += strtox(outbuf + slen,"\",\"sfp_serial\":\"");
for (uint8_t s = 0; s < 16 && sfp_module_serial[sfp][s]; s++) str_x_to_html(sfp_module_serial[sfp]);
outbuf[slen++] = sfp_module_serial[sfp][s];
slen += strtox(outbuf + slen,"\",\"sfp_los\":"); slen += strtox(outbuf + slen,"\",\"sfp_los\":");
if (machine.sfp_port[sfp].pin_los == GPIO_NA) { if (machine.sfp_port[sfp].pin_los == GPIO_NA) {
slen += strtox(outbuf + slen,"null"); slen += strtox(outbuf + slen,"null");
@@ -1043,7 +1055,7 @@ void send_vlanlist(void)
n = vlan_name(i); n = vlan_name(i);
if (n != 0xffff) { if (n != 0xffff) {
while (vlan_names[n] && vlan_names[n] != ' ') while (vlan_names[n] && vlan_names[n] != ' ')
char_to_html(vlan_names[n++]); json_char_to_html(vlan_names[n++]);
} }
slen += strtox(outbuf + slen, "\"}"); slen += strtox(outbuf + slen, "\"}");
+6 -1
View File
@@ -88,7 +88,12 @@ bool sfp_read_field(__xdata char *dst, uint8_t sfp, uint8_t start, uint8_t lengt
return false; return false;
dst[length] = NUL; dst[length] = NUL;
memcpy(dst, sfp_buf, length); for (uint8_t i = 0; i < length; i++) {
uint8_t c = sfp_buf[i];
if (c && (c < 0x20 || c > 0x7e || c == '"' || c == '\\'))
c = '.';
dst[i] = c;
}
while (length > 0 && dst[--length] == ' ') while (length > 0 && dst[--length] == ' ')
dst[length] = NUL; dst[length] = NUL;