comparison libpurple/protocols/jabber/jutil.c @ 28482:22c65c1090a8

jabber: Use a better method for dealing with terminating slashes in JIDs. This saves an allocation/free in jabber_normalize
author Paul Aurich <paul@darkrain42.org>
date Sat, 29 Aug 2009 02:38:28 +0000
parents 2c85f44113b4
children 2e3678cd33a0
comparison
equal deleted inserted replaced
28481:d7cfffdd35e6 28482:22c65c1090a8
275 275
276 return TRUE; 276 return TRUE;
277 #endif /* USE_IDN */ 277 #endif /* USE_IDN */
278 } 278 }
279 279
280 JabberID* 280 static JabberID*
281 jabber_id_new(const char *str) 281 jabber_id_new_internal(const char *str, gboolean allow_terminating_slash)
282 { 282 {
283 const char *at = NULL; 283 const char *at = NULL;
284 const char *slash = NULL; 284 const char *slash = NULL;
285 const char *c; 285 const char *c;
286 gboolean needs_validation = FALSE; 286 gboolean needs_validation = FALSE;
321 if (!slash) { 321 if (!slash) {
322 if (c == str) { 322 if (c == str) {
323 /* JIDs cannot start with / */ 323 /* JIDs cannot start with / */
324 return NULL; 324 return NULL;
325 } 325 }
326 if (c[1] == '\0') { 326 if (c[1] == '\0' && !allow_terminating_slash) {
327 /* JIDs cannot end with / */ 327 /* JIDs cannot end with / */
328 return NULL; 328 return NULL;
329 } 329 }
330 slash = c; 330 slash = c;
331 } 331 }
384 384
385 if (at) { 385 if (at) {
386 jid->node = g_ascii_strdown(str, at - str); 386 jid->node = g_ascii_strdown(str, at - str);
387 if (slash) { 387 if (slash) {
388 jid->domain = g_ascii_strdown(at + 1, slash - (at + 1)); 388 jid->domain = g_ascii_strdown(at + 1, slash - (at + 1));
389 jid->resource = g_strdup(slash + 1); 389 if (*(slash + 1))
390 jid->resource = g_strdup(slash + 1);
390 } else { 391 } else {
391 jid->domain = g_ascii_strdown(at + 1, -1); 392 jid->domain = g_ascii_strdown(at + 1, -1);
392 } 393 }
393 } else { 394 } else {
394 if (slash) { 395 if (slash) {
395 jid->domain = g_ascii_strdown(str, slash - str); 396 jid->domain = g_ascii_strdown(str, slash - str);
396 jid->resource = g_strdup(slash + 1); 397 if (*(slash + 1))
398 jid->resource = g_strdup(slash + 1);
397 } else { 399 } else {
398 jid->domain = g_ascii_strdown(str, -1); 400 jid->domain = g_ascii_strdown(str, -1);
399 } 401 }
400 } 402 }
401 return jid; 403 return jid;
419 /* normalization */ 421 /* normalization */
420 if(at) { 422 if(at) {
421 node = g_utf8_casefold(str, at-str); 423 node = g_utf8_casefold(str, at-str);
422 if(slash) { 424 if(slash) {
423 domain = g_utf8_casefold(at+1, slash-(at+1)); 425 domain = g_utf8_casefold(at+1, slash-(at+1));
424 jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC); 426 if (*(slash + 1))
427 jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC);
425 } else { 428 } else {
426 domain = g_utf8_casefold(at+1, -1); 429 domain = g_utf8_casefold(at+1, -1);
427 } 430 }
428 } else { 431 } else {
429 if(slash) { 432 if(slash) {
430 domain = g_utf8_casefold(str, slash-str); 433 domain = g_utf8_casefold(str, slash-str);
431 jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC); 434 if (*(slash + 1))
435 jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC);
432 } else { 436 } else {
433 domain = g_utf8_casefold(str, -1); 437 domain = g_utf8_casefold(str, -1);
434 } 438 }
435 } 439 }
436 440
498 jabber_id_free(jid); 502 jabber_id_free(jid);
499 503
500 return out; 504 return out;
501 } 505 }
502 506
507 JabberID *
508 jabber_id_new(const char *str)
509 {
510 return jabber_id_new_internal(str, FALSE);
511 }
512
503 const char *jabber_normalize(const PurpleAccount *account, const char *in) 513 const char *jabber_normalize(const PurpleAccount *account, const char *in)
504 { 514 {
505 PurpleConnection *gc = account ? account->gc : NULL; 515 PurpleConnection *gc = account ? account->gc : NULL;
506 JabberStream *js = gc ? gc->proto_data : NULL; 516 JabberStream *js = gc ? gc->proto_data : NULL;
507 static char buf[3072]; /* maximum legal length of a jabber jid */ 517 static char buf[3072]; /* maximum legal length of a jabber jid */
508 JabberID *jid; 518 JabberID *jid;
509 char *tmp; 519
510 size_t len = strlen(in); 520 jid = jabber_id_new_internal(in, TRUE);
511
512 /*
513 * If the JID ends with a '/', jabber_id_new is going to throw it away as
514 * invalid. However, this is what the UI generates for a JID with no
515 * resource. Deal with that by dropping away the '/'...
516 */
517 if (in[len - 1] == '/')
518 tmp = g_strndup(in, len - 1);
519 else
520 tmp = (gchar *)in;
521
522 jid = jabber_id_new(tmp);
523
524 if (tmp != in)
525 g_free(tmp);
526
527 if(!jid) 521 if(!jid)
528 return NULL; 522 return NULL;
529 523
530 if(js && jid->node && jid->resource && 524 if(js && jid->node && jid->resource &&
531 jabber_chat_find(js, jid->node, jid->domain)) 525 jabber_chat_find(js, jid->node, jid->domain))