Mercurial > pidgin
comparison libpurple/protocols/jabber/jutil.c @ 27590:a08e84032814
merge of '2348ff22f0ff3453774b8b25b36238465580c609'
and 'e76f11543c2a4aa05bdf584f087cbe3439029661'
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sun, 12 Jul 2009 05:43:38 +0000 |
parents | f1f901b3d6f2 |
children | aac25c66a843 |
comparison
equal
deleted
inserted
replaced
27104:048bcf41deef | 27590:a08e84032814 |
---|---|
52 } | 52 } |
53 | 53 |
54 return TRUE; | 54 return TRUE; |
55 } | 55 } |
56 | 56 |
57 gboolean jabber_nameprep_validate(const char *str) | 57 gboolean jabber_domain_validate(const char *str) |
58 { | 58 { |
59 const char *c; | 59 const char *c; |
60 size_t len; | |
60 | 61 |
61 if(!str) | 62 if(!str) |
62 return TRUE; | 63 return TRUE; |
63 | 64 |
64 if(strlen(str) > 1023) | 65 len = strlen(str); |
66 if (len > 1023) | |
65 return FALSE; | 67 return FALSE; |
66 | 68 |
67 c = str; | 69 c = str; |
70 | |
71 if (*c == '[') { | |
72 /* Check if str is a valid IPv6 identifier */ | |
73 gboolean valid = FALSE; | |
74 | |
75 if (*(c + len - 1) != ']') | |
76 return FALSE; | |
77 | |
78 /* Ugly, but in-place */ | |
79 *(gchar *)(c + len - 1) = '\0'; | |
80 valid = purple_ipv6_address_is_valid(c + 1); | |
81 *(gchar *)(c + len - 1) = ']'; | |
82 | |
83 return valid; | |
84 } | |
85 | |
68 while(c && *c) { | 86 while(c && *c) { |
69 gunichar ch = g_utf8_get_char(c); | 87 gunichar ch = g_utf8_get_char(c); |
70 if(!g_unichar_isgraph(ch)) | 88 /* The list of characters allowed in domain names is pretty small */ |
89 if ((ch <= 0x7F && !( (ch >= 'a' && ch <= 'z') | |
90 || (ch >= '0' && ch <= '9') | |
91 || (ch >= 'A' && ch <= 'Z') | |
92 || ch == '.' | |
93 || ch == '-' )) || (ch >= 0x80 && !g_unichar_isgraph(ch))) | |
71 return FALSE; | 94 return FALSE; |
72 | 95 |
73 c = g_utf8_next_char(c); | 96 c = g_utf8_next_char(c); |
74 } | 97 } |
75 | |
76 | 98 |
77 return TRUE; | 99 return TRUE; |
78 } | 100 } |
79 | 101 |
80 gboolean jabber_resourceprep_validate(const char *str) | 102 gboolean jabber_resourceprep_validate(const char *str) |
101 | 123 |
102 | 124 |
103 JabberID* | 125 JabberID* |
104 jabber_id_new(const char *str) | 126 jabber_id_new(const char *str) |
105 { | 127 { |
106 char *at; | 128 const char *at = NULL; |
107 char *slash; | 129 const char *slash = NULL; |
130 const char *c; | |
131 gboolean needs_validation = FALSE; | |
132 #if 0 | |
133 gboolean node_is_required = FALSE; | |
134 #endif | |
108 char *node = NULL; | 135 char *node = NULL; |
109 char *domain; | 136 char *domain; |
110 JabberID *jid; | 137 JabberID *jid; |
111 | 138 |
112 if(!str || !g_utf8_validate(str, -1, NULL)) | 139 if (!str) |
140 return NULL; | |
141 | |
142 for (c = str; *c != '\0'; c++) | |
143 { | |
144 switch (*c) { | |
145 case '@': | |
146 if (!slash) { | |
147 if (at) { | |
148 /* Multiple @'s in the node/domain portion, not a valid JID! */ | |
149 return NULL; | |
150 } | |
151 if (c == str) { | |
152 /* JIDs cannot start with @ */ | |
153 return NULL; | |
154 } | |
155 if (c[1] == '\0') { | |
156 /* JIDs cannot end with @ */ | |
157 return NULL; | |
158 } | |
159 at = c; | |
160 } | |
161 break; | |
162 | |
163 case '/': | |
164 if (!slash) { | |
165 if (c == str) { | |
166 /* JIDs cannot start with / */ | |
167 return NULL; | |
168 } | |
169 if (c[1] == '\0') { | |
170 /* JIDs cannot end with / */ | |
171 return NULL; | |
172 } | |
173 slash = c; | |
174 } | |
175 break; | |
176 | |
177 default: | |
178 /* characters allowed everywhere */ | |
179 if ((*c >= 'a' && *c <= 'z') | |
180 || (*c >= '0' && *c <= '9') | |
181 || (*c >= 'A' && *c <= 'Z') | |
182 || *c == '.' || *c == '-') | |
183 /* We're good */ | |
184 break; | |
185 | |
186 #if 0 | |
187 if (slash != NULL) { | |
188 /* characters allowed only in the resource */ | |
189 if (implement_me) | |
190 /* We're good */ | |
191 break; | |
192 } | |
193 | |
194 /* characters allowed only in the node */ | |
195 if (implement_me) { | |
196 /* | |
197 * Ok, this character is valid, but only if it's a part | |
198 * of the node and not the domain. But we don't know | |
199 * if "c" is a part of the node or the domain until after | |
200 * we've found the @. So set a flag for now and check | |
201 * that we found an @ later. | |
202 */ | |
203 node_is_required = TRUE; | |
204 break; | |
205 } | |
206 #endif | |
207 | |
208 /* | |
209 * Hmm, this character is a bit more exotic. Better fall | |
210 * back to using the more expensive UTF-8 compliant | |
211 * stringprep functions. | |
212 */ | |
213 needs_validation = TRUE; | |
214 break; | |
215 } | |
216 } | |
217 | |
218 #if 0 | |
219 if (node_is_required && at == NULL) | |
220 /* Found invalid characters in the domain */ | |
221 return NULL; | |
222 #endif | |
223 | |
224 if (!needs_validation) { | |
225 /* JID is made of only ASCII characters--just lowercase and return */ | |
226 jid = g_new0(JabberID, 1); | |
227 | |
228 if (at) { | |
229 jid->node = g_ascii_strdown(str, at - str); | |
230 if (slash) { | |
231 jid->domain = g_ascii_strdown(at + 1, slash - (at + 1)); | |
232 jid->resource = g_strdup(slash + 1); | |
233 } else { | |
234 jid->domain = g_ascii_strdown(at + 1, -1); | |
235 } | |
236 } else { | |
237 if (slash) { | |
238 jid->domain = g_ascii_strdown(str, slash - str); | |
239 jid->resource = g_strdup(slash + 1); | |
240 } else { | |
241 jid->domain = g_ascii_strdown(str, -1); | |
242 } | |
243 } | |
244 return jid; | |
245 } | |
246 | |
247 /* | |
248 * If we get here, there are some non-ASCII chars in the string, so | |
249 * we'll need to validate it, normalize, and finally do a full jabber | |
250 * nodeprep on the jid. | |
251 */ | |
252 | |
253 if (!g_utf8_validate(str, -1, NULL)) | |
113 return NULL; | 254 return NULL; |
114 | 255 |
115 jid = g_new0(JabberID, 1); | 256 jid = g_new0(JabberID, 1); |
116 | 257 |
117 at = g_utf8_strchr(str, -1, '@'); | 258 /* normalization */ |
118 slash = g_utf8_strchr(str, -1, '/'); | |
119 | |
120 if(at) { | 259 if(at) { |
121 node = g_utf8_normalize(str, at-str, G_NORMALIZE_NFKC); | 260 node = g_utf8_normalize(str, at-str, G_NORMALIZE_NFKC); |
122 if(slash) { | 261 if(slash) { |
123 domain = g_utf8_normalize(at+1, slash-(at+1), G_NORMALIZE_NFKC); | 262 domain = g_utf8_normalize(at+1, slash-(at+1), G_NORMALIZE_NFKC); |
124 jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC); | 263 jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC); |
142 if (domain) { | 281 if (domain) { |
143 jid->domain = g_utf8_strdown(domain, -1); | 282 jid->domain = g_utf8_strdown(domain, -1); |
144 g_free(domain); | 283 g_free(domain); |
145 } | 284 } |
146 | 285 |
286 /* and finally the jabber nodeprep */ | |
147 if(!jabber_nodeprep_validate(jid->node) || | 287 if(!jabber_nodeprep_validate(jid->node) || |
148 !jabber_nameprep_validate(jid->domain) || | 288 !jabber_domain_validate(jid->domain) || |
149 !jabber_resourceprep_validate(jid->resource)) { | 289 !jabber_resourceprep_validate(jid->resource)) { |
150 jabber_id_free(jid); | 290 jabber_id_free(jid); |
151 return NULL; | 291 return NULL; |
152 } | 292 } |
153 | 293 |