pi-hole / FTL

The Pi-hole FTL engine
https://pi-hole.net
Other
1.38k stars 196 forks source link

Local DNS record with non-ASCII characters results in config parsing error. #1726

Closed yubiuser closed 1 year ago

yubiuser commented 1 year ago

Steps to reproduce the behavior:

  1. Add a local DNS record "Täst.com"
  2. Delete it.
  3. FTL will restart and throw an error (and part of the config will be reseted)
2023-11-02 22:15:01.930 [363162M] INFO: Compiled for linux/arm64/v8 (compiled on CI) using cc (Alpine 12.2.1_git20220924-r10) 12.2.1 20220924
2023-11-02 22:15:01.940 [363162M] ERR: Cannot parse config file: line 115: bad escape char
2023-11-02 22:15:01.955 [363162M] INFO: Moving /etc/pihole/custom.list to /etc/pihole/custom.list.bck
2023-11-02 22:15:01.969 [363162M] INFO: Initialised webserver ports at 8080 (HTTP) and 443 (HTTPS
### Tasks
- [x] Check escaping of Umlauts
DL6ER commented 1 year ago

Deleting is not necessary, the issue happens after adding + the adjacent restart.

We are talking about the line

0.0.0.0 Täst.com

in unescaped form. As TOML supports UTF-8, we can just leave it unescaped (this is what https://github.com/pi-hole/FTL/pull/1727) does, however, this has still sent me down a rabbit hole - more details below if you are interested.

FTL currently escapes the added config line to

"0.0.0.0 T\0xc3\0xa4st.com"

which should work but TOMLC99 doesn't like it. Carefully inspectingtoml.c we see that the only two escape sequence are either of

"0.0.0.0 T\uC3A4st.com"
"0.0.0.0 T\U0000C3A4st.com"

where the \u has to be lowercase and the hex string itself C3A4 needs to be uppercase (c3a4 is considered invalid) and 2 bytes or \U uppercase and 4 bytes (still all uppercase). Every other combination leads to a syntax error and FTL hence discarding your most recent changes in development-v6.

While checking the toml.c code, I found two auxiliary functions toml_ucs_to_utf8() and toml_utf8_to_ucs() which are neither documented nor used by toml.c itself, but their names alone made me think: Well, that must be there for a reason and they may be what we need. So I checked out these functions to learn how to use them and took them to do the heavy lifting with escaping. This worked out nicely. The escaped string reads:

"0.0.0.0 T\U0000C3A4st.com"