comparison libpurple/protocols/gg/lib/libgadu.c @ 30972:a42f7d3ad459

Update internal/external libgadu to 1.9.0, except for some superfluous changes, such as the extra format_ variable in gg_convert_to_html. Fixes #12789.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sun, 28 Nov 2010 00:18:31 +0000
parents 0665d7eff0a3
children a8cc50c2279f
comparison
equal deleted inserted replaced
30971:d63748b78769 30972:a42f7d3ad459
67 #ifdef GG_CONFIG_HAVE_OPENSSL 67 #ifdef GG_CONFIG_HAVE_OPENSSL
68 # include <openssl/err.h> 68 # include <openssl/err.h>
69 # include <openssl/rand.h> 69 # include <openssl/rand.h>
70 #endif 70 #endif
71 71
72 #define GG_LIBGADU_VERSION "1.9.0-rc2" 72 #define GG_LIBGADU_VERSION "1.9.0"
73 73
74 /** 74 /**
75 * Poziom rejestracji informacji odpluskwiających. Zmienna jest maską bitową 75 * Poziom rejestracji informacji odpluskwiających. Zmienna jest maską bitową
76 * składającą się ze stałych \c GG_DEBUG_... 76 * składającą się ze stałych \c GG_DEBUG_...
77 * 77 *
178 #ifndef lint 178 #ifndef lint
179 static char rcsid[] 179 static char rcsid[]
180 #ifdef __GNUC__ 180 #ifdef __GNUC__
181 __attribute__ ((unused)) 181 __attribute__ ((unused))
182 #endif 182 #endif
183 = "$Id: libgadu.c 878 2009-11-16 23:48:19Z wojtekka $"; 183 = "$Id: libgadu.c 923 2010-03-09 20:03:29Z wojtekka $";
184 #endif 184 #endif
185 185
186 #endif /* DOXYGEN */ 186 #endif /* DOXYGEN */
187 187
188 /** 188 /**
1314 1314
1315 /** 1315 /**
1316 * \internal Zamienia tekst z formatowaniem Gadu-Gadu na HTML. 1316 * \internal Zamienia tekst z formatowaniem Gadu-Gadu na HTML.
1317 * 1317 *
1318 * \param dst Bufor wynikowy (może być \c NULL) 1318 * \param dst Bufor wynikowy (może być \c NULL)
1319 * \param utf_msg Tekst źródłowy 1319 * \param src Tekst źródłowy w UTF-8
1320 * \param format Atrybuty tekstu źródłowego 1320 * \param format Atrybuty tekstu źródłowego
1321 * \param format_len Długość bloku atrybutów tekstu źródłowego 1321 * \param format_len Długość bloku atrybutów tekstu źródłowego
1322 * 1322 *
1323 * \note Wynikowy tekst nie jest idealnym kodem HTML, ponieważ ma jak
1324 * dokładniej odzwierciedlać to, co wygenerowałby oryginalny klient.
1325 *
1323 * \note Dokleja \c \\0 na końcu bufora wynikowego. 1326 * \note Dokleja \c \\0 na końcu bufora wynikowego.
1324 * 1327 *
1325 * \return Długość tekstu wynikowego bez \c \\0 (nawet jeśli \c dst to \c NULL). 1328 * \return Długość tekstu wynikowego bez \c \\0 (nawet jeśli \c dst to \c NULL).
1326 */ 1329 */
1327 static int gg_convert_to_html(char *dst, const char *utf_msg, const unsigned char *format, int format_len) 1330 static int gg_convert_to_html(char *dst, const char *src, const unsigned char *format, int format_len)
1328 { 1331 {
1329 const char span_fmt[] = "<span style=\"color:#%02x%02x%02x; font-family:'MS Shell Dlg 2'; font-size:9pt; \">"; 1332 const char span_fmt[] = "<span style=\"color:#%02x%02x%02x; font-family:'MS Shell Dlg 2'; font-size:9pt; \">";
1330 const int span_len = 75; 1333 const int span_len = 75;
1331 const char img_fmt[] = "<img src=\"%02x%02x%02x%02x%02x%02x%02x%02x\">"; 1334 const char img_fmt[] = "<img name=\"%02x%02x%02x%02x%02x%02x%02x%02x\">";
1332 const int img_len = 28; 1335 const int img_len = 29;
1333 int char_pos = 0; 1336 int char_pos = 0;
1334 int format_idx = 3; 1337 int format_idx = 0;
1335 unsigned char old_attr = 0; 1338 unsigned char old_attr = 0;
1336 const unsigned char *color = (const unsigned char*) "\x00\x00\x00"; 1339 const unsigned char *color = (const unsigned char*) "\x00\x00\x00";
1337 int len, i; 1340 int len, i;
1338 1341
1339 len = 0; 1342 len = 0;
1340 1343
1341 for (i = 0; utf_msg[i] != 0; i++) { 1344 /* Nie mamy atrybutów dla pierwsze znaku, a tekst nie jest pusty, więc
1342 unsigned char attr; 1345 * tak czy inaczej trzeba otworzyć <span>. */
1343 int attr_pos; 1346
1344 1347 if (src[0] != 0 && (format_idx + 3 > format_len || (format[format_idx] | (format[format_idx + 1] << 8)) != 0)) {
1345 if (format_idx + 3 <= format_len) { 1348 if (dst != NULL)
1349 sprintf(&dst[len], span_fmt, 0, 0, 0);
1350
1351 len += span_len;
1352 }
1353
1354 /* Pętla przechodzi też przez kończące \0, żeby móc dokleić obrazek
1355 * na końcu tekstu. */
1356
1357 for (i = 0; ; i++) {
1358 /* Analizuj atrybuty tak długo jak dotyczą aktualnego znaku. */
1359 for (;;) {
1360 unsigned char attr;
1361 int attr_pos;
1362
1363 if (format_idx + 3 > format_len)
1364 break;
1365
1346 attr_pos = format[format_idx] | (format[format_idx + 1] << 8); 1366 attr_pos = format[format_idx] | (format[format_idx + 1] << 8);
1367
1368 if (attr_pos != char_pos)
1369 break;
1370
1347 attr = format[format_idx + 2]; 1371 attr = format[format_idx + 2];
1348 } else { 1372
1349 attr_pos = -1; 1373 /* Nie doklejaj atrybutów na końcu, co najwyżej obrazki. */
1350 attr = 0; 1374
1351 } 1375 if (src[i] == 0)
1352 1376 attr &= ~(GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR);
1353 if (attr_pos == char_pos) { 1377
1354 format_idx += 3; 1378 format_idx += 3;
1355 1379
1356 if ((attr & (GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR)) != 0) { 1380 if ((attr & (GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR)) != 0) {
1357 if (char_pos != 0) { 1381 if (char_pos != 0) {
1358 if ((old_attr & GG_FONT_UNDERLINE) != 0) 1382 if ((old_attr & GG_FONT_UNDERLINE) != 0)
1375 } 1399 }
1376 1400
1377 if (dst != NULL) 1401 if (dst != NULL)
1378 sprintf(&dst[len], span_fmt, color[0], color[1], color[2]); 1402 sprintf(&dst[len], span_fmt, color[0], color[1], color[2]);
1379 len += span_len; 1403 len += span_len;
1380 } else if (char_pos == 0) { 1404 } else if (char_pos == 0 && src[0] != 0) {
1381 if (dst != NULL) 1405 if (dst != NULL)
1382 sprintf(&dst[len], span_fmt, 0, 0, 0); 1406 sprintf(&dst[len], span_fmt, 0, 0, 0);
1383 len += span_len; 1407 len += span_len;
1384 } 1408 }
1385 1409
1408 len += img_len; 1432 len += img_len;
1409 format_idx += 10; 1433 format_idx += 10;
1410 } 1434 }
1411 1435
1412 old_attr = attr; 1436 old_attr = attr;
1413 } else if (i == 0) { 1437 }
1414 if (dst != NULL) 1438
1415 sprintf(&dst[len], span_fmt, 0, 0, 0); 1439 /* Doklej znak zachowując htmlowe escapowanie. */
1416 1440
1417 len += span_len; 1441 switch (src[i]) {
1418 }
1419
1420 switch (utf_msg[i]) {
1421 case '&': 1442 case '&':
1422 gg_append(dst, &len, "&amp;", 5); 1443 gg_append(dst, &len, "&amp;", 5);
1423 break; 1444 break;
1424 case '<': 1445 case '<':
1425 gg_append(dst, &len, "&lt;", 4); 1446 gg_append(dst, &len, "&lt;", 4);
1435 break; 1456 break;
1436 case '\n': 1457 case '\n':
1437 gg_append(dst, &len, "<br>", 4); 1458 gg_append(dst, &len, "<br>", 4);
1438 break; 1459 break;
1439 case '\r': 1460 case '\r':
1461 case 0:
1440 break; 1462 break;
1441 default: 1463 default:
1442 if (dst != NULL) 1464 if (dst != NULL)
1443 dst[len] = utf_msg[i]; 1465 dst[len] = src[i];
1444 len++; 1466 len++;
1445 } 1467 }
1446 1468
1447 /* Sprawdź, czy bajt nie jest kontynuacją znaku unikodowego. */ 1469 /* Sprawdź, czy bajt nie jest kontynuacją znaku unikodowego. */
1448 1470
1449 if ((utf_msg[i] & 0xc0) != 0xc0) 1471 if ((src[i] & 0xc0) != 0xc0)
1450 char_pos++; 1472 char_pos++;
1451 } 1473
1474 if (src[i] == 0)
1475 break;
1476 }
1477
1478 /* Zamknij tagi. */
1452 1479
1453 if ((old_attr & GG_FONT_UNDERLINE) != 0) 1480 if ((old_attr & GG_FONT_UNDERLINE) != 0)
1454 gg_append(dst, &len, "</u>", 4); 1481 gg_append(dst, &len, "</u>", 4);
1455 1482
1456 if ((old_attr & GG_FONT_ITALIC) != 0) 1483 if ((old_attr & GG_FONT_ITALIC) != 0)
1457 gg_append(dst, &len, "</i>", 4); 1484 gg_append(dst, &len, "</i>", 4);
1458 1485
1459 if ((old_attr & GG_FONT_BOLD) != 0) 1486 if ((old_attr & GG_FONT_BOLD) != 0)
1460 gg_append(dst, &len, "</b>", 4); 1487 gg_append(dst, &len, "</b>", 4);
1461 1488
1462 /* Dla pustych tekstów dodaj pusty <span>. */ 1489 if (src[0] != 0)
1463 1490 gg_append(dst, &len, "</span>", 7);
1464 if (i == 0) {
1465 if (dst != NULL)
1466 sprintf(&dst[len], span_fmt, 0, 0, 0);
1467
1468 len += span_len;
1469 }
1470
1471 gg_append(dst, &len, "</span>", 7);
1472 1491
1473 if (dst != NULL) 1492 if (dst != NULL)
1474 dst[len] = 0; 1493 dst[len] = 0;
1475 1494
1476 return len; 1495 return len;
1562 if (format == NULL || formatlen < 3) { 1581 if (format == NULL || formatlen < 3) {
1563 format = (unsigned char*) "\x02\x06\x00\x00\x00\x08\x00\x00\x00"; 1582 format = (unsigned char*) "\x02\x06\x00\x00\x00\x08\x00\x00\x00";
1564 formatlen = 9; 1583 formatlen = 9;
1565 } 1584 }
1566 1585
1567 len = gg_convert_to_html(NULL, utf_msg, format, formatlen); 1586 len = gg_convert_to_html(NULL, utf_msg, format + 3, formatlen - 3);
1568 1587
1569 html_msg = malloc(len + 1); 1588 html_msg = malloc(len + 1);
1570 1589
1571 if (html_msg == NULL) { 1590 if (html_msg == NULL) {
1572 seq_no = -1; 1591 seq_no = -1;
1573 goto cleanup; 1592 goto cleanup;
1574 } 1593 }
1575 1594
1576 gg_convert_to_html(html_msg, utf_msg, format, formatlen); 1595 gg_convert_to_html(html_msg, utf_msg, format + 3, formatlen - 3);
1577 1596
1578 s80.seq = gg_fix32(seq_no); 1597 s80.seq = gg_fix32(seq_no);
1579 s80.msgclass = gg_fix32(msgclass); 1598 s80.msgclass = gg_fix32(msgclass);
1580 s80.offset_plain = gg_fix32(sizeof(s80) + strlen(html_msg) + 1); 1599 s80.offset_plain = gg_fix32(sizeof(s80) + strlen(html_msg) + 1);
1581 s80.offset_attr = gg_fix32(sizeof(s80) + strlen(html_msg) + 1 + strlen(cp_msg) + 1); 1600 s80.offset_attr = gg_fix32(sizeof(s80) + strlen(html_msg) + 1 + strlen(cp_msg) + 1);