diff options
| author | Dirk Engling <erdgeist@erdgeist.org> | 2026-10-24 05:48:37 +0200 |
|---|---|---|
| committer | Dirk Engling <erdgeist@erdgeist.org> | 2026-10-24 05:48:37 +0200 |
| commit | 185bee5366b26db3788d1486bb15e9b46f344771 (patch) | |
| tree | 8e89cf0cf75889faa2e4f9c7b4416de49ff12fca /scan_urlencoded_query.c | |
| parent | 040c7eab81f8b1526841d3c8ce56e4912cae10f1 (diff) | |
Add a url escaper next to the scanner
Diffstat (limited to 'scan_urlencoded_query.c')
| -rw-r--r-- | scan_urlencoded_query.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/scan_urlencoded_query.c b/scan_urlencoded_query.c index 50aced3..cf0c5b1 100644 --- a/scan_urlencoded_query.c +++ b/scan_urlencoded_query.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | /* This matrix holds for each ascii character the information, | 22 | /* This matrix holds for each ascii character the information, |
| 23 | whether it is a non-terminating character for on of the three | 23 | whether it is a non-terminating character for one of the three |
| 24 | scan states we are in, that is 'path', 'param' and 'value' from | 24 | scan states we are in, that is 'path', 'param' and 'value' from |
| 25 | /path?param=value¶m=value, it is encoded in bit 0, 1 and 2 | 25 | /path?param=value¶m=value, it is encoded in bit 0, 1 and 2 |
| 26 | respectively | 26 | respectively |
| @@ -159,3 +159,29 @@ ssize_t scan_fixed_int(char *data, size_t len, int *tmp) { | |||
| 159 | *tmp = -*tmp; | 159 | *tmp = -*tmp; |
| 160 | return len; | 160 | return len; |
| 161 | } | 161 | } |
| 162 | |||
| 163 | size_t fmt_urlencoded(char *dest, const uint8_t *src, size_t len) { | ||
| 164 | static const char safe[] = "$/.=~-_"; | ||
| 165 | static const char hexdigit[] = "0123456789abcdef"; | ||
| 166 | size_t written = 0, i; | ||
| 167 | |||
| 168 | for (i = 0; i < len; ++i) { | ||
| 169 | uint8_t c = src[i]; | ||
| 170 | |||
| 171 | /* strchr would find the terminator, so a zero byte never counts as safe */ | ||
| 172 | if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c && strchr(safe, c))) { | ||
| 173 | if (dest) | ||
| 174 | dest[written] = (char)c; | ||
| 175 | ++written; | ||
| 176 | } else { | ||
| 177 | if (dest) { | ||
| 178 | dest[written] = '%'; | ||
| 179 | dest[written + 1] = hexdigit[c >> 4]; | ||
| 180 | dest[written + 2] = hexdigit[c & 15]; | ||
| 181 | } | ||
| 182 | written += 3; | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | return written; | ||
| 187 | } | ||
