Mercurial > pidgin
diff 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 |
line wrap: on
line diff
--- a/libpurple/protocols/gg/lib/libgadu.c Sat Nov 27 22:36:49 2010 +0000 +++ b/libpurple/protocols/gg/lib/libgadu.c Sun Nov 28 00:18:31 2010 +0000 @@ -69,7 +69,7 @@ # include <openssl/rand.h> #endif -#define GG_LIBGADU_VERSION "1.9.0-rc2" +#define GG_LIBGADU_VERSION "1.9.0" /** * Poziom rejestracji informacji odpluskwiających. Zmienna jest maską bitową @@ -180,7 +180,7 @@ #ifdef __GNUC__ __attribute__ ((unused)) #endif -= "$Id: libgadu.c 878 2009-11-16 23:48:19Z wojtekka $"; += "$Id: libgadu.c 923 2010-03-09 20:03:29Z wojtekka $"; #endif #endif /* DOXYGEN */ @@ -1316,41 +1316,65 @@ * \internal Zamienia tekst z formatowaniem Gadu-Gadu na HTML. * * \param dst Bufor wynikowy (może być \c NULL) - * \param utf_msg Tekst źródłowy + * \param src Tekst źródłowy w UTF-8 * \param format Atrybuty tekstu źródłowego * \param format_len Długość bloku atrybutów tekstu źródłowego * + * \note Wynikowy tekst nie jest idealnym kodem HTML, ponieważ ma jak + * dokładniej odzwierciedlać to, co wygenerowałby oryginalny klient. + * * \note Dokleja \c \\0 na końcu bufora wynikowego. * * \return Długość tekstu wynikowego bez \c \\0 (nawet jeśli \c dst to \c NULL). */ -static int gg_convert_to_html(char *dst, const char *utf_msg, const unsigned char *format, int format_len) +static int gg_convert_to_html(char *dst, const char *src, const unsigned char *format, int format_len) { const char span_fmt[] = "<span style=\"color:#%02x%02x%02x; font-family:'MS Shell Dlg 2'; font-size:9pt; \">"; const int span_len = 75; - const char img_fmt[] = "<img src=\"%02x%02x%02x%02x%02x%02x%02x%02x\">"; - const int img_len = 28; + const char img_fmt[] = "<img name=\"%02x%02x%02x%02x%02x%02x%02x%02x\">"; + const int img_len = 29; int char_pos = 0; - int format_idx = 3; + int format_idx = 0; unsigned char old_attr = 0; const unsigned char *color = (const unsigned char*) "\x00\x00\x00"; int len, i; len = 0; - for (i = 0; utf_msg[i] != 0; i++) { - unsigned char attr; - int attr_pos; + /* Nie mamy atrybutów dla pierwsze znaku, a tekst nie jest pusty, więc + * tak czy inaczej trzeba otworzyć <span>. */ + + if (src[0] != 0 && (format_idx + 3 > format_len || (format[format_idx] | (format[format_idx + 1] << 8)) != 0)) { + if (dst != NULL) + sprintf(&dst[len], span_fmt, 0, 0, 0); + + len += span_len; + } + + /* Pętla przechodzi też przez kończące \0, żeby móc dokleić obrazek + * na końcu tekstu. */ - if (format_idx + 3 <= format_len) { + for (i = 0; ; i++) { + /* Analizuj atrybuty tak długo jak dotyczą aktualnego znaku. */ + for (;;) { + unsigned char attr; + int attr_pos; + + if (format_idx + 3 > format_len) + break; + attr_pos = format[format_idx] | (format[format_idx + 1] << 8); + + if (attr_pos != char_pos) + break; + attr = format[format_idx + 2]; - } else { - attr_pos = -1; - attr = 0; - } + + /* Nie doklejaj atrybutów na końcu, co najwyżej obrazki. */ - if (attr_pos == char_pos) { + if (src[i] == 0) + attr &= ~(GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR); + format_idx += 3; if ((attr & (GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR)) != 0) { @@ -1377,7 +1401,7 @@ if (dst != NULL) sprintf(&dst[len], span_fmt, color[0], color[1], color[2]); len += span_len; - } else if (char_pos == 0) { + } else if (char_pos == 0 && src[0] != 0) { if (dst != NULL) sprintf(&dst[len], span_fmt, 0, 0, 0); len += span_len; @@ -1410,14 +1434,11 @@ } old_attr = attr; - } else if (i == 0) { - if (dst != NULL) - sprintf(&dst[len], span_fmt, 0, 0, 0); - - len += span_len; } - switch (utf_msg[i]) { + /* Doklej znak zachowując htmlowe escapowanie. */ + + switch (src[i]) { case '&': gg_append(dst, &len, "&", 5); break; @@ -1437,19 +1458,25 @@ gg_append(dst, &len, "<br>", 4); break; case '\r': + case 0: break; default: if (dst != NULL) - dst[len] = utf_msg[i]; + dst[len] = src[i]; len++; } /* Sprawdź, czy bajt nie jest kontynuacją znaku unikodowego. */ - if ((utf_msg[i] & 0xc0) != 0xc0) + if ((src[i] & 0xc0) != 0xc0) char_pos++; + + if (src[i] == 0) + break; } + /* Zamknij tagi. */ + if ((old_attr & GG_FONT_UNDERLINE) != 0) gg_append(dst, &len, "</u>", 4); @@ -1459,16 +1486,8 @@ if ((old_attr & GG_FONT_BOLD) != 0) gg_append(dst, &len, "</b>", 4); - /* Dla pustych tekstów dodaj pusty <span>. */ - - if (i == 0) { - if (dst != NULL) - sprintf(&dst[len], span_fmt, 0, 0, 0); - - len += span_len; - } - - gg_append(dst, &len, "</span>", 7); + if (src[0] != 0) + gg_append(dst, &len, "</span>", 7); if (dst != NULL) dst[len] = 0; @@ -1564,7 +1583,7 @@ formatlen = 9; } - len = gg_convert_to_html(NULL, utf_msg, format, formatlen); + len = gg_convert_to_html(NULL, utf_msg, format + 3, formatlen - 3); html_msg = malloc(len + 1); @@ -1573,7 +1592,7 @@ goto cleanup; } - gg_convert_to_html(html_msg, utf_msg, format, formatlen); + gg_convert_to_html(html_msg, utf_msg, format + 3, formatlen - 3); s80.seq = gg_fix32(seq_no); s80.msgclass = gg_fix32(msgclass);