qulogic/pidgin

Update internal libgadu to 1.12.0
release-2.x.y
2014-06-16, Tomasz Wasilczyk
0e8bb1df9718
Parents 385126da0582
Children f1c54a78d896
Update internal libgadu to 1.12.0
--- a/ChangeLog Thu May 22 18:35:00 2014 -0500
+++ b/ChangeLog Mon Jun 16 23:01:47 2014 +0200
@@ -13,7 +13,7 @@
* Fix build against Python 3. (Ed Catmur) (#15969)
Gadu-Gadu:
- * Updated internal libgadu to version 1.12.0-rc2.
+ * Updated internal libgadu to version 1.12.0.
IRC:
* Fix a possible leak of unencrypted data when using /me command
--- a/configure.ac Thu May 22 18:35:00 2014 -0500
+++ b/configure.ac Mon Jun 16 23:01:47 2014 +0200
@@ -1035,7 +1035,7 @@
gadu_manual_check="no"
fi
if test "x$gadu_manual_check" = "xno"; then
- PKG_CHECK_MODULES(GADU, [libgadu >= 1.11.0], [
+ PKG_CHECK_MODULES(GADU, [libgadu >= 1.12.0], [
gadu_includes="yes"
gadu_libs="yes"
], [
@@ -1069,7 +1069,7 @@
]])], [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <libgadu.h>]], [[
#if GG_DEFAULT_PROTOCOL_VERSION < 0x2e
-#error "Your libgadu version is too old. libpurple requires 1.11.0 or higher."
+#error "Your libgadu version is too old. libpurple requires 1.12.0 or higher."
#endif
]])], [
AC_MSG_RESULT(yes)
@@ -1080,7 +1080,7 @@
echo
echo
echo "Your supplied copy of libgadu is too old."
- echo "Install version 1.11.0 or newer."
+ echo "Install version 1.12.0 or newer."
echo "Then rerun this ./configure"
echo
echo "Falling back to using our own copy of libgadu"
--- a/libpurple/protocols/gg/lib/config.h Thu May 22 18:35:00 2014 -0500
+++ b/libpurple/protocols/gg/lib/config.h Mon Jun 16 23:01:47 2014 +0200
@@ -5,7 +5,7 @@
/* libpurple's config */
#include <config.h>
-#define GG_LIBGADU_VERSION "1.12.0-rc2"
+#define GG_LIBGADU_VERSION "1.12.0"
/* Defined if libgadu was compiled for bigendian machine. */
#undef GG_CONFIG_BIGENDIAN
@@ -87,3 +87,7 @@
/* Defined if libgadu uses system defalt trusted CAs. */
#define GG_CONFIG_SSL_SYSTEM_TRUST
+
+/* Defined if libgadu is GPL compliant (was not linked with OpenSSL or any
+ other non-GPL compliant library support). */
+#define GG_CONFIG_IS_GPL_COMPLIANT
--- a/libpurple/protocols/gg/lib/dcc7.c Thu May 22 18:35:00 2014 -0500
+++ b/libpurple/protocols/gg/lib/dcc7.c Mon Jun 16 23:01:47 2014 +0200
@@ -1540,7 +1540,7 @@
if (gg_fix32(pkt->magic) != GG_DCC7_RELAY_REPLY ||
gg_fix32(pkt->rcount) < 1 ||
- gg_fix32(pkt->rcount > 256) ||
+ gg_fix32(pkt->rcount) > 256 ||
gg_fix32(pkt->len) < sizeof(*pkt) +
gg_fix32(pkt->rcount) * sizeof(srv))
{
--- a/libpurple/protocols/gg/lib/fileio.h Thu May 22 18:35:00 2014 -0500
+++ b/libpurple/protocols/gg/lib/fileio.h Mon Jun 16 23:01:47 2014 +0200
@@ -34,11 +34,17 @@
#ifdef _WIN32
# include <io.h>
# define gg_file_close _close
+# undef lseek
# define lseek _lseek
+# undef open
# define open _open
+# undef read
# define read _read
+# undef stat
# define stat _stat
+# undef fstat
# define fstat _fstat
+# undef write
# define write _write
# define S_IRWXO 0
# define S_IRWXG 0
--- a/libpurple/protocols/gg/lib/handlers.c Thu May 22 18:35:00 2014 -0500
+++ b/libpurple/protocols/gg/lib/handlers.c Mon Jun 16 23:01:47 2014 +0200
@@ -405,6 +405,7 @@
static int gg_session_handle_send_msg_ack(struct gg_session *gs, uint32_t type,
const char *ptr, size_t len, struct gg_event *ge)
{
+ struct gg_session_private *p = gs->private_data;
const struct gg_send_msg_ack *s = (const struct gg_send_msg_ack*) ptr;
gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a message ack\n");
@@ -414,6 +415,10 @@
ge->event.ack.recipient = gg_fix32(s->recipient);
ge->event.ack.seq = gg_fix32(s->seq);
+ if (ge->event.ack.seq == 0 && p->imgout_waiting_ack > 0)
+ p->imgout_waiting_ack--;
+ gg_image_sendout(gs);
+
return 0;
}
@@ -423,6 +428,7 @@
static int gg_session_handle_send_msg_ack_110(struct gg_session *gs,
uint32_t type, const char *ptr, size_t len, struct gg_event *ge)
{
+ struct gg_session_private *p = gs->private_data;
GG110MessageAck *msg = gg110_message_ack__unpack(NULL, len, (uint8_t*)ptr);
size_t i;
@@ -435,11 +441,11 @@
*/
gg_debug_session(gs, GG_DEBUG_MISC | GG_DEBUG_WARNING,
"// gg_session_handle_send_msg_ack_110() magic dummy1 "
- "value 0x4000");
+ "value 0x4000\n");
} else if (msg->dummy1 != 0) {
gg_debug_session(gs, GG_DEBUG_MISC | GG_DEBUG_WARNING,
"// gg_session_handle_send_msg_ack_110() unknown dummy1 "
- "value: %x", msg->dummy1);
+ "value: %x\n", msg->dummy1);
}
gg_debug_session(gs, GG_DEBUG_VERBOSE,
@@ -466,6 +472,10 @@
gg110_message_ack__free_unpacked(msg, NULL);
+ if (msg->seq == 0 && p->imgout_waiting_ack > 0)
+ p->imgout_waiting_ack--;
+ gg_image_sendout(gs);
+
return 0;
}
@@ -1388,13 +1398,13 @@
if (msg->data.len < sizeof(struct gg_msg_image_reply)) {
gg_debug_session(gs, GG_DEBUG_ERROR,
"// gg_session_handle_recv_msg_110() "
- "packet too small\n");
- return -1;
+ "packet too small (%" GG_SIZE_FMT " < %"
+ GG_SIZE_FMT ")\n", msg->data.len,
+ sizeof(struct gg_msg_image_reply));
+ } else {
+ gg_image_queue_parse(ge, (char *)msg->data.data,
+ msg->data.len, gs, sender, type);
}
-
- gg_image_queue_parse(ge, (char *)msg->data.data, msg->data.len,
- gs, sender, type);
-
gg110_recv_message__free_unpacked(msg, NULL);
return gg_ack_110(gs, GG110_ACK__TYPE__MSG, seq, ge);
}
--- a/libpurple/protocols/gg/lib/internal.h Thu May 22 18:35:00 2014 -0500
+++ b/libpurple/protocols/gg/lib/internal.h Mon Jun 16 23:01:47 2014 +0200
@@ -27,8 +27,16 @@
#define GG_DEFAULT_CLIENT_VERSION_110 "11.3.45.10771"
#ifdef _WIN32
-# define GG_SIZE_FMT "Iu"
-# define _GG_INT64_MODIFIER "I64"
+# ifdef __COVERITY__
+# define GG_SIZE_FMT "lu"
+# define _GG_INT64_MODIFIER "ll"
+# undef PRIu64
+# undef PRIx64
+# undef PRId64
+# else
+# define GG_SIZE_FMT "Iu"
+# define _GG_INT64_MODIFIER "I64"
+# endif
#elif defined(_LP64)
# define GG_SIZE_FMT "zu"
# define _GG_INT64_MODIFIER "l"
@@ -66,6 +74,8 @@
[(condition) ? 1 : -1]; static_assertion_failed_ ## message dummy; \
(void)dummy; }
+#define GG_IMGOUT_WAITING_MAX 4
+
struct gg_dcc7_relay {
uint32_t addr;
uint16_t port;
@@ -98,6 +108,15 @@
gg_eventqueue_t *next;
};
+typedef struct _gg_imgout_queue_t gg_imgout_queue_t;
+struct _gg_imgout_queue_t {
+ struct gg_send_msg msg_hdr;
+ char buf[1910];
+ size_t buf_len;
+
+ gg_imgout_queue_t *next;
+};
+
struct gg_session_private {
gg_compat_t compatibility;
@@ -108,6 +127,9 @@
int check_after_queue;
int fd_after_queue;
+ gg_imgout_queue_t *imgout_queue;
+ int imgout_waiting_ack;
+
gg_socket_manager_type_t socket_manager_type;
gg_socket_manager_t socket_manager;
void *socket_handle;
@@ -164,6 +186,8 @@
void gg_compat_message_ack(struct gg_session *sess, int seq);
+void gg_image_sendout(struct gg_session *sess);
+
void gg_strarr_free(char **strarr);
char ** gg_strarr_dup(char **strarr);
--- a/libpurple/protocols/gg/lib/libgadu.c Thu May 22 18:35:00 2014 -0500
+++ b/libpurple/protocols/gg/lib/libgadu.c Mon Jun 16 23:01:47 2014 +0200
@@ -530,6 +530,12 @@
p->event_queue = next;
}
+ while (p->imgout_queue) {
+ gg_imgout_queue_t *next = p->imgout_queue->next;
+ free(p->imgout_queue);
+ p->imgout_queue = next;
+ }
+
if (p->dummyfds_created) {
close(p->dummyfds[0]);
close(p->dummyfds[1]);
@@ -985,7 +991,8 @@
} else
sess->protocol_version = p->protocol_version;
- sess->client_version = (p->client_version) ? strdup(p->client_version) : NULL;
+ if (p->client_version && strcmp(p->client_version, "-") != 0)
+ sess->client_version = strdup(p->client_version);
sess->last_sysmsg = p->last_sysmsg;
sess->image_size = p->image_size;
sess->pid = -1;
@@ -1510,6 +1517,32 @@
return succ ? seq : -1;
}
+static char *
+gg_message_legacy_text_to_html(const char *src, gg_encoding_t encoding,
+ const unsigned char *format, size_t format_len)
+{
+ size_t len;
+ char *dst;
+
+ if (format == NULL || format_len <= 3) {
+ format = NULL;
+ format_len = 0;
+ } else {
+ format += 3;
+ format_len -= 3;
+ }
+
+ len = gg_message_text_to_html(NULL, src, encoding, format, format_len);
+
+ dst = malloc(len + 1);
+ if (dst == NULL)
+ return NULL;
+
+ gg_message_text_to_html(dst, src, encoding, format, format_len);
+
+ return dst;
+}
+
/**
* \internal Wysyła wiadomość.
*
@@ -1567,6 +1600,21 @@
recipients_count == 1)
{
int is_html = (html_message != NULL);
+ char *formatted_msg = NULL;
+
+ if (formatlen > 3 && !is_html) {
+ gg_debug_session(sess, GG_DEBUG_MISC | GG_DEBUG_WARNING,
+ "// gg_send_message_common() using legacy "
+ "formatting with new protocol\n");
+ formatted_msg = gg_message_legacy_text_to_html(
+ (const char *)message, sess->encoding,
+ format, formatlen);
+ if (formatted_msg == NULL)
+ goto cleanup;
+ html_message = (unsigned char*)formatted_msg;
+ is_html = 1;
+ }
+
seq_no = gg_send_message_110(sess, recipients[0], 0,
(const char*)(is_html ? html_message : message),
is_html);
@@ -1617,7 +1665,7 @@
formatlen = 0;
}
- if (sess->encoding == GG_ENCODING_UTF8) {
+ if (sess->encoding != GG_ENCODING_CP1250) {
cp_msg = recoded_msg = gg_encoding_convert(tmp_msg, sess->encoding, GG_ENCODING_CP1250, -1, -1);
free(tmp_msg);
@@ -1627,7 +1675,7 @@
cp_msg = recoded_msg = tmp_msg;
}
} else {
- if (sess->encoding == GG_ENCODING_UTF8) {
+ if (sess->encoding != GG_ENCODING_CP1250) {
cp_msg = recoded_msg = gg_encoding_convert(
(const char*)message, sess->encoding,
GG_ENCODING_CP1250, -1, -1);
@@ -1640,38 +1688,24 @@
}
if (html_message == NULL) {
- size_t len;
- char *tmp;
- const char *utf_msg;
- const unsigned char *format_ = NULL;
- size_t formatlen_ = 0;
+ char *formatted_msg;
+
+ formatted_msg = gg_message_legacy_text_to_html(
+ (const char*)message, sess->encoding, format, formatlen);
+ if (formatted_msg == NULL)
+ goto cleanup;
if (sess->encoding == GG_ENCODING_UTF8) {
- utf_msg = (const char*) message;
+ utf_html_msg = recoded_html_msg = formatted_msg;
} else {
- utf_msg = recoded_msg = gg_encoding_convert(
- (const char*)message, sess->encoding,
+ utf_html_msg = recoded_html_msg = gg_encoding_convert(
+ formatted_msg, sess->encoding,
GG_ENCODING_UTF8, -1, -1);
-
- if (utf_msg == NULL)
+ free(formatted_msg);
+
+ if (utf_html_msg == NULL)
goto cleanup;
}
-
- if (format != NULL && formatlen >= 3) {
- format_ = format + 3;
- formatlen_ = formatlen - 3;
- }
-
- len = gg_message_text_to_html(NULL, utf_msg, GG_ENCODING_UTF8, format_, formatlen_);
-
- tmp = malloc(len + 1);
-
- if (tmp == NULL)
- goto cleanup;
-
- gg_message_text_to_html(tmp, utf_msg, GG_ENCODING_UTF8, format_, formatlen_);
-
- utf_html_msg = recoded_html_msg = tmp;
} else {
if (sess->encoding == GG_ENCODING_UTF8) {
utf_html_msg = (const char*) html_message;
@@ -1783,6 +1817,17 @@
gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_message(%p, %d, "
"%u, %p)\n", sess, msgclass, recipient, message);
+ if (sess->protocol_version >= GG_PROTOCOL_VERSION_110) {
+ int seq_no;
+
+ seq_no = gg_send_message_110(sess, recipient, 0, (const char*)message, 0);
+
+ if (seq_no >= 0)
+ gg_compat_message_sent(sess, seq_no, 1, &recipient);
+
+ return seq_no;
+ }
+
return gg_send_message_common(sess, msgclass, 1, &recipient, message,
(const unsigned char*)"\x02\x06\x00\x00\x00\x08\x00\x00\x00",
9, NULL);
@@ -2073,11 +2118,13 @@
*/
int gg_image_reply(struct gg_session *sess, uin_t recipient, const char *filename, const char *image, int size)
{
+ struct gg_session_private *p;
struct gg_msg_image_reply *r;
struct gg_send_msg s;
const char *tmp;
char buf[1910];
int res = -1;
+ gg_imgout_queue_t *queue = NULL, *queue_end = NULL;
gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_image_reply(%p, %d, "
"\"%s\", %p, %d);\n", sess, recipient, filename, image, size);
@@ -2087,6 +2134,8 @@
return -1;
}
+ p = sess->private_data;
+
if (sess->state != GG_STATE_CONNECTED) {
errno = ENOTCONN;
return -1;
@@ -2118,6 +2167,7 @@
r->crc32 = gg_fix32(gg_crc32(0, (const unsigned char*) image, size));
while (size > 0) {
+ gg_imgout_queue_t *it;
size_t buflen, chunklen;
/* \0 + struct gg_msg_image_reply */
@@ -2135,15 +2185,57 @@
size -= chunklen;
image += chunklen;
- res = gg_send_packet(sess, GG_SEND_MSG, &s, sizeof(s), buf, buflen + chunklen, NULL);
+ it = gg_new0(sizeof(gg_imgout_queue_t));
+ if (!it)
+ break;
+ if (queue_end) {
+ queue_end->next = it;
+ queue_end = it;
+ } else {
+ queue = queue_end = it;
+ }
+
+ memcpy(&it->msg_hdr, &s, sizeof(s));
+ memcpy(it->buf, buf, buflen + chunklen);
+ it->buf_len = buflen + chunklen;
+
+ r->flag = GG_MSG_OPTION_IMAGE_REPLY_MORE;
+ }
+
+ if (p->imgout_queue) {
+ queue_end = p->imgout_queue;
+ while (queue_end->next)
+ queue_end = queue_end->next;
+ queue_end->next = queue;
+ } else {
+ p->imgout_queue = queue;
+ }
+ gg_image_sendout(sess);
+
+ return res;
+}
+
+void gg_image_sendout(struct gg_session *sess)
+{
+ struct gg_session_private *p = sess->private_data;
+
+ while (p->imgout_waiting_ack < GG_IMGOUT_WAITING_MAX && p->imgout_queue) {
+ gg_imgout_queue_t *it = p->imgout_queue;
+ int res;
+
+ p->imgout_queue = p->imgout_queue->next;
+ p->imgout_waiting_ack++;
+
+ res = gg_send_packet(sess, GG_SEND_MSG,
+ &it->msg_hdr, sizeof(it->msg_hdr),
+ it->buf, it->buf_len,
+ NULL);
+
+ free(it);
if (res == -1)
break;
-
- r->flag = GG_MSG_OPTION_IMAGE_REPLY_MORE;
}
-
- return res;
}
static int gg_notify105_ex(struct gg_session *sess, uin_t *userlist, char *types, int count)
--- a/libpurple/protocols/gg/lib/libgadu.h Thu May 22 18:35:00 2014 -0500
+++ b/libpurple/protocols/gg/lib/libgadu.h Mon Jun 16 23:01:47 2014 +0200
@@ -1822,7 +1822,7 @@
#define GG_PROTOCOL_VERSION_110 0x40
/* GG_DEPRECATED */
-#define GG_DEFAULT_CLIENT_VERSION NULL
+#define GG_DEFAULT_CLIENT_VERSION "-"
#define GG_DEFAULT_PROTOCOL_VERSION GG_PROTOCOL_VERSION_110
#define GG_DEFAULT_TIMEOUT 30
--- a/libpurple/protocols/gg/lib/resolver.c Thu May 22 18:35:00 2014 -0500
+++ b/libpurple/protocols/gg/lib/resolver.c Mon Jun 16 23:01:47 2014 +0200
@@ -59,9 +59,13 @@
* \internal Funkcja pomocnicza zwalniająca zasoby po rozwiązywaniu nazwy
* w wątku.
*
+ * \note Funkcja nie powinna być statyczna, ponieważ zostanie potraktowana
+ * jako inline i kompilator może "zoptymalizować" jej wywołanie w funkcji
+ * pthread_cleanup_pop().
+ *
* \param data Wskaźnik na wskaźnik bufora zaalokowanego w wątku
*/
-static void gg_resolver_cleaner(void *data)
+void gg_resolver_cleaner(void *data)
{
void **buf_ptr = (void **) data;
--- a/libpurple/protocols/gg/lib/resolver.h Thu May 22 18:35:00 2014 -0500
+++ b/libpurple/protocols/gg/lib/resolver.h Mon Jun 16 23:01:47 2014 +0200
@@ -23,5 +23,6 @@
int gg_gethostbyname_real(const char *hostname, struct in_addr **result, unsigned int *count, int pthread);
int gg_resolver_recv(int fd, void *buf, size_t len);
+void gg_resolver_cleaner(void *data);
#endif /* LIBGADU_RESOLVER_H */