summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scan_urlencoded_query.c28
-rw-r--r--scan_urlencoded_query.h8
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&param=value, it is encoded in bit 0, 1 and 2 25 /path?param=value&param=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
163size_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
11typedef struct { 13typedef struct {
@@ -52,4 +54,10 @@ void scan_urlencoded_skipvalue(char **string);
52 */ 54 */
53ssize_t scan_fixed_int(char *data, size_t len, int *number); 55ssize_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 */
61size_t fmt_urlencoded(char *dest, const uint8_t *src, size_t len);
62
55#endif 63#endif