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