QrCodeComponent: WiFi field escaping only escapes the first special char (regex missing /g) #814

Closed
opened 2026-07-23 12:50:28 +00:00 by spikerj · 2 comments
Owner

Summary

QrCodeComponent (dev-tools-qr-code/src/lib/qr-code.component.ts) builds the WiFi QR payload (WIFI:T:...;S:<ssid>;P:<password>;H:...;;) and escapes the special characters \ ; , " : in the SSID/password via:

private escapeWifiField(value: string): string {
  return value.replace(/([\;,":])/, "\$1");   // <-- no `g` flag
}

The regex has no global flag, so only the first special character is escaped. Any SSID or password containing two or more of \ ; , " : produces a malformed WiFi string.

Reproduction

escapeWifiField("a;b;c")      => "a\;b;c"        // expected "a\;b\;c"
escapeWifiField("Net:5G;Home") => "Net\:5G;Home"  // second special char ':' vs ';' unescaped

Impact

The generated WiFi QR code carries an unescaped delimiter, so a scanning phone mis-parses the payload — it truncates the SSID/password at the unescaped ;/: (or reads a wrong field), and the "connect to WiFi" action fails or joins the wrong network. Common real-world passwords/SSIDs contain multiple special characters (e.g. : in "5G:Home", ; or , in generated passwords).

Fix

Add the global (and, per the WiFi QR spec, this is a per-character escape) flag:

return value.replace(/([\;,":])/g, "\$1");

Notes

Found via unit tests in the frontend coverage sweep (PR #551). Current (buggy) behavior is pinned by a characterization test in qr-code.component.spec.ts referencing this issue.

### Summary `QrCodeComponent` (`dev-tools-qr-code/src/lib/qr-code.component.ts`) builds the WiFi QR payload (`WIFI:T:...;S:<ssid>;P:<password>;H:...;;`) and escapes the special characters `\ ; , " :` in the SSID/password via: ```ts private escapeWifiField(value: string): string { return value.replace(/([\;,":])/, "\$1"); // <-- no `g` flag } ``` The regex has **no global flag**, so only the **first** special character is escaped. Any SSID or password containing two or more of `\ ; , " :` produces a malformed WiFi string. ### Reproduction ``` escapeWifiField("a;b;c") => "a\;b;c" // expected "a\;b\;c" escapeWifiField("Net:5G;Home") => "Net\:5G;Home" // second special char ':' vs ';' unescaped ``` ### Impact The generated WiFi QR code carries an unescaped delimiter, so a scanning phone mis-parses the payload — it truncates the SSID/password at the unescaped `;`/`:` (or reads a wrong field), and the "connect to WiFi" action fails or joins the wrong network. Common real-world passwords/SSIDs contain multiple special characters (e.g. `:` in "5G:Home", `;` or `,` in generated passwords). ### Fix Add the global (and, per the WiFi QR spec, this is a per-character escape) flag: ```ts return value.replace(/([\;,":])/g, "\$1"); ``` ### Notes Found via unit tests in the frontend coverage sweep (PR #551). Current (buggy) behavior is pinned by a characterization test in `qr-code.component.spec.ts` referencing this issue.
Author
Owner

Confirmed still present on master (value.replace(/([\\\;,":])/, "\\\\$1") — no /g), fixed in spikersoft-angular PR #571 — awaiting CI/review.

The characterization test that pinned S:a\;b;c; is flipped to assert the correct S:a\;b\;c;, plus a second case escaping every kind of special character in one password (; , " \\ :) so a partial fix cannot pass.

Verified: feature-dev-tools-qr-code 9 tests pass.

— Opus 5 Agent

Confirmed still present on master (`value.replace(/([\\\;,":])/, "\\\\$1")` — no `/g`), fixed in spikersoft-angular **PR #571** — awaiting CI/review. The characterization test that pinned `S:a\;b;c;` is flipped to assert the correct `S:a\;b\;c;`, plus a second case escaping every kind of special character in one password (`; , " \\ :`) so a partial fix cannot pass. Verified: `feature-dev-tools-qr-code` 9 tests pass. — Opus 5 Agent
Author
Owner

Fixed and verified. spikersoft-angular PR #571 merged to master (721d171b).

Verified on master: escapeWifiField is now value.replace(/([\\;,":])/g, "\\\\$1"). The pinned test asserting the malformed S:a\;b;c; is flipped to require S:a\;b\;c;, and a second guard escapes every special-character kind (; , " \\ :) in one password so a partial fix cannot pass.

PR CI was green end to end. Closing.

— Opus 5 Agent

Fixed and verified. spikersoft-angular PR #571 merged to master (`721d171b`). Verified on master: `escapeWifiField` is now `value.replace(/([\\;,":])/g, "\\\\$1")`. The pinned test asserting the malformed `S:a\;b;c;` is flipped to require `S:a\;b\;c;`, and a second guard escapes every special-character kind (`; , " \\ :`) in one password so a partial fix cannot pass. PR CI was green end to end. Closing. — Opus 5 Agent
Sign in to join this conversation.