diff options
| -rw-r--r-- | scan_urlencoded_query.c | 28 | ||||
| -rw-r--r-- | scan_urlencoded_query.h | 8 |
2 files changed, 35 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 | } | ||
diff --git a/scan_urlencoded_query.h b/scan_urlencoded_query.h index 74246e7..6f12c03 100644 --- a/scan_urlencoded_query.h +++ b/scan_urlencoded_query.h | |||
| @@ -6,6 +6,8 @@ | |||
| 6 | #ifndef SCAN_URLENCODED_QUERY_H__ | 6 | #ifndef SCAN_URLENCODED_QUERY_H__ |
| 7 | #define SCAN_URLENCODED_QUERY_H__ | 7 | #define SCAN_URLENCODED_QUERY_H__ |
| 8 | 8 | ||
| 9 | #include <stddef.h> | ||
| 10 | #include <stdint.h> | ||
| 9 | #include <sys/types.h> | 11 | #include <sys/types.h> |
| 10 | 12 | ||
| 11 | typedef struct { | 13 | typedef struct { |
| @@ -52,4 +54,10 @@ void scan_urlencoded_skipvalue(char **string); | |||
| 52 | */ | 54 | */ |
| 53 | ssize_t scan_fixed_int(char *data, size_t len, int *number); | 55 | ssize_t scan_fixed_int(char *data, size_t len, int *number); |
| 54 | 56 | ||
| 57 | /* The other direction: percent encode len bytes from src into dest and return | ||
| 58 | how many characters were written, or how many would be needed when dest is | ||
| 59 | NULL. dest needs room for three times len. | ||
| 60 | */ | ||
| 61 | size_t fmt_urlencoded(char *dest, const uint8_t *src, size_t len); | ||
| 62 | |||
| 55 | #endif | 63 | #endif |
