mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
fix(parser): reject malformed MAC inputs and make print helpers banked
parse_mac now accepts only a strict aa:bb:cc:dd:ee:ff (or '-' separators) form: each octet is exactly two hex digits, the 5 separators are a single consistent character, and nothing is allowed after the 6th octet. This rejects the malformed values the reviewer flagged (repeated separators, missing digits, trailing characters). A new inline hexval() helper does the digit-to-value conversion and can be reused by future commands. print_mac and print_ip are marked __banked to match cmd_parser(), which lives in codeseg BANK2 and is itself __banked, so callers across the code bank work correctly. cmd_parser.h is updated with the new prototypes and the __banked qualifier on print_ip. Verified with make MACHINE=KP_9000_9XHML_X_V3_1: the build links cleanly and the internal-RAM (DSEG) layout is unchanged against main; XSEG is unchanged and ROM grows by 184 bytes. A host-side test confirms parse_mac rejects the two malformed inputs from the review.
This commit is contained in:
1 parent
6616a0c9ce
commit
dc4fb5becc
2 files changed
+45
-25
No files matched your search
+42
-24
@@ -106,6 +106,18 @@ inline uint8_t isnumber(uint8_t l)
|
||||
return (l <= ('9'-'0'));
|
||||
}
|
||||
|
||||
/* Converts a single ASCII hex digit to its value, or 0xff if it is not a valid
|
||||
* hex digit. Accepts '0'-'9', 'a'-'f' and 'A'-'F'. */
|
||||
inline uint8_t hexval(uint8_t c)
|
||||
{
|
||||
if (isnumber(c))
|
||||
return c - '0';
|
||||
c |= 0x20;
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
uint8_t cmd_compare(uint8_t start, __code uint8_t * cmd)
|
||||
{
|
||||
@@ -349,7 +361,7 @@ err:
|
||||
}
|
||||
|
||||
// Prints an IPv4 address.
|
||||
void print_ip(__xdata uint8_t * ptr)
|
||||
void print_ip(__xdata uint8_t * ptr) __banked
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
uint8_t num;
|
||||
@@ -365,7 +377,7 @@ void print_ip(__xdata uint8_t * ptr)
|
||||
}
|
||||
|
||||
// Prints a MAC address.
|
||||
void print_mac(__xdata uint8_t *ptr)
|
||||
void print_mac(__xdata uint8_t *ptr) __banked
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
uint8_t num;
|
||||
@@ -380,38 +392,44 @@ void print_mac(__xdata uint8_t *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
// Parses a MAC address (12 hex digits, ':' or '-' separators optional) from
|
||||
// cmd_buffer starting at idx into mac[6]. Returns the number of bytes
|
||||
// consumed, or 0 on error.
|
||||
// Parses a strict MAC address "aa:bb:cc:dd:ee:ff" (or "-" separators) from
|
||||
// cmd_buffer starting at idx into mac[6]. Each of the 6 octets must be exactly
|
||||
// two hex digits and the 5 separators must be the same single character, so
|
||||
// malformed input like repeated separators ("aa::bb"), missing digits or a
|
||||
// trailing hex digit ("aa:bb:cc:dd:ee:ff:0") is rejected. Returns the number of
|
||||
// bytes consumed, or 0 on error.
|
||||
uint8_t parse_mac(uint8_t idx, __xdata uint8_t *mac)
|
||||
{
|
||||
uint8_t sep = 0;
|
||||
uint8_t b = 0;
|
||||
uint8_t hi = 0xff; /* 0xff = waiting for the high nibble */
|
||||
uint8_t c;
|
||||
uint8_t hi;
|
||||
uint8_t lo;
|
||||
|
||||
while (b < 6) {
|
||||
hi = hexval(cmd_buffer[idx++]);
|
||||
lo = hexval(cmd_buffer[idx++]);
|
||||
if (hi == 0xff || lo == 0xff)
|
||||
return 0;
|
||||
mac[b++] = (hi << 4) | lo;
|
||||
|
||||
if (b == 6)
|
||||
break;
|
||||
c = cmd_buffer[idx];
|
||||
if (c == NUL || c == ' ' || c == '\r' || c == '\n')
|
||||
break;
|
||||
if (c != ':' && c != '-')
|
||||
return 0;
|
||||
if (sep == 0)
|
||||
sep = c;
|
||||
else if (c != sep)
|
||||
return 0;
|
||||
idx++;
|
||||
if (c == ':' || c == '-')
|
||||
continue;
|
||||
c |= 0x20;
|
||||
if (c >= '0' && c <= '9')
|
||||
c -= '0';
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
c -= 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (hi == 0xff) {
|
||||
hi = c;
|
||||
} else {
|
||||
mac[b++] = (hi << 4) | c;
|
||||
hi = 0xff;
|
||||
}
|
||||
}
|
||||
if (b != 6 || hi != 0xff)
|
||||
|
||||
// No trailing characters: the next byte must be a separator-like EOF.
|
||||
c = cmd_buffer[idx];
|
||||
if (c != NUL && c != ' ')
|
||||
return 0;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user