Dillo v3.2.0-88-g47ab7c70
Loading...
Searching...
No Matches
misc.h
Go to the documentation of this file.
1#ifndef __DILLO_MISC_H__
2#define __DILLO_MISC_H__
3
4#include <stddef.h> /* for size_t */
5#include <ctype.h> /* iscntrl, isascii */
6
7
8#ifdef __cplusplus
9extern "C" {
10#endif /* __cplusplus */
11
12#define d_isascii(c) (((c) & ~0x7f) == 0)
13
14char *a_Misc_escape_chars(const char *str, const char *esc_set);
15int a_Misc_expand_tabs(char **start, char *end, char *buf, int buflen);
16int a_Misc_get_content_type_from_data(void *Data, size_t Size,const char **PT);
17int a_Misc_content_type_check(const char *EntryType, const char *DetectedType);
18void a_Misc_parse_content_type(const char *str, char **major, char **minor,
19 char **charset);
20int a_Misc_content_type_cmp(const char* ct1, const char *ct2);
21int a_Misc_parse_geometry(char *geom, int *x, int *y, int *w, int *h);
22int a_Misc_parse_search_url(char *source, char **label, char **urlstr);
23char *a_Misc_encode_base64(const char *in);
24Dstr *a_Misc_file2dstr(const char *filename);
25
30static inline void a_Misc_parse_content_disposition(const char *disposition, char **type, char **filename)
31{
32 static const char tspecials_space[] = "()<>@,;:\\\"/[]?= ";
33 const char terminators[] = " ;\t";
34 const char *str, *s;
35
36 /* All are mandatory */
37 if (!disposition || !type || !filename)
38 return;
39
40 *type = NULL;
41 *filename = NULL;
42 str = disposition;
43
44 /* Parse the type (attachment, inline, ...) by reading alpha characters. */
45 for (s = str; *s && d_isascii((uchar_t)*s) && !iscntrl((uchar_t)*s) &&
46 !strchr(tspecials_space, *s); s++) ;
47
48 if (s != str) {
49 *type = dStrndup(str, s - str);
50 } else {
51 /* Cannot find type, stop here */
52 return;
53 }
54
55 /* Abort if there are no terminators after the type */
56 if (!strchr(terminators, *s)) {
57 dFree(*type);
58 *type = NULL;
59 return;
60 }
61
62 /* Skip blanks like "attachment ; ..." */
63 while (*s == ' ' || *s == '\t')
64 s++;
65
66 /* Stop if the terminator is not ; */
67 if (*s != ';')
68 return;
69
70 /* Now parse the filename */
71 bool_t quoted = FALSE;
72 const char key[] = "filename";
73
74 /* Locate "filename", if not found stop */
75 if ((s = dStriAsciiStr(str, key)) == NULL)
76 return;
77
78 /* Ensure that it is preceded by a terminator if it doesn't start the
79 * disposition??? */
80 if (s != str && !strchr(terminators, s[-1]))
81 return;
82
83 /* Advance s over "filename" (skipping the nul character) */
84 s += sizeof(key) - 1;
85
86 /* Skip blanks like "filename =..." */
87 while (*s == ' ' || *s == '\t')
88 s++;
89
90 /* Stop if there is no equal sign */
91 if (*s != '=')
92 return;
93
94 /* Skip over the equal */
95 s++;
96
97 /* Skip blanks after the equal like "filename= ..." */
98 while (*s == ' ' || *s == '\t')
99 s++;
100
101 size_t len = 0;
102 if (*s == '"') {
103 quoted = TRUE;
104
105 /* Skip over quote */
106 s++;
107
108 /* Ignore dots at the beginning of the filename */
109 while (*s == '.')
110 s++;
111
112 size_t maxlen = strlen(s);
113
114 /* Must have at least two characters left */
115 if (maxlen < 2)
116 return;
117
118 for (size_t i = 1; i < maxlen; i++) {
119 /* Find closing quote not escaped */
120 if (s[i - 1] != '\\' && s[i] == '"') {
121 /* Copy i bytes, skip closing quote */
122 len = i;
123 *filename = dStrndup(s, len);
124 break;
125 }
126 }
127 } else {
128 /* Ignore dots at the beginning of the filename */
129 while (*s == '.')
130 s++;
131
132 /* Keep filename until we find a terminator */
133 if ((len = strcspn(s, terminators))) {
134 *filename = dStrndup(s, len);
135 }
136 }
137
138 /* No filename, stop here */
139 if (*filename == NULL)
140 return;
141
142 /* Otherwise remove bad characters from filename */
143 const char bad_characters[] = "/\\|~";
144
145 /* Make a copy */
146 char *src = dStrndup(*filename, len);
147 char *dst = *filename;
148 int bad = 0;
149 size_t j = 0;
150
151 for (size_t i = 0; i < len; i++) {
152 int c = src[i];
153 if (i + 1 < len && c == '\\' && src[i + 1] == '\"') {
154 /* Found \", copy the quote only */
155 dst[j++] = '"';
156 i++; /* Skip quote in src */
157 } else if (strchr(bad_characters, c)) {
158 /* Bad character, replace with '_' */
159 dst[j++] = '_';
160 } else if (!quoted && (!d_isascii((uchar_t) c) || c == '=')) {
161 /* Found non-ascii character or '=', disregard */
162 bad = 1;
163 break;
164 } else {
165 /* Character is fine, just copy as-is */
166 dst[j++] = src[i];
167 }
168 }
169
170 /* Always terminate filename */
171 dst[j] = '\0';
172
173 dFree(src);
174
175 if (bad) {
176 dFree(*filename);
177 *filename = NULL;
178 return;
179 }
180}
181
182#ifdef __cplusplus
183}
184#endif /* __cplusplus */
185
186#endif /* __DILLO_MISC_H__ */
187
unsigned char uchar_t
Definition d_size.h:17
unsigned char bool_t
Definition d_size.h:21
void dFree(void *mem)
Definition dlib.c:68
char * dStriAsciiStr(const char *haystack, const char *needle)
Case insensitive strstr.
Definition dlib.c:184
char * dStrndup(const char *s, size_t sz)
Definition dlib.c:88
#define TRUE
Definition dlib.h:35
#define FALSE
Definition dlib.h:31
int a_Misc_parse_search_url(char *source, char **label, char **urlstr)
Parse dillorc's search_url string ([<label> ]<url>) Return value: -1 on error, 0 on success (and labe...
Definition misc.c:391
static void a_Misc_parse_content_disposition(const char *disposition, char **type, char **filename)
Parse Content-Disposition string, e.g., "attachment; filename="file name.jpg"".
Definition misc.h:30
int a_Misc_content_type_check(const char *EntryType, const char *DetectedType)
Check the server-supplied 'Content-Type' against our detected type.
Definition misc.c:321
void a_Misc_parse_content_type(const char *str, char **major, char **minor, char **charset)
Parse Content-Type string, e.g., "text/html; charset=utf-8".
Definition misc.c:210
#define d_isascii(c)
Definition misc.h:12
int a_Misc_expand_tabs(char **start, char *end, char *buf, int buflen)
Takes a string and converts any tabs to spaces.
Definition misc.c:54
Dstr * a_Misc_file2dstr(const char *filename)
Load a local file into a dStr.
Definition misc.c:464
char * a_Misc_encode_base64(const char *in)
Encodes string using base64 encoding.
Definition misc.c:425
char * a_Misc_escape_chars(const char *str, const char *esc_set)
Escape characters as XX sequences.
Definition misc.c:26
int a_Misc_parse_geometry(char *geom, int *x, int *y, int *w, int *h)
Parse a geometry string.
Definition misc.c:360
int a_Misc_content_type_cmp(const char *ct1, const char *ct2)
Compare two Content-Type strings.
Definition misc.c:274
int a_Misc_get_content_type_from_data(void *Data, size_t Size, const char **PT)
Detects 'Content-Type' from a data stream sample.
Definition misc.c:136
Definition dlib.h:114