Skip to content

BSSID entered with ':' or '-' separators is silently parsed wrong (pinning never matches) #5797

Description

@TheRealZam

What happened?

A BSSID entered in WiFi Setup → BSSID (optional) with the usual : or -
separators is silently parsed into a wrong value. No error is shown, the field
appears accepted, and the effect is that BSSID pinning simply never matches —
findWiFi() falls back to picking by RSSI as though nothing had been set.

fillStr2MAC() (wled00/network.cpp:339) parses the field with
strtoull(str, nullptr, 16), which stops at the first non-hex character:

void fillStr2MAC(uint8_t *mac, const char *str) {
  for (int i = 0; i < 6; i++) *mac++ = 0;
  if (!str) return;
  uint64_t MAC = strtoull(str, nullptr, 16);
  for (int i = 0; i < 6; i++) { *--mac = MAC & 0xFF; MAC >>= 8; }
}

The input is maxlength="12" (settings_wifi.htm:136), so a colon-separated
MAC is also truncated to 12 characters before it ever reaches the parser. The
two combine: 9E:2A:6F:44:27:7A becomes the field value 9E:2A:6F:44:, which
parses as 0x9E, and is stored as 00:00:00:00:00:9E.

Compiling fillStr2MAC() unmodified and feeding it what the form would submit:

target BSSID 9E:2A:6F:44:27:7A

  typed with colons      -> field 9E:2A:6F:44:  -> 00:00:00:00:00:9E
  typed with dashes      -> field 9E-2A-6F-44-  -> 00:00:00:00:00:9E
  lowercase, colons      -> field 9e:2a:6f:44:  -> 00:00:00:00:00:9E
  no separators (ok)     -> field 9E2A6F44277A  -> 9E:2A:6F:44:27:7A

Only the bare-hex form works, and nothing on the page says so — the label is
just "BSSID (optional):", with no placeholder, no pattern, and no hint that
separators are disallowed. Every other place a MAC is shown to the user
(including the network scanner in the same dialog) displays it with colons.

This affects both entry paths, neither of which strips separators:

  • the settings form — wled00/set.cpp:54
  • POST /json/cfgwled00/cfg.cpp:108

To Reproduce Bug

  1. WiFi Setup → enter a valid SSID.
  2. In BSSID (optional) type a real BSSID the normal way, e.g.
    9E:2A:6F:44:27:7A. Note the field stops accepting input after 12
    characters, leaving 9E:2A:6F:44:.
  3. Save.
  4. Read it back with GET /json/cfgnw.ins[0].bssid is "9e2a6f44"-ish
    rather than what was intended, and the pin has no effect on AP selection.

Expected Behavior

Either of:

  • Accept the separated form. Stripping : and - before parsing would make
    the field behave the way the displayed MACs elsewhere in the UI lead you to
    expect; or
  • Reject it visibly — a pattern/validation message, so a wrong value cannot
    be saved silently.

Ideally also a placeholder="9E2A6F44277A" on the input, since the required
format is currently undiscoverable.

Worth noting: settings_wifi.htm:72 already contains
networks[i].bssid.replaceAll(':','') in a commented-out fragment of the
scanner's option text, so the need to strip separators was anticipated
somewhere along the way.

Install Method

Self-compiled

What version of WLED?

17.0.0-devV5, built from main at d9b9a84. The code path is unchanged in
released versions.

Which microcontroller/board are you seeing the problem on?

ESP32

Anything else?

Low severity, but the failure is entirely silent, and the symptom it produces —
"BSSID pinning doesn't work" — points away from the actual cause. Someone
debugging why their device still roams has no reason to suspect the field they
filled in correctly-looking.

Happy to open a PR for whichever of the two behaviours you'd prefer; stripping
separators in fillStr2MAC() plus raising the input maxlength would be the
smaller change and keeps both the bare and separated forms working.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions