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, "&amp;", 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);