1 /*
2 * File: dpiutil.c
3 *
4 * Copyright 2004-2007 Jorge Arellano Cid <jcid@dillo.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 */
12
13 #include <unistd.h>
14 #include <stdio.h>
15 #include <stdarg.h>
16 #include <string.h>
17 #include <ctype.h>
18 #include <errno.h>
19 #include <sys/socket.h>
20
21 #include "dpiutil.h"
22
23 /*
24 * Debugging macros
25 */
26 #define _MSG(...)
27 #define MSG(...) printf("[dpiutil.c]: " __VA_ARGS__)
28
29
30 /* Escaping/De-escaping ---------------------------------------------------*/
31
32 /*
33 * Escape URI characters in 'esc_set' as %XX sequences.
34 * Return value: New escaped string.
35 */
Escape_uri_str(const char * str,const char * p_esc_set)36 char *Escape_uri_str(const char *str, const char *p_esc_set)
37 {
38 static const char *esc_set, *hex = "0123456789ABCDEF";
39 char *p;
40 Dstr *dstr;
41 int i;
42
43 esc_set = (p_esc_set) ? p_esc_set : "%#:' ";
44 dstr = dStr_sized_new(64);
45 for (i = 0; str[i]; ++i) {
46 if (str[i] <= 0x1F || str[i] == 0x7F || strchr(esc_set, str[i])) {
47 dStr_append_c(dstr, '%');
48 dStr_append_c(dstr, hex[(str[i] >> 4) & 15]);
49 dStr_append_c(dstr, hex[str[i] & 15]);
50 } else {
51 dStr_append_c(dstr, str[i]);
52 }
53 }
54 p = dstr->str;
55 dStr_free(dstr, FALSE);
56
57 return p;
58 }
59
60 /*
61 * Unescape %XX sequences in a string.
62 * Return value: a new unescaped string
63 */
Unescape_uri_str(const char * s)64 char *Unescape_uri_str(const char *s)
65 {
66 char *p, *buf = dStrdup(s);
67
68 if (strchr(s, '%')) {
69 for (p = buf; (*p = *s); ++s, ++p) {
70 if (*p == '%' && isxdigit(s[1]) && isxdigit(s[2])) {
71 *p = (isdigit(s[1]) ? (s[1] - '0')
72 : D_ASCII_TOUPPER(s[1]) - 'A' + 10) * 16;
73 *p += isdigit(s[2]) ? (s[2] - '0')
74 : D_ASCII_TOUPPER(s[2]) - 'A' + 10;
75 s += 2;
76 }
77 }
78 }
79
80 return buf;
81 }
82
83
84 static const char *unsafe_chars = "&<>\"'";
85 static const char *unsafe_rep[] =
86 { "&", "<", ">", """, "'" };
87 static const int unsafe_rep_len[] = { 5, 4, 4, 6, 5 };
88
89 /*
90 * Escape unsafe characters as html entities.
91 * Return value: New escaped string.
92 */
Escape_html_str(const char * str)93 char *Escape_html_str(const char *str)
94 {
95 int i;
96 char *p;
97 Dstr *dstr = dStr_sized_new(64);
98
99 for (i = 0; str[i]; ++i) {
100 if ((p = strchr(unsafe_chars, str[i])))
101 dStr_append(dstr, unsafe_rep[p - unsafe_chars]);
102 else
103 dStr_append_c(dstr, str[i]);
104 }
105 p = dstr->str;
106 dStr_free(dstr, FALSE);
107
108 return p;
109 }
110
111 /*
112 * Unescape a few HTML entities (inverse of Escape_html_str)
113 * Return value: New unescaped string.
114 */
Unescape_html_str(const char * str)115 char *Unescape_html_str(const char *str)
116 {
117 int i, j, k;
118 char *u_str = dStrdup(str);
119
120 if (!strchr(str, '&'))
121 return u_str;
122
123 for (i = 0, j = 0; str[i]; ++i) {
124 if (str[i] == '&') {
125 for (k = 0; k < 5; ++k) {
126 if (!dStrnAsciiCasecmp(str + i, unsafe_rep[k], unsafe_rep_len[k])) {
127 i += unsafe_rep_len[k] - 1;
128 break;
129 }
130 }
131 u_str[j++] = (k < 5) ? unsafe_chars[k] : str[i];
132 } else {
133 u_str[j++] = str[i];
134 }
135 }
136 u_str[j] = 0;
137
138 return u_str;
139 }
140
141 /*
142 * Filter '\n', '\r', "%0D" and "%0A" from the authority part of an FTP url.
143 * This helps to avoid a SMTP relaying hack. This filtering could be done
144 * only when port == 25, but if the mail server is listening on another
145 * port it wouldn't work.
146 * Note: AFAIS this should be done by wget.
147 */
Filter_smtp_hack(char * url)148 char *Filter_smtp_hack(char *url)
149 {
150 int i;
151 char c;
152
153 if (strlen(url) > 6) { /* ftp:// */
154 for (i = 6; (c = url[i]) && c != '/'; ++i) {
155 if (c == '\n' || c == '\r') {
156 memmove(url + i, url + i + 1, strlen(url + i));
157 --i;
158 } else if (c == '%' && url[i+1] == '0' &&
159 (D_ASCII_TOLOWER(url[i+2]) == 'a' ||
160 D_ASCII_TOLOWER(url[i+2]) == 'd')) {
161 memmove(url + i, url + i + 3, strlen(url + i + 2));
162 --i;
163 }
164 }
165 }
166 return url;
167 }
168
169