Skip to content

Commit

Permalink
Bluetooth: Host: Fix bt_addr_from_str for str starting with ':'
Browse files Browse the repository at this point in the history
The previous implementation would read from `addr->val[0]` before it was
initialized if the input string started with a colon ':'.

Signed-off-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
  • Loading branch information
alwa-nordic authored and nashif committed Jun 5, 2023
1 parent 75bb62a commit a4e7b53
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 13 deletions.
3 changes: 2 additions & 1 deletion include/zephyr/bluetooth/addr.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ static inline int bt_addr_le_to_str(const bt_addr_le_t *addr, char *str,
* @param[in] str The string representation of a Bluetooth address.
* @param[out] addr Address of buffer to store the Bluetooth address
*
* @return Zero on success or (negative) error code otherwise.
* @retval 0 Success. The parsed address is stored in @p addr.
* @return -EINVAL Invalid address string. @p str is not a well-formed Bluetooth address.
*/
int bt_addr_from_str(const char *str, bt_addr_t *addr);

Expand Down
29 changes: 17 additions & 12 deletions subsys/bluetooth/host/addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,28 +53,33 @@ int bt_addr_le_create_static(bt_addr_le_t *addr)

int bt_addr_from_str(const char *str, bt_addr_t *addr)
{
int i, j;
uint8_t tmp;
/* Parse a null-terminated string with a Bluetooth address in
* canonical "XX:XX:XX:XX:XX:XX" format.
*/

if (strlen(str) != 17U) {
const size_t len = strlen(str);

/* Verify length. */
if (len != BT_ADDR_STR_LEN - 1) {
return -EINVAL;
}

for (i = 5, j = 1; *str != '\0'; str++, j++) {
if (!(j % 3) && (*str != ':')) {
/* Verify that all the colons are present. */
for (size_t i = 2; i < len; i += 3) {
if (str[i] != ':') {
return -EINVAL;
} else if (*str == ':') {
i--;
continue;
}
}

addr->val[i] = addr->val[i] << 4;
/* Parse each octet as hex and populate `addr->val`. It must be
* reversed since `bt_addr_t` is in 'on-air' format.
*/
for (size_t i = 0; i < ARRAY_SIZE(addr->val); i++) {
const size_t reverse_i = ARRAY_SIZE(addr->val) - 1 - i;

if (char2hex(*str, &tmp) < 0) {
if (!hex2bin(&str[i * 3], 2, &addr->val[reverse_i], 1)) {
return -EINVAL;
}

addr->val[i] |= tmp;
}

return 0;
Expand Down

0 comments on commit a4e7b53

Please sign in to comment.