diff -Nru libgadu-1.12.1/autoclean.sh libgadu-1.12.2/autoclean.sh --- libgadu-1.12.1/autoclean.sh 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/autoclean.sh 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,4 @@ #!/bin/sh -# $Id$ rm -rf \ aclocal.m4 \ diff -Nru libgadu-1.12.1/autogen.sh libgadu-1.12.2/autogen.sh --- libgadu-1.12.1/autogen.sh 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/autogen.sh 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,4 @@ #!/bin/sh -# $Id$ echo protobuf && ./protobufgen.sh || exit 1 echo aclocal && aclocal -I m4 || exit 1 diff -Nru libgadu-1.12.1/configure.ac libgadu-1.12.2/configure.ac --- libgadu-1.12.1/configure.ac 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/configure.ac 2017-01-21 17:57:03.000000000 +0000 @@ -1,6 +1,4 @@ -dnl $Id$ - -AC_INIT([libgadu], [1.12.1]) +AC_INIT([libgadu], [1.12.2]) AC_CONFIG_SRCDIR([src/libgadu.c]) AM_INIT_AUTOMAKE() @@ -64,6 +62,8 @@ AC_SUBST([MINGW_LIBDATA]) AC_SUBST([LDFLAGS_NO_INSTALL]) +AC_CHECK_FUNCS([mkstemp]) + AC_C_BIGENDIAN if test "x$ac_cv_c_bigendian" = "xyes"; then @@ -267,9 +267,15 @@ if test "x$with_protobuf" != "xno"; then PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c >= 1.0.0], [ - LIBS_PRIVATE="$LIBS_PRIVATE $PROTOBUF_C_LIBS" - AC_DEFINE([GG_CONFIG_HAVE_PROTOBUF_C], [], [Defined if libgadu was compiled and linked with system provided libprotobuf-c.]) - have_protobuf_c=yes + protobufc_ver=`$PKG_CONFIG --modversion libprotobuf-c` + if test "x$protobufc_ver" = "x1.0.0-rc1"; then + echo "WARNING: libprotobuf-c $protobufc_ver found. It's not compatible with 1.0.0 API" + have_protobuf_c=no + else + LIBS_PRIVATE="$LIBS_PRIVATE $PROTOBUF_C_LIBS" + AC_DEFINE([GG_CONFIG_HAVE_PROTOBUF_C], [], [Defined if libgadu was compiled and linked with system provided libprotobuf-c.]) + have_protobuf_c=yes + fi ], [have_protobuf_c=no]) else have_protobuf_c=no @@ -296,6 +302,9 @@ LIBS="$LIBS $GNUTLS_LIBS" have_gnutls="yes" ], [:]) + PKG_CHECK_MODULES([GNUTLS_2_12], [gnutls >= 2.12.0], [ + AC_DEFINE([HAVE_GNUTLS_2_12], [], [Defined if GnuTLS >= 2.12.0 is available.]) + ], [:]) fi dnl @@ -412,7 +421,7 @@ dnl Sprawdź, czy mamy libxml2 do testów automatycznych dnl - PKG_CHECK_MODULES([LIBXML2], [libxml-2.0], [ + PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.2.3], [ have_libxml2="yes" AC_DEFINE([HAVE_LIBXML2], [], [Defined if libxml2 is available.]) ], [ @@ -421,10 +430,13 @@ fi AM_CONDITIONAL([HAVE_GLIBC], [test "x$have_glibc" = "xyes"]) -AM_CONDITIONAL([HAVE_GNUTLS_TESTS], [test "x$have_gnutls" = "xyes"]) AM_CONDITIONAL([HAVE_CURL_AND_EXPAT], [test "x$have_curl" = "xyes" -a "x$have_expat" = "xyes"]) AM_CONDITIONAL([HAVE_PERL], [test "x$have_perl" = "xyes"]) +AM_CONDITIONAL([BUILD_CONNECT_TEST], [test \( "x$have_glibc" = "xyes" -a \ + "x$have_gnutls" = "xyes" -a "x$have_pthread" = "xyes" \) -o \ + "x$is_mingw" = "xyes"]) + dnl dnl Sprawdź, czy mamy czym generować dokumentację dnl @@ -442,6 +454,18 @@ have_doxygen="no" fi +dnl +dnl Ostrzeżenia kompilatora +dnl + +AC_ARG_ENABLE(werror, + [ --enable-werror halt on warnings]) + +if test "x$enable_werror" == "xyes"; then + CFLAGS="$CFLAGS -Werror" +fi + + AC_CONFIG_FILES([Makefile src/Makefile include/Makefile pkgconfig/Makefile pkgconfig/libgadu.pc docs/Makefile docs/Doxyfile examples/Makefile]) AM_COND_IF([ENABLE_TESTS], diff -Nru libgadu-1.12.1/debian/changelog libgadu-1.12.2/debian/changelog --- libgadu-1.12.1/debian/changelog 2017-02-03 15:28:08.000000000 +0000 +++ libgadu-1.12.2/debian/changelog 2017-06-18 14:25:48.000000000 +0000 @@ -1,3 +1,18 @@ +libgadu (1:1.12.2-2) unstable; urgency=medium + + * QA upload. + * Upload to unstable. + + -- Adrian Bunk Sun, 18 Jun 2017 17:25:48 +0300 + +libgadu (1:1.12.2-1) experimental; urgency=low + + * New upstream release + * Bumped Standards-Version (no changes needed) + * Orphaned the package + + -- Marcin Owsiany Tue, 14 Feb 2017 20:29:44 +0100 + libgadu (1:1.12.1-4) unstable; urgency=high * Cherry-pick a fix for TLS connections broken due to an incompatible diff -Nru libgadu-1.12.1/debian/control libgadu-1.12.2/debian/control --- libgadu-1.12.1/debian/control 2015-01-13 20:24:00.000000000 +0000 +++ libgadu-1.12.2/debian/control 2017-02-14 19:29:44.000000000 +0000 @@ -1,7 +1,7 @@ Source: libgadu Section: libs Priority: optional -Maintainer: Marcin Owsiany +Maintainer: Debian QA Group Build-Depends: # debianization tools debhelper (>= 9~), dpkg-dev (>= 1.16.1~), dh-autoreconf, @@ -16,7 +16,7 @@ # documentation building doxygen Build-Conflicts: autoconf2.13, automake1.4 -Standards-Version: 3.9.6 +Standards-Version: 3.9.8 Homepage: http://toxygen.net/libgadu/ Vcs-Git: git://github.com/porridge/libgadu.git -b debian-1.12 Vcs-Browser: https://github.com/porridge/libgadu diff -Nru libgadu-1.12.1/debian/patches/fix-TLS-connections libgadu-1.12.2/debian/patches/fix-TLS-connections --- libgadu-1.12.1/debian/patches/fix-TLS-connections 2017-02-03 15:28:08.000000000 +0000 +++ libgadu-1.12.2/debian/patches/fix-TLS-connections 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -Description: fix TLS connections - Cherry-pick a fix for TLS connections broken due to an incompatible - server-side change. (Closes: #853928) -Author: Marcin Owsiany -Bug-Debian: http://bugs.debian.org/853928 -Origin: upstream, https://github.com/wojtekka/libgadu/commit/cf07f39da1d69c7219be928e3afcedbdd3c0f49c - ---- libgadu-1.12.1.orig/src/events.c -+++ libgadu-1.12.1/src/events.c -@@ -898,7 +898,7 @@ static gg_action_t gg_handle_send_hub(st - - if (sess->ssl_flag != GG_SSL_DISABLED) { - req = gg_saprintf -- ("GET %s/appsvc/appmsg_ver10.asp?fmnumber=%u&fmt=2&" -+ ("GET %s/appsvc/appmsg_ver11.asp?tls=1&fmnumber=%u&fmt=2&" - "lastmsg=%d&version=%s&age=2&gender=1 HTTP/1.0\r\n" - "Connection: close\r\n" - "Host: " GG_APPMSG_HOST "\r\n" diff -Nru libgadu-1.12.1/debian/patches/series libgadu-1.12.2/debian/patches/series --- libgadu-1.12.1/debian/patches/series 2017-02-03 15:28:08.000000000 +0000 +++ libgadu-1.12.2/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -fix-TLS-connections diff -Nru libgadu-1.12.1/declspec.sh libgadu-1.12.2/declspec.sh --- libgadu-1.12.1/declspec.sh 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/declspec.sh 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,4 @@ #!/bin/sh -# $Id$ # this script if for converting libgadu.h file to be used with MSVC diff -Nru libgadu-1.12.1/docs/changelog.dox libgadu-1.12.2/docs/changelog.dox --- libgadu-1.12.1/docs/changelog.dox 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/docs/changelog.dox 2017-01-21 17:57:03.000000000 +0000 @@ -9,6 +9,10 @@ przypadków nie mają wpływ na interfejs binarny biblioteki. Nowe funkcje, stałe i pola struktur nie zmieniają dotychczasowego zachowania. +\section changelog-1_12_2 libgadu 1.12.2 + +- Brak zmian API/ABI. + \section changelog-1_12_1 libgadu 1.12.1 - Brak zmian API/ABI. diff -Nru libgadu-1.12.1/docs/protocol.html libgadu-1.12.2/docs/protocol.html --- libgadu-1.12.1/docs/protocol.html 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/docs/protocol.html 2017-01-21 17:57:03.000000000 +0000 @@ -2431,12 +2431,6 @@
  • Maciej Muszkowski (maciek.muszkowski%gmail.com): Poprawiony opis połączeń bezpośrednich/relay w GG 8.x/10.x
  • -
    - - - diff -Nru libgadu-1.12.1/examples/register.c libgadu-1.12.2/examples/register.c --- libgadu-1.12.1/examples/register.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/examples/register.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2006 Wojtek Kaniewski * diff -Nru libgadu-1.12.1/examples/remind.c libgadu-1.12.2/examples/remind.c --- libgadu-1.12.1/examples/remind.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/examples/remind.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2006 Wojtek Kaniewski * diff -Nru libgadu-1.12.1/.gitignore libgadu-1.12.2/.gitignore --- libgadu-1.12.1/.gitignore 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/.gitignore 2017-01-21 17:57:03.000000000 +0000 @@ -55,6 +55,7 @@ test/automatic/protocol test/automatic/resolver test/automatic/script.c +test/automatic/skipped.c test/automatic/libgadu-*.c test/automatic/*-valgrind test/manual/client diff -Nru libgadu-1.12.1/include/deflate.h libgadu-1.12.2/include/deflate.h --- libgadu-1.12.1/include/deflate.h 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/include/deflate.h 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2011 Bartosz Brachaczek * diff -Nru libgadu-1.12.1/include/fileio.h libgadu-1.12.2/include/fileio.h --- libgadu-1.12.1/include/fileio.h 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/include/fileio.h 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2011 Bartosz Brachaczek * @@ -27,6 +25,10 @@ #ifndef LIBGADU_FILEIO_H #define LIBGADU_FILEIO_H +#ifdef LIBGADU_NETWORK_H +# error "Always include fileio.h before network.h" +#endif + #include #include #include @@ -46,8 +48,12 @@ # define fstat _fstat # undef write # define write _write -# define S_IRWXO 0 -# define S_IRWXG 0 +# ifndef S_IRWXO +# define S_IRWXO 0 +# endif +# ifndef S_IRWXG +# define S_IRWXG 0 +# endif #else # ifdef sun # include diff -Nru libgadu-1.12.1/include/internal.h libgadu-1.12.2/include/internal.h --- libgadu-1.12.1/include/internal.h 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/include/internal.h 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2009 Jakub Zawadzki * @@ -21,6 +19,24 @@ #ifndef LIBGADU_INTERNAL_H #define LIBGADU_INTERNAL_H +#if defined(LIBGADU_DEBUG_H) || \ + defined(LIBGADU_DEFLATE_H) || \ + defined(LIBGADU_ENCODING_H) || \ + defined(LIBGADU_FILEIO_H) || \ + defined(LIBGADU_LIBGADU_H) || \ + defined(LIBGADU_MESSAGE_H) || \ + defined(LIBGADU_NETWORK_H) || \ + defined(LIBGADU_PROTOBUF_H) || \ + defined(LIBGADU_PROTOCOL_H) || \ + defined(LIBGADU_RESOLVER_H) || \ + defined(LIBGADU_SESSION_H) || \ + defined(LIBGADU_STRMAN_H) || \ + defined(LIBGADU_TVBUFF_H) || \ + defined(LIBGADU_TVBUILDER_H) +# error "internal.h must be included first" +#endif + +#include "config.h" #include "libgadu.h" #define GG_DEFAULT_CLIENT_VERSION_100 "10.1.0.11070" @@ -59,12 +75,14 @@ (offsetof(struct gg_login_params, member) < (glp)->struct_size || \ offsetof(struct gg_login_params, member) <= offsetof(struct gg_login_params, struct_size)) +#ifdef _MSC_VER +# define inline __inline +#endif + #ifdef __GNUC__ -# define GG_UNUSED __attribute__ ((unused)) # define GG_NORETURN __attribute__ ((noreturn)) # define GG_CDECL __attribute__ ((__cdecl__)) #else -# define GG_UNUSED # define GG_NORETURN # define GG_CDECL #endif @@ -191,8 +209,11 @@ void gg_strarr_free(char **strarr); char ** gg_strarr_dup(char **strarr); +int gg_rand(void *buff, size_t len); + #ifdef _WIN32 +#include #include typedef struct { diff -Nru libgadu-1.12.1/include/libgadu.h.in libgadu-1.12.2/include/libgadu.h.in --- libgadu-1.12.1/include/libgadu.h.in 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/include/libgadu.h.in 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2009 Wojtek Kaniewski * Robert J. Woźny @@ -33,10 +31,6 @@ #ifndef LIBGADU_LIBGADU_H #define LIBGADU_LIBGADU_H -#ifdef _WIN32 -#pragma pack(push, 1) -#endif - #ifdef __cplusplus extern "C" { #endif @@ -153,6 +147,10 @@ # define GG_GNUC_PRINTF(format_idx, arg_idx) #endif +#ifdef _WIN32 +#pragma pack(push, 1) +#endif + /** \endcond */ /** @@ -2616,14 +2614,14 @@ #define GG_CHAT_INFO_UPDATE_ENTERED 0x01 #define GG_CHAT_INFO_UPDATE_EXITED 0x03 -#ifdef __cplusplus -} -#endif - #ifdef _WIN32 #pragma pack(pop) #endif +#ifdef __cplusplus +} +#endif + #endif /* LIBGADU_LIBGADU_H */ /* diff -Nru libgadu-1.12.1/include/network.h libgadu-1.12.2/include/network.h --- libgadu-1.12.1/include/network.h 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/include/network.h 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2002 Wojtek Kaniewski * Robert J. Woźny @@ -30,7 +28,6 @@ #ifdef _WIN32 # include -# include # include # include # include diff -Nru libgadu-1.12.1/include/protobuf-c.h libgadu-1.12.2/include/protobuf-c.h --- libgadu-1.12.1/include/protobuf-c.h 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/include/protobuf-c.h 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2014, Dave Benson and the protobuf-c authors. + * Copyright (c) 2008-2016, Dave Benson and the protobuf-c authors. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -106,9 +106,25 @@ * sufficient to allow them to be cast to `ProtobufCMessage`. * * For each message defined in a `.proto` file, we generate a number of - * functions. Each function name contains a prefix based on the package name and - * message name in order to make it a unique C identifier. + * functions and macros. Each function name contains a prefix based on the + * package name and message name in order to make it a unique C identifier. * + * - `INIT`. Statically initializes a message object, initializing its + * descriptor and setting its fields to default values. Uninitialized + * messages cannot be processed by the protobuf-c library. + * +~~~{.c} +#define FOO__BAR__BAZ_BAH__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&foo__bar__baz_bah__descriptor), 0 } +~~~ + * - `init()`. Initializes a message object, initializing its descriptor and + * setting its fields to default values. Uninitialized messages cannot be + * processed by the protobuf-c library. + * +~~~{.c} +void foo__bar__baz_bah__init + (Foo__Bar__BazBah *message); +~~~ * - `unpack()`. Unpacks data for a particular message format. Note that the * `allocator` parameter is usually `NULL` to indicate that the system's * `malloc()` and `free()` functions should be used for dynamically allocating @@ -239,6 +255,9 @@ /** Set if the field is marked with the `deprecated` option. */ PROTOBUF_C_FIELD_FLAG_DEPRECATED = (1 << 1), + + /** Set if the field is a member of a oneof (union). */ + PROTOBUF_C_FIELD_FLAG_ONEOF = (1 << 2), } ProtobufCFieldFlag; /** @@ -545,7 +564,7 @@ /** * The offset in bytes of the message's C structure's quantifier field * (the `has_MEMBER` field for optional members or the `n_MEMBER` field - * for repeated members. + * for repeated members or the case enum for oneofs). */ unsigned quantifier_offset; @@ -762,13 +781,13 @@ * The version of the protobuf-c headers, represented as a string using the same * format as protobuf_c_version(). */ -#define PROTOBUF_C_VERSION "1.0.2" +#define PROTOBUF_C_VERSION "1.2.1" /** * The version of the protobuf-c headers, represented as an integer using the * same format as protobuf_c_version_number(). */ -#define PROTOBUF_C_VERSION_NUMBER 1000002 +#define PROTOBUF_C_VERSION_NUMBER 1002001 /** * The minimum protoc-c version which works with the current version of the @@ -787,7 +806,7 @@ * \return * A `ProtobufCEnumValue` object. * \retval NULL - * If not found. + * If not found or if the optimize_for = CODE_SIZE option was set. */ PROTOBUF_C__API const ProtobufCEnumValue * @@ -827,7 +846,7 @@ * \return * A `ProtobufCFieldDescriptor` object. * \retval NULL - * If not found. + * If not found or if the optimize_for = CODE_SIZE option was set. */ PROTOBUF_C__API const ProtobufCFieldDescriptor * @@ -1001,7 +1020,7 @@ * \return * A `ProtobufCMethodDescriptor` object. * \retval NULL - * If not found. + * If not found or if the optimize_for = CODE_SIZE option was set. */ PROTOBUF_C__API const ProtobufCMethodDescriptor * diff -Nru libgadu-1.12.1/include/protobuf.h libgadu-1.12.2/include/protobuf.h --- libgadu-1.12.1/include/protobuf.h 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/include/protobuf.h 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2012 Tomek Wasilczyk * @@ -18,6 +16,8 @@ * USA. */ +#include "internal.h" + #ifndef LIBGADU_PROTOBUF_H #define LIBGADU_PROTOBUF_H @@ -25,14 +25,12 @@ #include #include -#include "config.h" #ifdef GG_CONFIG_HAVE_PROTOBUF_C #include #else #include "protobuf-c.h" #endif -#include "internal.h" #include "fileio.h" typedef size_t (*gg_protobuf_size_cb_t)(const void *message); diff -Nru libgadu-1.12.1/include/protocol.h libgadu-1.12.2/include/protocol.h --- libgadu-1.12.1/include/protocol.h 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/include/protocol.h 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2009-2010 Jakub Zawadzki * Bartłomiej Zimoń diff -Nru libgadu-1.12.1/include/session.h libgadu-1.12.2/include/session.h --- libgadu-1.12.1/include/session.h 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/include/session.h 2017-01-21 17:57:03.000000000 +0000 @@ -48,8 +48,11 @@ #ifdef GG_CONFIG_HAVE_GNUTLS typedef struct { + int global_init_called; gnutls_session_t session; + int session_ready; gnutls_certificate_credentials_t xcred; + int xcred_ready; } gg_session_gnutls_t; #define GG_SESSION_GNUTLS(gs) ((gg_session_gnutls_t*) (gs)->ssl)->session diff -Nru libgadu-1.12.1/include/strman.h libgadu-1.12.2/include/strman.h --- libgadu-1.12.1/include/strman.h 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/include/strman.h 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2011 Bartosz Brachaczek * diff -Nru libgadu-1.12.1/include/tvbuff.h libgadu-1.12.2/include/tvbuff.h --- libgadu-1.12.1/include/tvbuff.h 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/include/tvbuff.h 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2012 Tomek Wasilczyk * diff -Nru libgadu-1.12.1/include/tvbuilder.h libgadu-1.12.2/include/tvbuilder.h --- libgadu-1.12.1/include/tvbuilder.h 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/include/tvbuilder.h 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2012 Tomek Wasilczyk * diff -Nru libgadu-1.12.1/m4/openssl.m4 libgadu-1.12.2/m4/openssl.m4 --- libgadu-1.12.1/m4/openssl.m4 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/m4/openssl.m4 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,4 @@ -dnl based on curses.m4 -dnl $Id$ +dnl based on curses.m4 AC_DEFUN([AC_CHECK_OPENSSL],[ AC_SUBST(OPENSSL_LIBS) diff -Nru libgadu-1.12.1/m4/stdint.m4 libgadu-1.12.2/m4/stdint.m4 --- libgadu-1.12.1/m4/stdint.m4 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/m4/stdint.m4 2017-01-21 17:57:03.000000000 +0000 @@ -1,8 +1,6 @@ dnl Based on AC_NEED_STDINT_H by Guido Draheim that can be dnl found at http://www.gnu.org/software/ac-archive/. Do not complain him dnl about this macro. -dnl -dnl $Id$ AC_DEFUN([AC_NEED_STDINT_H], [AC_MSG_CHECKING([for uintXX_t types]) diff -Nru libgadu-1.12.1/README libgadu-1.12.2/README --- libgadu-1.12.1/README 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/README 2017-01-21 17:57:03.000000000 +0000 @@ -1,4 +1,4 @@ -libgadu 1.12.1 +libgadu 1.12.2 (C) Copyright 2001-2014 Autorzy (pełna lista w pliku AUTHORS) libgadu jest biblioteką przeznaczoną do obsługi protokołu komunikatora diff -Nru libgadu-1.12.1/src/common.c libgadu-1.12.2/src/common.c --- libgadu-1.12.1/src/common.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/common.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2002 Wojtek Kaniewski * Robert J. Woźny @@ -25,9 +23,11 @@ * \brief Funkcje wykorzystywane przez różne moduły biblioteki */ +#include "internal.h" + +#include "fileio.h" #include "network.h" #include "strman.h" -#include "fileio.h" #include #include @@ -36,9 +36,12 @@ #include #include -#include "config.h" -#include "libgadu.h" -#include "internal.h" +#ifdef HAVE_GNUTLS_2_12 +# include +# include +#elif defined(GG_CONFIG_HAVE_OPENSSL) +# include +#endif #ifndef GG_CONFIG_HAVE_VA_COPY # ifdef GG_CONFIG_HAVE___VA_COPY @@ -871,6 +874,50 @@ return out; } +int gg_rand(void *buff, size_t len) +{ +#ifdef HAVE_GNUTLS_2_12 + int res; + + if (gnutls_global_init() != GNUTLS_E_SUCCESS) { + gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR, "// gg_rand() " + "gnutls init failed\n"); + return 0; + } + + res = gnutls_rnd(GNUTLS_RND_NONCE, buff, len); + gnutls_global_deinit(); + + if (res != GNUTLS_E_SUCCESS) { + gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR, "// gg_rand() " + "gnutls rand failed\n"); + return 0; + } + + return 1; +#elif defined(GG_CONFIG_HAVE_OPENSSL) + if (RAND_bytes(buff, len) != 1) { + gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR, "// gg_rand() " + "openssl rand failed\n"); + return 0; + } + + return 1; +#else + size_t i; + uint8_t *bytebuff = buff; + + for (i = 0; i < len; i++) { + /* This is not the most efficient way, + * but rand is not a preferred way too. + */ + bytebuff[i] = rand() & 0xFF; + } + + return 1; +#endif +} + /* * Local variables: * c-indentation-style: k&r diff -Nru libgadu-1.12.1/src/dcc7.c libgadu-1.12.2/src/dcc7.c --- libgadu-1.12.1/src/dcc7.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/dcc7.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2010 Wojtek Kaniewski * Tomasz Chiliński @@ -29,6 +27,8 @@ * \brief Obsługa połączeń bezpośrednich od wersji Gadu-Gadu 7.x */ +#include "internal.h" + #include "fileio.h" #include "network.h" #include "strman.h" @@ -39,10 +39,8 @@ #include #include -#include "libgadu.h" #include "protocol.h" #include "resolver.h" -#include "internal.h" #include "debug.h" #ifdef _MSC_VER @@ -290,9 +288,13 @@ uint16_t external_port; uint32_t external_addr; struct in_addr addr; + uint32_t randval; gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_listen_and_send_info(%p)\n", dcc); + if (!gg_rand(&randval, sizeof(randval))) + return -1; + if (gg_dcc7_listen(dcc, dcc->sess->client_addr, dcc->sess->client_port) == -1) return -1; @@ -317,7 +319,7 @@ pkt.type = GG_DCC7_TYPE_P2P; pkt.id = dcc->cid; snprintf((char*) pkt.info, sizeof(pkt.info), "%s %d", inet_ntoa(addr), external_port); - snprintf((char*) pkt.hash, sizeof(pkt.hash), "%u", external_addr + external_port * rand()); + snprintf((char*) pkt.hash, sizeof(pkt.hash), "%u", external_addr + external_port * randval); return gg_send_packet(dcc->sess, GG_DCC7_INFO, &pkt, sizeof(pkt), NULL); } @@ -789,7 +791,7 @@ #if defined(HAVE__STRTOUI64) || defined(HAVE_STRTOULL) { - uint64_t cid; + uint64_t cid, dcc_cid; # ifdef HAVE__STRTOUI64 cid = _strtoui64(tmp + 2, NULL, 0); @@ -797,14 +799,16 @@ cid = strtoull(tmp + 2, NULL, 0); # endif + GG_STATIC_ASSERT(sizeof(dcc_cid) == sizeof(dcc->cid), bad_cid_size); + memcpy(&dcc_cid, &dcc->cid, sizeof(dcc_cid)); + dcc_cid = gg_fix64(dcc_cid); + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info() info.str=%s, " - "info.id=%llu, sess.id=%llu\n", tmp + 2, cid, - *((unsigned long long*) &dcc->cid)); - - cid = gg_fix64(cid); + "info.id=%" PRIu64 ", sess.id=%" PRIu64 "\n", + tmp + 2, cid, dcc_cid); - if (memcmp(&dcc->cid, &cid, sizeof(cid)) != 0) { + if (cid != dcc_cid) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info() invalid session id\n"); e->type = GG_EVENT_DCC7_ERROR; e->event.dcc7_error = GG_ERROR_DCC7_HANDSHAKE; diff -Nru libgadu-1.12.1/src/dcc.c libgadu-1.12.2/src/dcc.c --- libgadu-1.12.1/src/dcc.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/dcc.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2008 Wojtek Kaniewski * Tomasz Chiliński @@ -26,6 +24,8 @@ * \brief Obsługa połączeń bezpośrednich do wersji Gadu-Gadu 6.x */ +#include "internal.h" + #include "fileio.h" #include "network.h" @@ -34,9 +34,7 @@ #include #include -#include "libgadu.h" #include "debug.h" -#include "internal.h" /** * \internal Przekazuje zawartość pakietu do odpluskwiania. diff -Nru libgadu-1.12.1/src/debug.c libgadu-1.12.2/src/debug.c --- libgadu-1.12.1/src/debug.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/debug.c 2017-01-21 17:57:03.000000000 +0000 @@ -25,13 +25,15 @@ * * \brief Funkcje odpluskwiania */ + +#include "internal.h" + #include #include #include #include #include -#include "libgadu.h" #include "debug.h" /** diff -Nru libgadu-1.12.1/src/deflate.c libgadu-1.12.2/src/deflate.c --- libgadu-1.12.1/src/deflate.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/deflate.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2011 Bartosz Brachaczek * @@ -24,11 +22,11 @@ * \brief Funkcje kompresji Deflate */ +#include "internal.h" + #include #include -#include "libgadu.h" -#include "internal.h" #include "deflate.h" #ifdef GG_CONFIG_HAVE_ZLIB diff -Nru libgadu-1.12.1/src/encoding.c libgadu-1.12.2/src/encoding.c --- libgadu-1.12.1/src/encoding.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/encoding.c 2017-01-21 17:57:03.000000000 +0000 @@ -17,11 +17,12 @@ * USA. */ +#include "internal.h" + #include "strman.h" #include #include -#include "libgadu.h" #include "encoding.h" /** diff -Nru libgadu-1.12.1/src/endian.c libgadu-1.12.2/src/endian.c --- libgadu-1.12.1/src/endian.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/endian.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2010 Wojtek Kaniewski * Robert J. Woźny @@ -28,7 +26,6 @@ * \brief Konwersja między różnymi kolejnościami bajtów */ -#include "libgadu.h" #include "internal.h" /** diff -Nru libgadu-1.12.1/src/events.c libgadu-1.12.2/src/events.c --- libgadu-1.12.1/src/events.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/events.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2006 Wojtek Kaniewski * Robert J. Woźny @@ -29,17 +27,16 @@ * \todo Poprawna obsługa gg_proxy_http_only */ +#include "internal.h" + #include "strman.h" #include "network.h" -#include "libgadu.h" #include "protocol.h" -#include "internal.h" #include "encoding.h" #include "debug.h" #include "session.h" #include "resolver.h" -#include "config.h" #include #include @@ -253,24 +250,61 @@ gs->ssl = tmp; - gnutls_global_init(); - gnutls_certificate_allocate_credentials(&tmp->xcred); + if (gnutls_global_init() != GNUTLS_E_SUCCESS) { + gg_debug(GG_DEBUG_MISC, " // gg_session_init_ssl() " + "gnutls_global_init failed\n"); + return -1; + } + tmp->global_init_called = 1; + + if (gnutls_certificate_allocate_credentials(&tmp->xcred) != GNUTLS_E_SUCCESS) { + gg_debug(GG_DEBUG_MISC, " // gg_session_init_ssl() " + "gnutls_certificate_allocate_credentials failed\n"); + return -1; + } + tmp->xcred_ready = 1; + #ifdef GG_CONFIG_SSL_SYSTEM_TRUST #ifdef HAVE_GNUTLS_CERTIFICATE_SET_X509_SYSTEM_TRUST - gnutls_certificate_set_x509_system_trust(tmp->xcred); + if (gnutls_certificate_set_x509_system_trust(tmp->xcred) < 0) { + gg_debug(GG_DEBUG_MISC, " // gg_session_init_ssl() " + "gnutls_certificate_set_x509_system_trust failed\n"); + return -1; + } #else - gnutls_certificate_set_x509_trust_file(tmp->xcred, + if (gnutls_certificate_set_x509_trust_file(tmp->xcred, GG_CONFIG_GNUTLS_SYSTEM_TRUST_STORE, - GNUTLS_X509_FMT_PEM); + GNUTLS_X509_FMT_PEM) < 0) + { + gg_debug(GG_DEBUG_MISC, " // gg_session_init_ssl() " + "gnutls_certificate_set_x509_trust_file failed\n"); + return -1; + } #endif #endif } else { gnutls_deinit(tmp->session); + tmp->session_ready = 0; + } + + if (gnutls_init(&tmp->session, GNUTLS_CLIENT) != GNUTLS_E_SUCCESS) { + gg_debug(GG_DEBUG_MISC, " // gg_session_init_ssl() gnutls_init failed\n"); + return -1; } + tmp->session_ready = 1; - gnutls_init(&tmp->session, GNUTLS_CLIENT); - gnutls_set_default_priority(tmp->session); - gnutls_credentials_set(tmp->session, GNUTLS_CRD_CERTIFICATE, tmp->xcred); + if (gnutls_set_default_priority(tmp->session) != GNUTLS_E_SUCCESS) { + gg_debug(GG_DEBUG_MISC, " // gg_session_init_ssl() " + "gnutls_set_default_priority failed\n"); + return -1; + } + if (gnutls_credentials_set(tmp->session, GNUTLS_CRD_CERTIFICATE, + tmp->xcred) != GNUTLS_E_SUCCESS) + { + gg_debug(GG_DEBUG_MISC, " // gg_session_init_ssl() " + "gnutls_credentials_set failed\n"); + return -1; + } gnutls_transport_set_ptr(tmp->session, (gnutls_transport_ptr_t) (intptr_t) gs->fd); #endif @@ -898,7 +932,7 @@ if (sess->ssl_flag != GG_SSL_DISABLED) { req = gg_saprintf - ("GET %s/appsvc/appmsg_ver10.asp?fmnumber=%u&fmt=2&" + ("GET %s/appsvc/appmsg_ver11.asp?tls=1&fmnumber=%u&fmt=2&" "lastmsg=%d&version=%s&age=2&gender=1 HTTP/1.0\r\n" "Connection: close\r\n" "Host: " GG_APPMSG_HOST "\r\n" @@ -1282,7 +1316,7 @@ break; } - gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() TLS negotiation succeded:\n"); + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() TLS negotiation succeeded:\n"); gg_debug_session(sess, GG_DEBUG_MISC, "// cipher: VERS-%s:%s:%s:%s:COMP-%s\n", gnutls_protocol_get_name(gnutls_protocol_get_version(GG_SESSION_GNUTLS(sess))), gnutls_cipher_get_name(gnutls_cipher_get(GG_SESSION_GNUTLS(sess))), @@ -1304,11 +1338,15 @@ if (gnutls_x509_crt_import(cert, &peers[0], GNUTLS_X509_FMT_DER) == 0) { size = sizeof(buf); - gnutls_x509_crt_get_dn(cert, buf, &size); - gg_debug_session(sess, GG_DEBUG_MISC, "// cert subject: %s\n", buf); + if (gnutls_x509_crt_get_dn(cert, buf, &size) == 0) { + gg_debug_session(sess, GG_DEBUG_MISC, + "// cert subject: %s\n", buf); + } size = sizeof(buf); - gnutls_x509_crt_get_issuer_dn(cert, buf, &size); - gg_debug_session(sess, GG_DEBUG_MISC, "// cert issuer: %s\n", buf); + if (gnutls_x509_crt_get_issuer_dn(cert, buf, &size) == 0) { + gg_debug_session(sess, GG_DEBUG_MISC, + "// cert issuer: %s\n", buf); + } if (gnutls_x509_crt_check_hostname(cert, sess->connect_host) != 0) valid_hostname = 1; @@ -1380,7 +1418,7 @@ } gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() TLS negotiation" - " succeded:\n// cipher: %s\n", + " succeeded:\n// cipher: %s\n", SSL_get_cipher_name(GG_SESSION_OPENSSL(sess))); peer = SSL_get_peer_certificate(GG_SESSION_OPENSSL(sess)); diff -Nru libgadu-1.12.1/src/handlers.c libgadu-1.12.2/src/handlers.c --- libgadu-1.12.1/src/handlers.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/handlers.c 2017-01-21 17:57:03.000000000 +0000 @@ -26,18 +26,18 @@ * \brief Funkcje obsługi przychodzących pakietów */ +#include "internal.h" + #include #include "fileio.h" #include "network.h" #include "strman.h" -#include "libgadu.h" #include "resolver.h" #include "session.h" #include "protocol.h" #include "encoding.h" #include "message.h" -#include "internal.h" #include "deflate.h" #include "tvbuff.h" #include "protobuf.h" @@ -363,7 +363,7 @@ static int gg_session_handle_login_ok(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) { - gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() login succeded\n"); + gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() login succeeded\n"); ge->type = GG_EVENT_CONN_SUCCESS; gs->state = GG_STATE_CONNECTED; gs->check = GG_CHECK_READ; @@ -1431,7 +1431,7 @@ ev->seq = seq; ev->time = msg->time; - if (abs(msg->time - gg_server_time(gs)) > 2) + if (labs(msg->time - gg_server_time(gs)) > 2) ev->msgclass |= GG_CLASS_QUEUED; ev->message = NULL; @@ -2397,7 +2397,7 @@ uint64_t id; uint32_t version; - uint32_t dummy1; + uint32_t map_size; uint32_t participants_count; uin_t *participants = NULL; @@ -2406,16 +2406,25 @@ id = gg_tvbuff_read_uint64(tvb); gg_tvbuff_expected_uint32(tvb, 0); /* unknown */ version = gg_tvbuff_read_uint32(tvb); - dummy1 = gg_tvbuff_read_uint32(tvb); - if (gg_tvbuff_is_valid(tvb) && dummy1 == 1) { - uint32_t name_length; - name_length = gg_tvbuff_read_uint32(tvb); - gg_tvbuff_skip(tvb, name_length); + map_size = gg_tvbuff_read_uint32(tvb); + for (i = 0; i < map_size && gg_tvbuff_is_valid(tvb); i++) { + uint32_t key_length; + uint32_t value_length; + + /* \todo Obsługa opisu (tytułu, tematu) pokoju. + * Jeżeli klucz to "title", to w wartości mamy opis pokoju. + * Dodatkowo, w momencie zmiany opisu pokoju dostajemy pakiet 0x54. + */ + key_length = gg_tvbuff_read_uint32(tvb); + gg_tvbuff_skip(tvb, key_length); + + value_length = gg_tvbuff_read_uint32(tvb); + gg_tvbuff_skip(tvb, value_length); - gg_tvbuff_expected_uint32(tvb, 0); /* unknown */ gg_tvbuff_expected_uint32(tvb, 2); /* unknown */ } + participants_count = gg_tvbuff_read_uint32(tvb); if (id == 0 && participants_count > 0) { gg_debug_session(gs, GG_DEBUG_MISC | GG_DEBUG_WARNING, @@ -2496,13 +2505,14 @@ if (msg->update_type == GG_CHAT_INFO_UPDATE_ENTERED) { uin_t *old_part = chat->participants; chat->participants = realloc(chat->participants, - sizeof(uin_t) * chat->participants_count); + sizeof(uin_t) * (chat->participants_count + 1)); if (chat->participants == NULL) { chat->participants = old_part; gg_debug_session(gs, GG_DEBUG_ERROR, "// gg_session_handle_chat_info_update() " "out of memory (count=%u)\n", chat->participants_count); + gg110_chat_info_update__free_unpacked(msg, NULL); return -1; } chat->participants_count++; @@ -2512,15 +2522,14 @@ for (idx = 0; idx < chat->participants_count; idx++) if (chat->participants[idx] == participant) break; - if (chat->participants_count > 1 && - idx < chat->participants_count) - chat->participants[idx] = chat->participants[chat->participants_count - 1]; if (idx < chat->participants_count) { chat->participants_count--; if (chat->participants_count == 0) { free(chat->participants); chat->participants = NULL; } else { + chat->participants[idx] = + chat->participants[chat->participants_count]; chat->participants = realloc(chat->participants, sizeof(uin_t)*chat->participants_count); } diff -Nru libgadu-1.12.1/src/http.c libgadu-1.12.2/src/http.c --- libgadu-1.12.1/src/http.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/http.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2002 Wojtek Kaniewski * @@ -24,11 +22,11 @@ * \brief Obsługa połączeń HTTP */ +#include "internal.h" + #include "strman.h" #include "network.h" -#include "libgadu.h" #include "resolver.h" -#include "internal.h" #include #include diff -Nru libgadu-1.12.1/src/libgadu.c libgadu-1.12.2/src/libgadu.c --- libgadu-1.12.1/src/libgadu.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/libgadu.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2010 Wojtek Kaniewski * Robert J. Woźny @@ -28,14 +26,14 @@ * \brief Główny moduł biblioteki */ +#include "internal.h" + #include "strman.h" -#include "network.h" #include "fileio.h" +#include "network.h" -#include "libgadu.h" #include "protocol.h" #include "resolver.h" -#include "internal.h" #include "encoding.h" #include "debug.h" #include "session.h" @@ -121,14 +119,6 @@ */ char *gg_proxy_password = NULL; -#ifndef DOXYGEN - -#ifndef lint -static char rcsid[] GG_UNUSED = "$Id$"; -#endif - -#endif /* DOXYGEN */ - static void gg_compat_message_sent(struct gg_session *sess, int seq, size_t recipients_count, uin_t *recipients); static void gg_compat_message_cleanup(struct gg_session *sess); @@ -1242,9 +1232,12 @@ gg_session_gnutls_t *tmp; tmp = (gg_session_gnutls_t*) sess->ssl; - gnutls_deinit(tmp->session); - gnutls_certificate_free_credentials(tmp->xcred); - gnutls_global_deinit(); + if (tmp->session_ready) + gnutls_deinit(tmp->session); + if (tmp->xcred_ready) + gnutls_certificate_free_credentials(tmp->xcred); + if (tmp->global_init_called) + gnutls_global_deinit(); free(sess->ssl); } #endif diff -Nru libgadu-1.12.1/src/message.c libgadu-1.12.2/src/message.c --- libgadu-1.12.1/src/message.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/message.c 2017-01-21 17:57:03.000000000 +0000 @@ -26,6 +26,8 @@ * konwersji między tekstem z atrybutami i HTML. */ +#include "internal.h" + #include #include #include diff -Nru libgadu-1.12.1/src/network.c libgadu-1.12.2/src/network.c --- libgadu-1.12.1/src/network.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/network.c 2017-01-21 17:57:03.000000000 +0000 @@ -16,6 +16,8 @@ * USA. */ +#include "internal.h" + #include "network.h" #include #include diff -Nru libgadu-1.12.1/src/obsolete.c libgadu-1.12.2/src/obsolete.c --- libgadu-1.12.1/src/obsolete.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/obsolete.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2003 Wojtek Kaniewski * @@ -31,12 +29,11 @@ /** \cond obsolete */ +#include "internal.h" + #include #include -#include "libgadu.h" -#include "internal.h" - struct gg_http *gg_userlist_get(uin_t uin, const char *passwd, int async) { gg_debug(GG_DEBUG_MISC, "// gg_userlist_get() is obsolete. use gg_userlist_request() instead!\n"); diff -Nru libgadu-1.12.1/src/protobuf.c libgadu-1.12.2/src/protobuf.c --- libgadu-1.12.1/src/protobuf.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/protobuf.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2012 Tomek Wasilczyk * @@ -24,6 +22,8 @@ * \brief Funkcje pomocnicze do obsługi formatu protocol buffers */ +#include "internal.h" + #include "protobuf.h" #define GG_PROTOBUFF_UIN_MAXLEN 15 diff -Nru libgadu-1.12.1/src/protobuf-c.c libgadu-1.12.2/src/protobuf-c.c --- libgadu-1.12.1/src/protobuf-c.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/protobuf-c.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2014, Dave Benson and the protobuf-c authors. + * Copyright (c) 2008-2015, Dave Benson and the protobuf-c authors. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -234,15 +234,15 @@ * Number of bytes required. */ static inline size_t -get_tag_size(unsigned number) +get_tag_size(uint32_t number) { - if (number < (1 << 4)) { + if (number < (1UL << 4)) { return 1; - } else if (number < (1 << 11)) { + } else if (number < (1UL << 11)) { return 2; - } else if (number < (1 << 18)) { + } else if (number < (1UL << 18)) { return 3; - } else if (number < (1 << 25)) { + } else if (number < (1UL << 25)) { return 4; } else { return 5; @@ -261,13 +261,13 @@ static inline size_t uint32_size(uint32_t v) { - if (v < (1 << 7)) { + if (v < (1UL << 7)) { return 1; - } else if (v < (1 << 14)) { + } else if (v < (1UL << 14)) { return 2; - } else if (v < (1 << 21)) { + } else if (v < (1UL << 21)) { return 3; - } else if (v < (1 << 28)) { + } else if (v < (1UL << 28)) { return 4; } else { return 5; @@ -288,13 +288,13 @@ { if (v < 0) { return 10; - } else if (v < (1 << 7)) { + } else if (v < (1L << 7)) { return 1; - } else if (v < (1 << 14)) { + } else if (v < (1L << 14)) { return 2; - } else if (v < (1 << 21)) { + } else if (v < (1L << 21)) { return 3; - } else if (v < (1 << 28)) { + } else if (v < (1L << 28)) { return 4; } else { return 5; @@ -314,9 +314,9 @@ zigzag32(int32_t v) { if (v < 0) - return ((uint32_t) (-v)) * 2 - 1; + return (-(uint32_t)v) * 2 - 1; else - return v * 2; + return (uint32_t)(v) * 2; } /** @@ -351,15 +351,15 @@ if (upper_v == 0) { return uint32_size((uint32_t) v); - } else if (upper_v < (1 << 3)) { + } else if (upper_v < (1UL << 3)) { return 5; - } else if (upper_v < (1 << 10)) { + } else if (upper_v < (1UL << 10)) { return 6; - } else if (upper_v < (1 << 17)) { + } else if (upper_v < (1UL << 17)) { return 7; - } else if (upper_v < (1 << 24)) { + } else if (upper_v < (1UL << 24)) { return 8; - } else if (upper_v < (1U << 31)) { + } else if (upper_v < (1UL << 31)) { return 9; } else { return 10; @@ -379,9 +379,9 @@ zigzag64(int64_t v) { if (v < 0) - return ((uint64_t) (-v)) * 2 - 1; + return (-(uint64_t)v) * 2 - 1; else - return v * 2; + return (uint64_t)(v) * 2; } /** @@ -420,8 +420,9 @@ switch (field->type) { case PROTOBUF_C_TYPE_SINT32: return rv + sint32_size(*(const int32_t *) member); + case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_INT32: - return rv + int32_size(*(const uint32_t *) member); + return rv + int32_size(*(const int32_t *) member); case PROTOBUF_C_TYPE_UINT32: return rv + uint32_size(*(const uint32_t *) member); case PROTOBUF_C_TYPE_SINT64: @@ -441,9 +442,6 @@ return rv + 4; case PROTOBUF_C_TYPE_DOUBLE: return rv + 8; - case PROTOBUF_C_TYPE_ENUM: - /* \todo Is this correct for negative-valued enums? */ - return rv + uint32_size(*(const uint32_t *) member); case PROTOBUF_C_TYPE_STRING: { const char *str = *(char * const *) member; size_t len = str ? strlen(str) : 0; @@ -464,6 +462,39 @@ } /** + * Calculate the serialized size of a single oneof message field, including + * the space needed by the preceding tag. Returns 0 if the oneof field isn't + * selected or is not set. + * + * \param field + * Field descriptor for member. + * \param oneof_case + * A pointer to the case enum that selects the field in the oneof. + * \param member + * Field to encode. + * \return + * Number of bytes required. + */ +static size_t +oneof_field_get_packed_size(const ProtobufCFieldDescriptor *field, + const uint32_t *oneof_case, + const void *member) +{ + if (*oneof_case == field->id) { + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void * const *) member; + if (ptr == NULL || ptr == field->default_value) + return 0; + } + } else { + return 0; + } + return required_field_get_packed_size(field, member); +} + +/** * Calculate the serialized size of a single optional message field, including * the space needed by the preceding tag. Returns 0 if the optional field isn't * set. @@ -529,12 +560,12 @@ for (i = 0; i < count; i++) rv += sint32_size(((int32_t *) array)[i]); break; + case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_INT32: for (i = 0; i < count; i++) - rv += int32_size(((uint32_t *) array)[i]); + rv += int32_size(((int32_t *) array)[i]); break; case PROTOBUF_C_TYPE_UINT32: - case PROTOBUF_C_TYPE_ENUM: for (i = 0; i < count; i++) rv += uint32_size(((uint32_t *) array)[i]); break; @@ -624,7 +655,10 @@ if (field->label == PROTOBUF_C_LABEL_REQUIRED) { rv += required_field_get_packed_size(field, member); } else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) { - rv += optional_field_get_packed_size(field, qmember, member); + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF)) + rv += oneof_field_get_packed_size(field, qmember, member); + else + rv += optional_field_get_packed_size(field, qmember, member); } else { rv += repeated_field_get_packed_size( field, @@ -952,7 +986,7 @@ static size_t tag_pack(uint32_t id, uint8_t *out) { - if (id < (1 << (32 - 3))) + if (id < (1UL << (32 - 3))) return uint32_pack(id << 3, out); else return uint64_pack(((uint64_t) id) << 3, out); @@ -980,11 +1014,11 @@ case PROTOBUF_C_TYPE_SINT32: out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; return rv + sint32_pack(*(const int32_t *) member, out + rv); + case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_INT32: out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; - return rv + int32_pack(*(const uint32_t *) member, out + rv); + return rv + int32_pack(*(const int32_t *) member, out + rv); case PROTOBUF_C_TYPE_UINT32: - case PROTOBUF_C_TYPE_ENUM: out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; return rv + uint32_pack(*(const uint32_t *) member, out + rv); case PROTOBUF_C_TYPE_SINT64: @@ -1022,6 +1056,40 @@ } /** + * Pack a oneof field and return the number of bytes written. Only packs the + * field that is selected by the case enum. + * + * \param field + * Field descriptor. + * \param oneof_case + * A pointer to the case enum that selects the field in the oneof. + * \param member + * The field member. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static size_t +oneof_field_pack(const ProtobufCFieldDescriptor *field, + const uint32_t *oneof_case, + const void *member, uint8_t *out) +{ + if (*oneof_case == field->id) { + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void * const *) member; + if (ptr == NULL || ptr == field->default_value) + return 0; + } + } else { + return 0; + } + return required_field_pack(field, member, out); +} + +/** * Pack an optional field and return the number of bytes written. * * \param field @@ -1221,6 +1289,7 @@ copy_to_little_endian_64(payload_at, array, count); payload_at += count * 8; break; + case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_INT32: { const int32_t *arr = (const int32_t *) array; for (i = 0; i < count; i++) @@ -1239,7 +1308,6 @@ payload_at += sint64_pack(arr[i], payload_at); break; } - case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_UINT32: { const uint32_t *arr = (const uint32_t *) array; for (i = 0; i < count; i++) @@ -1315,6 +1383,7 @@ * quantifier field of the structure), but the pointer is only * valid if the field is: * - a repeated field, or + * - a field that is part of a oneof * - an optional field that isn't a pointer type * (Meaning: not a message or a string). */ @@ -1324,11 +1393,10 @@ if (field->label == PROTOBUF_C_LABEL_REQUIRED) { rv += required_field_pack(field, member, out + rv); } else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) { - /* - * Note that qmember is bogus for strings and messages, - * but it isn't used. - */ - rv += optional_field_pack(field, qmember, member, out + rv); + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF)) + rv += oneof_field_pack (field, qmember, member, out + rv); + else + rv += optional_field_pack(field, qmember, member, out + rv); } else { rv += repeated_field_pack(field, *(const size_t *) qmember, member, out + rv); @@ -1374,13 +1442,13 @@ rv += sint32_pack(*(const int32_t *) member, scratch + rv); buffer->append(buffer, rv, scratch); break; + case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_INT32: scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; - rv += int32_pack(*(const uint32_t *) member, scratch + rv); + rv += int32_pack(*(const int32_t *) member, scratch + rv); buffer->append(buffer, rv, scratch); break; case PROTOBUF_C_TYPE_UINT32: - case PROTOBUF_C_TYPE_ENUM: scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT; rv += uint32_pack(*(const uint32_t *) member, scratch + rv); buffer->append(buffer, rv, scratch); @@ -1463,6 +1531,39 @@ } /** + * Pack a oneof field to a buffer. Only packs the field that is selected by the case enum. + * + * \param field + * Field descriptor. + * \param oneof_case + * A pointer to the case enum that selects the field in the oneof. + * \param member + * The element to be packed. + * \param[out] buffer + * Virtual buffer to append data to. + * \return + * Number of bytes serialised to `buffer`. + */ +static size_t +oneof_field_pack_to_buffer(const ProtobufCFieldDescriptor *field, + const uint32_t *oneof_case, + const void *member, ProtobufCBuffer *buffer) +{ + if (*oneof_case == field->id) { + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void *const *) member; + if (ptr == NULL || ptr == field->default_value) + return 0; + } + } else { + return 0; + } + return required_field_pack_to_buffer(field, member, buffer); +} + +/** * Pack an optional field to a buffer. * * \param field @@ -1522,6 +1623,7 @@ case PROTOBUF_C_TYPE_FIXED64: case PROTOBUF_C_TYPE_DOUBLE: return count * 8; + case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_INT32: { const int32_t *arr = (const int32_t *) array; for (i = 0; i < count; i++) @@ -1534,7 +1636,6 @@ rv += sint32_size(arr[i]); break; } - case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_UINT32: { const uint32_t *arr = (const uint32_t *) array; for (i = 0; i < count; i++) @@ -1614,6 +1715,7 @@ } break; #endif + case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_INT32: for (i = 0; i < count; i++) { unsigned len = int32_pack(((int32_t *) array)[i], scratch); @@ -1628,7 +1730,6 @@ rv += len; } break; - case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_UINT32: for (i = 0; i < count; i++) { unsigned len = uint32_pack(((uint32_t *) array)[i], scratch); @@ -1700,7 +1801,7 @@ siz = sizeof_elt_in_repeated_array(field->type); for (i = 0; i < count; i++) { rv += required_field_pack_to_buffer(field, array, buffer); - array = ((char*)array) + siz; + array += siz; } return rv; } @@ -1740,12 +1841,21 @@ if (field->label == PROTOBUF_C_LABEL_REQUIRED) { rv += required_field_pack_to_buffer(field, member, buffer); } else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) { - rv += optional_field_pack_to_buffer( - field, - qmember, - member, - buffer - ); + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF)) { + rv += oneof_field_pack_to_buffer( + field, + qmember, + member, + buffer + ); + } else { + rv += optional_field_pack_to_buffer( + field, + qmember, + member, + buffer + ); + } } else { rv += repeated_field_pack_to_buffer( field, @@ -1840,7 +1950,7 @@ return 0; /* error: bad header */ } -/* sizeof(ScannedMember) must be <= (1<descriptor->fields; + latter_msg->descriptor->fields; for (i = 0; i < latter_msg->descriptor->n_fields; i++) { if (fields[i].label == PROTOBUF_C_LABEL_REPEATED) { size_t *n_earlier = @@ -1963,38 +2073,64 @@ *n_earlier = 0; *p_earlier = 0; } - } else if (fields[i].type == PROTOBUF_C_TYPE_MESSAGE) { - ProtobufCMessage **em = - STRUCT_MEMBER_PTR(ProtobufCMessage *, - earlier_msg, - fields[i].offset); - ProtobufCMessage **lm = - STRUCT_MEMBER_PTR(ProtobufCMessage *, - latter_msg, - fields[i].offset); - if (*em != NULL) { - if (*lm != NULL) { - if (!merge_messages - (*em, *lm, allocator)) - return FALSE; + } else if (fields[i].label == PROTOBUF_C_LABEL_OPTIONAL) { + const ProtobufCFieldDescriptor *field; + uint32_t *earlier_case_p = STRUCT_MEMBER_PTR(uint32_t, + earlier_msg, + fields[i]. + quantifier_offset); + uint32_t *latter_case_p = STRUCT_MEMBER_PTR(uint32_t, + latter_msg, + fields[i]. + quantifier_offset); + protobuf_c_boolean need_to_merge = FALSE; + void *earlier_elem; + void *latter_elem; + const void *def_val; + + if (fields[i].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) { + if (*latter_case_p == 0) { + /* lookup correct oneof field */ + int field_index = + int_range_lookup( + latter_msg->descriptor + ->n_field_ranges, + latter_msg->descriptor + ->field_ranges, + *earlier_case_p); + field = latter_msg->descriptor->fields + + field_index; } else { - /* Zero copy the optional message */ - assert(fields[i].label == - PROTOBUF_C_LABEL_OPTIONAL); - *lm = *em; - *em = NULL; + /* Oneof is present in the latter message, move on */ + continue; } + } else { + field = &fields[i]; } - } else if (fields[i].label == PROTOBUF_C_LABEL_OPTIONAL) { - size_t el_size = 0; - protobuf_c_boolean need_to_merge = FALSE; - void *earlier_elem = - STRUCT_MEMBER_P(earlier_msg, fields[i].offset); - void *latter_elem = - STRUCT_MEMBER_P(latter_msg, fields[i].offset); - const void *def_val = fields[i].default_value; - switch (fields[i].type) { + earlier_elem = + STRUCT_MEMBER_P(earlier_msg, field->offset); + latter_elem = + STRUCT_MEMBER_P(latter_msg, field->offset); + def_val = field->default_value; + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: { + ProtobufCMessage *em = *(ProtobufCMessage **) earlier_elem; + ProtobufCMessage *lm = *(ProtobufCMessage **) latter_elem; + if (em != NULL) { + if (lm != NULL) { + if (!merge_messages(em, lm, allocator)) + return FALSE; + /* Already merged */ + need_to_merge = FALSE; + } else { + /* Zero copy the message */ + need_to_merge = TRUE; + } + } + break; + } case PROTOBUF_C_TYPE_BYTES: { uint8_t *e_data = ((ProtobufCBinaryData *) earlier_elem)->data; @@ -2003,10 +2139,9 @@ const ProtobufCBinaryData *d_bd = (ProtobufCBinaryData *) def_val; - el_size = sizeof(ProtobufCBinaryData); need_to_merge = (e_data != NULL && - (d_bd != NULL && + (d_bd == NULL || e_data != d_bd->data)) && (l_data == NULL || (d_bd != NULL && @@ -2018,25 +2153,22 @@ char *l_str = *(char **) latter_elem; const char *d_str = def_val; - el_size = sizeof(char *); need_to_merge = e_str != d_str && l_str == d_str; break; } default: { - el_size = sizeof_elt_in_repeated_array(fields[i].type); - - need_to_merge = - STRUCT_MEMBER(protobuf_c_boolean, - earlier_msg, - fields[i].quantifier_offset) && - !STRUCT_MEMBER(protobuf_c_boolean, - latter_msg, - fields[i].quantifier_offset); + /* Could be has field or case enum, the logic is + * equivalent, since 0 (FALSE) means not set for + * oneof */ + need_to_merge = (*earlier_case_p != 0) && + (*latter_case_p == 0); break; } } if (need_to_merge) { + size_t el_size = + sizeof_elt_in_repeated_array(field->type); memcpy(latter_elem, earlier_elem, el_size); /* * Reset the element from the old message to 0 @@ -2047,16 +2179,11 @@ */ memset(earlier_elem, 0, el_size); - if (fields[i].quantifier_offset != 0) { - /* Set the has field, if applicable */ - STRUCT_MEMBER(protobuf_c_boolean, - latter_msg, - fields[i]. - quantifier_offset) = TRUE; - STRUCT_MEMBER(protobuf_c_boolean, - earlier_msg, - fields[i]. - quantifier_offset) = FALSE; + if (field->quantifier_offset != 0) { + /* Set the has field or the case enum, + * if applicable */ + *latter_case_p = *earlier_case_p; + *earlier_case_p = 0; } } } @@ -2095,9 +2222,9 @@ } *count_out = len / 8; return TRUE; + case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_INT32: case PROTOBUF_C_TYPE_SINT32: - case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_UINT32: case PROTOBUF_C_TYPE_INT64: case PROTOBUF_C_TYPE_SINT64: @@ -2227,10 +2354,11 @@ ProtobufCWireType wire_type = scanned_member->wire_type; switch (scanned_member->field->type) { + case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_INT32: if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) return FALSE; - *(uint32_t *) member = parse_int32(len, data); + *(int32_t *) member = parse_int32(len, data); return TRUE; case PROTOBUF_C_TYPE_UINT32: if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) @@ -2270,11 +2398,6 @@ case PROTOBUF_C_TYPE_BOOL: *(protobuf_c_boolean *) member = parse_boolean(len, data); return TRUE; - case PROTOBUF_C_TYPE_ENUM: - if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) - return FALSE; - *(uint32_t *) member = parse_uint32(len, data); - return TRUE; case PROTOBUF_C_TYPE_STRING: { char **pstr = member; unsigned pref_len = scanned_member->length_prefix_len; @@ -2355,6 +2478,64 @@ } static protobuf_c_boolean +parse_oneof_member (ScannedMember *scanned_member, + void *member, + ProtobufCMessage *message, + ProtobufCAllocator *allocator) +{ + uint32_t *oneof_case = STRUCT_MEMBER_PTR(uint32_t, message, + scanned_member->field->quantifier_offset); + + /* If we have already parsed a member of this oneof, free it. */ + if (*oneof_case != 0) { + /* lookup field */ + int field_index = + int_range_lookup(message->descriptor->n_field_ranges, + message->descriptor->field_ranges, + *oneof_case); + const ProtobufCFieldDescriptor *old_field = + message->descriptor->fields + field_index; + size_t el_size = sizeof_elt_in_repeated_array(old_field->type); + switch (old_field->type) { + case PROTOBUF_C_TYPE_STRING: { + char **pstr = member; + const char *def = old_field->default_value; + if (*pstr != NULL && *pstr != def) + do_free(allocator, *pstr); + break; + } + case PROTOBUF_C_TYPE_BYTES: { + ProtobufCBinaryData *bd = member; + const ProtobufCBinaryData *def_bd = old_field->default_value; + if (bd->data != NULL && + (def_bd == NULL || bd->data != def_bd->data)) + { + do_free(allocator, bd->data); + } + break; + } + case PROTOBUF_C_TYPE_MESSAGE: { + ProtobufCMessage **pmessage = member; + const ProtobufCMessage *def_mess = old_field->default_value; + if (*pmessage != NULL && *pmessage != def_mess) + protobuf_c_message_free_unpacked(*pmessage, allocator); + break; + } + default: + break; + } + + memset (member, 0, el_size); + } + if (!parse_required_member (scanned_member, member, allocator, TRUE)) + return FALSE; + + *oneof_case = scanned_member->tag; + return TRUE; +} + + +static protobuf_c_boolean parse_optional_member(ScannedMember *scanned_member, void *member, ProtobufCMessage *message, @@ -2444,6 +2625,7 @@ } break; #endif + case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_INT32: while (rem > 0) { unsigned s = scan_varint(rem, at); @@ -2468,7 +2650,6 @@ rem -= s; } break; - case PROTOBUF_C_TYPE_ENUM: case PROTOBUF_C_TYPE_UINT32: while (rem > 0) { unsigned s = scan_varint(rem, at); @@ -2567,8 +2748,13 @@ return parse_required_member(scanned_member, member, allocator, TRUE); case PROTOBUF_C_LABEL_OPTIONAL: - return parse_optional_member(scanned_member, member, - message, allocator); + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF)) { + return parse_oneof_member(scanned_member, member, + message, allocator); + } else { + return parse_optional_member(scanned_member, member, + message, allocator); + } case PROTOBUF_C_LABEL_REPEATED: if (scanned_member->wire_type == PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED && @@ -2672,10 +2858,10 @@ - FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2) #define REQUIRED_FIELD_BITMAP_SET(index) \ - (required_fields_bitmap[(index)/8] |= (1<<((index)%8))) + (required_fields_bitmap[(index)/8] |= (1UL<<((index)%8))) #define REQUIRED_FIELD_BITMAP_IS_SET(index) \ - (required_fields_bitmap[(index)/8] & (1<<((index)%8))) + (required_fields_bitmap[(index)/8] & (1UL<<((index)%8))) ProtobufCMessage * protobuf_c_message_unpack(const ProtobufCMessageDescriptor *desc, @@ -2686,7 +2872,7 @@ size_t rem = len; const uint8_t *at = data; const ProtobufCFieldDescriptor *last_field = desc->fields + 0; - ScannedMember first_member_slab[1 << + ScannedMember first_member_slab[1UL << FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2]; /* @@ -2747,17 +2933,15 @@ const ProtobufCFieldDescriptor *field; ScannedMember tmp; - memset(&tmp, 0, sizeof(ScannedMember)); - if (used == 0) { PROTOBUF_C_UNPACK_ERROR("error parsing tag/wiretype at offset %u", (unsigned) (at - data)); goto error_cleanup_during_scan; } /* - * \todo Consider optimizing for field[1].id == tag, if field[1] - * exists! - */ + * \todo Consider optimizing for field[1].id == tag, if field[1] + * exists! + */ if (last_field == NULL || last_field->id != tag) { /* lookup field */ int field_index = @@ -2836,7 +3020,7 @@ goto error_cleanup_during_scan; } - if (in_slab_index == (1U << + if (in_slab_index == (1UL << (which_slab + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2))) { size_t size; @@ -2935,7 +3119,7 @@ /* do real parsing */ for (i_slab = 0; i_slab <= which_slab; i_slab++) { unsigned max = (i_slab == which_slab) ? - in_slab_index : (1U << (i_slab + 4)); + in_slab_index : (1UL << (i_slab + 4)); ScannedMember *slab = scanned_member_slabs[i_slab]; unsigned j; @@ -2977,14 +3161,28 @@ protobuf_c_message_free_unpacked(ProtobufCMessage *message, ProtobufCAllocator *allocator) { - const ProtobufCMessageDescriptor *desc = message->descriptor; + const ProtobufCMessageDescriptor *desc; unsigned f; + if (message == NULL) + return; + + desc = message->descriptor; + ASSERT_IS_MESSAGE(message); + if (allocator == NULL) allocator = &protobuf_c__allocator; message->descriptor = NULL; for (f = 0; f < desc->n_fields; f++) { + if (0 != (desc->fields[f].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) && + desc->fields[f].id != + STRUCT_MEMBER(uint32_t, message, desc->fields[f].quantifier_offset)) + { + /* This is not the selected oneof, skip it */ + continue; + } + if (desc->fields[f].label == PROTOBUF_C_LABEL_REPEATED) { size_t n = STRUCT_MEMBER(size_t, message, @@ -2993,24 +3191,25 @@ message, desc->fields[f].offset); - if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) { - unsigned i; - for (i = 0; i < n; i++) - do_free(allocator, ((char **) arr)[i]); - } else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) { - unsigned i; - for (i = 0; i < n; i++) - do_free(allocator, ((ProtobufCBinaryData *) arr)[i].data); - } else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) { - unsigned i; - for (i = 0; i < n; i++) - protobuf_c_message_free_unpacked( - ((ProtobufCMessage **) arr)[i], - allocator - ); - } - if (arr != NULL) + if (arr != NULL) { + if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) { + unsigned i; + for (i = 0; i < n; i++) + do_free(allocator, ((char **) arr)[i]); + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) { + unsigned i; + for (i = 0; i < n; i++) + do_free(allocator, ((ProtobufCBinaryData *) arr)[i].data); + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) { + unsigned i; + for (i = 0; i < n; i++) + protobuf_c_message_free_unpacked( + ((ProtobufCMessage **) arr)[i], + allocator + ); + } do_free(allocator, arr); + } } else if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) { char *str = STRUCT_MEMBER(char *, message, desc->fields[f].offset); @@ -3189,7 +3388,12 @@ const char *name) { unsigned start = 0; - unsigned count = desc->n_value_names; + unsigned count; + + if (desc == NULL || desc->values_by_name == NULL) + return NULL; + + count = desc->n_value_names; while (count > 1) { unsigned mid = start + count / 2; @@ -3224,9 +3428,14 @@ const char *name) { unsigned start = 0; - unsigned count = desc->n_fields; + unsigned count; const ProtobufCFieldDescriptor *field; + if (desc == NULL || desc->fields_sorted_by_name == NULL) + return NULL; + + count = desc->n_fields; + while (count > 1) { unsigned mid = start + count / 2; int rv; @@ -3263,7 +3472,12 @@ const char *name) { unsigned start = 0; - unsigned count = desc->n_methods; + unsigned count; + + if (desc == NULL || desc->method_indices_by_name == NULL) + return NULL; + + count = desc->n_methods; while (count > 1) { unsigned mid = start + count / 2; diff -Nru libgadu-1.12.1/src/protobuf-c.c.patch libgadu-1.12.2/src/protobuf-c.c.patch --- libgadu-1.12.1/src/protobuf-c.c.patch 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/protobuf-c.c.patch 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,5 @@ ---- protobuf-c.c -+++ protobuf-c.c +--- protobuf-c.c.ori 2016-01-30 00:54:28.000000000 +0000 ++++ protobuf-c.c 2016-05-02 13:48:47.033083213 +0100 @@ -48,6 +48,9 @@ #include /* for malloc, free */ #include /* for strcmp, strlen, memcpy, memmove, memset */ @@ -10,7 +10,25 @@ #include "protobuf-c.h" #define TRUE 1 -@@ -1660,9 +1663,11 @@ +@@ -285,13 +288,13 @@ + { + if (v < 0) { + return 10; +- } else if (v < (1UL << 7)) { ++ } else if (v < (1L << 7)) { + return 1; +- } else if (v < (1UL << 14)) { ++ } else if (v < (1L << 14)) { + return 2; +- } else if (v < (1UL << 21)) { ++ } else if (v < (1L << 21)) { + return 3; +- } else if (v < (1UL << 28)) { ++ } else if (v < (1L << 28)) { + return 4; + } else { + return 5; +@@ -1761,9 +1764,11 @@ } return rv; @@ -22,54 +40,50 @@ } static size_t -@@ -1695,7 +1700,7 @@ - siz = sizeof_elt_in_repeated_array(field->type); - for (i = 0; i < count; i++) { - rv += required_field_pack_to_buffer(field, array, buffer); -- array += siz; -+ array = ((char*)array) + siz; +@@ -2078,6 +2083,10 @@ + latter_msg, + fields[i]. + quantifier_offset); ++ protobuf_c_boolean need_to_merge = FALSE; ++ void *earlier_elem; ++ void *latter_elem; ++ const void *def_val; + + if (fields[i].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) { + if (*latter_case_p == 0) { +@@ -2099,12 +2108,11 @@ + field = &fields[i]; + } + +- protobuf_c_boolean need_to_merge = FALSE; +- void *earlier_elem = ++ earlier_elem = + STRUCT_MEMBER_P(earlier_msg, field->offset); +- void *latter_elem = ++ latter_elem = + STRUCT_MEMBER_P(latter_msg, field->offset); +- const void *def_val = field->default_value; ++ def_val = field->default_value; + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: { +@@ -2487,6 +2495,7 @@ + *oneof_case); + const ProtobufCFieldDescriptor *old_field = + message->descriptor->fields + field_index; ++ size_t el_size = sizeof_elt_in_repeated_array(old_field->type); + switch (old_field->type) { + case PROTOBUF_C_TYPE_STRING: { + char **pstr = member; +@@ -2516,7 +2525,6 @@ + break; } - return rv; - } -@@ -1991,7 +1996,6 @@ - switch (fields[i].type) { - case PROTOBUF_C_TYPE_BYTES: { -- el_size = sizeof(ProtobufCBinaryData); - uint8_t *e_data = - ((ProtobufCBinaryData *) earlier_elem)->data; - uint8_t *l_data = -@@ -1999,6 +2003,7 @@ - const ProtobufCBinaryData *d_bd = - (ProtobufCBinaryData *) def_val; - -+ el_size = sizeof(ProtobufCBinaryData); - need_to_merge = - (e_data != NULL && - (d_bd != NULL && -@@ -2009,11 +2014,11 @@ - break; - } - case PROTOBUF_C_TYPE_STRING: { -- el_size = sizeof(char *); - char *e_str = *(char **) earlier_elem; - char *l_str = *(char **) latter_elem; - const char *d_str = def_val; - -+ el_size = sizeof(char *); - need_to_merge = e_str != d_str && l_str == d_str; - break; - } -@@ -2742,6 +2747,8 @@ - const ProtobufCFieldDescriptor *field; - ScannedMember tmp; - -+ memset(&tmp, 0, sizeof(ScannedMember)); -+ - if (used == 0) { - PROTOBUF_C_UNPACK_ERROR("error parsing tag/wiretype at offset %u", - (unsigned) (at - data)); -@@ -2887,6 +2894,7 @@ +- size_t el_size = sizeof_elt_in_repeated_array(old_field->type); + memset (member, 0, el_size); + } + if (!parse_required_member (scanned_member, member, allocator, TRUE)) +@@ -3070,6 +3078,7 @@ field->quantifier_offset); if (*n_ptr != 0) { unsigned n = *n_ptr; @@ -77,7 +91,7 @@ *n_ptr = 0; assert(rv->descriptor != NULL); #define CLEAR_REMAINING_N_PTRS() \ -@@ -2896,7 +2904,7 @@ +@@ -3079,7 +3088,7 @@ if (field->label == PROTOBUF_C_LABEL_REPEATED) \ STRUCT_MEMBER (size_t, rv, field->quantifier_offset) = 0; \ } @@ -86,7 +100,23 @@ if (!a) { CLEAR_REMAINING_N_PTRS(); goto error_cleanup; -@@ -3049,6 +3057,8 @@ +@@ -3152,11 +3161,13 @@ + protobuf_c_message_free_unpacked(ProtobufCMessage *message, + ProtobufCAllocator *allocator) + { ++ const ProtobufCMessageDescriptor *desc; ++ unsigned f; ++ + if (message == NULL) + return; + +- const ProtobufCMessageDescriptor *desc = message->descriptor; +- unsigned f; ++ desc = message->descriptor; + + ASSERT_IS_MESSAGE(message); + +@@ -3245,6 +3256,8 @@ protobuf_c_boolean protobuf_c_message_check(const ProtobufCMessage *message) { @@ -95,7 +125,7 @@ if (!message || !message->descriptor || message->descriptor->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) -@@ -3056,7 +3066,6 @@ +@@ -3252,7 +3265,6 @@ return FALSE; } @@ -103,3 +133,53 @@ for (i = 0; i < message->descriptor->n_fields; i++) { const ProtobufCFieldDescriptor *f = message->descriptor->fields + i; ProtobufCType type = f->type; +@@ -3375,11 +3387,13 @@ + protobuf_c_enum_descriptor_get_value_by_name(const ProtobufCEnumDescriptor *desc, + const char *name) + { ++ unsigned start = 0; ++ unsigned count; ++ + if (desc == NULL || desc->values_by_name == NULL) + return NULL; + +- unsigned start = 0; +- unsigned count = desc->n_value_names; ++ count = desc->n_value_names; + + while (count > 1) { + unsigned mid = start + count / 2; +@@ -3413,12 +3427,14 @@ + protobuf_c_message_descriptor_get_field_by_name(const ProtobufCMessageDescriptor *desc, + const char *name) + { ++ unsigned start = 0; ++ unsigned count; ++ const ProtobufCFieldDescriptor *field; ++ + if (desc == NULL || desc->fields_sorted_by_name == NULL) + return NULL; + +- unsigned start = 0; +- unsigned count = desc->n_fields; +- const ProtobufCFieldDescriptor *field; ++ count = desc->n_fields; + + while (count > 1) { + unsigned mid = start + count / 2; +@@ -3455,11 +3471,13 @@ + protobuf_c_service_descriptor_get_method_by_name(const ProtobufCServiceDescriptor *desc, + const char *name) + { ++ unsigned start = 0; ++ unsigned count; ++ + if (desc == NULL || desc->method_indices_by_name == NULL) + return NULL; + +- unsigned start = 0; +- unsigned count = desc->n_methods; ++ count = desc->n_methods; + + while (count > 1) { + unsigned mid = start + count / 2; diff -Nru libgadu-1.12.1/src/pubdir50.c libgadu-1.12.2/src/pubdir50.c --- libgadu-1.12.1/src/pubdir50.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/pubdir50.c 2017-01-21 17:57:03.000000000 +0000 @@ -25,6 +25,8 @@ * testowa konwersja, żeby poznać długość tekstu wynikowego. */ +#include "internal.h" + #include "network.h" #include "strman.h" #include @@ -32,8 +34,6 @@ #include #include -#include "libgadu.h" -#include "internal.h" #include "encoding.h" /** diff -Nru libgadu-1.12.1/src/pubdir.c libgadu-1.12.2/src/pubdir.c --- libgadu-1.12.1/src/pubdir.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/pubdir.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2001-2006 Wojtek Kaniewski * Dawid Jarosz @@ -26,14 +24,14 @@ * \brief Obsługa katalogu publicznego */ +#include "internal.h" + #include "network.h" #include #include #include #include -#include "libgadu.h" - /** * Rejestruje nowego użytkownika. * @@ -187,6 +185,7 @@ { struct gg_http *h; char *__fmpwd, *__pwd, *__tokenid, *__tokenval, *form, *query; + uint32_t randval; if (!password || !tokenid || !tokenval) { gg_debug(GG_DEBUG_MISC, "=> unregister, NULL parameter\n"); @@ -194,7 +193,10 @@ return NULL; } - __pwd = gg_saprintf("%d", rand()); + if (!gg_rand(&randval, sizeof(randval))) + return NULL; + + __pwd = gg_saprintf("%u", randval); __fmpwd = gg_urlencode(password); __tokenid = gg_urlencode(tokenid); __tokenval = gg_urlencode(tokenval); diff -Nru libgadu-1.12.1/src/resolver.c libgadu-1.12.2/src/resolver.c --- libgadu-1.12.1/src/resolver.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/resolver.c 2017-01-21 17:57:03.000000000 +0000 @@ -26,14 +26,14 @@ * \brief Funkcje rozwiązywania nazw */ +#include "internal.h" + #include #include #include #include "strman.h" #include "network.h" -#include "config.h" -#include "libgadu.h" #include "resolver.h" #include "session.h" @@ -98,8 +98,8 @@ char *new_buf = NULL; struct hostent he; struct hostent *he_ptr = NULL; - size_t buf_len = 1024; - int res = -1; + size_t buf_len; + int res; int h_errnop; int ret = 0; #ifdef GG_CONFIG_HAVE_PTHREAD @@ -118,6 +118,8 @@ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state); #endif + buf_len = 1024; + res = -1; buf = malloc(buf_len); #ifdef GG_CONFIG_HAVE_PTHREAD @@ -282,7 +284,7 @@ { struct in_addr addr_ip[2], *addr_list = NULL; unsigned int addr_count; - int res = 0; + int res; #ifdef GG_CONFIG_HAVE_PTHREAD int old_state; #endif @@ -291,6 +293,8 @@ pthread_cleanup_push(gg_resolver_cleaner, &addr_list); #endif + res = 0; + if ((addr_ip[0].s_addr = inet_addr(hostname)) == INADDR_NONE) { if (gg_gethostbyname_real(hostname, &addr_list, &addr_count, pthread) == -1) { #ifdef GG_CONFIG_HAVE_PTHREAD @@ -491,13 +495,20 @@ /** * \internal Struktura przekazywana do wątku rozwiązującego nazwę. */ -struct gg_resolver_pthread_data { - pthread_t thread; /*< Identyfikator wątku */ +struct gg_resolver_pthread_params { + pthread_barrier_t *init_barrier; /*< Bariera pilnująca poprawnej inicjalizacji wątku */ char *hostname; /*< Nazwa serwera */ int wfd; /*< Deskryptor do zapisu */ }; /** + * \internal Struktura opisująca wątek rozwiązujący nazwę. + */ +struct gg_resolver_pthread_data { + pthread_t thread; /*< Identyfikator wątku */ +}; + +/** * \internal Usuwanie zasobów po wątku rozwiązywaniu nazwy. * * Funkcja wywoływana po zakończeniu rozwiązanywania nazwy lub przy zwalnianiu @@ -517,30 +528,52 @@ data = (struct gg_resolver_pthread_data *) *priv_data; *priv_data = NULL; +#ifdef _WIN32 + /* Mingw's implementation of pthreads seems to not like pthread_cancel. + * Let's detach the thread and let it complete in background. + */ + if (force) + pthread_detach(data->thread); + else + pthread_join(data->thread, NULL); +#else if (force) pthread_cancel(data->thread); pthread_join(data->thread, NULL); +#endif - close(data->wfd); - free(data->hostname); free(data); } +static void gg_resolver_pthread_params_cleanup(void *params_raw) { + struct gg_resolver_pthread_params *params = params_raw; + + close(params->wfd); + free(params->hostname); + free(params); +} + /** * \internal Wątek rozwiązujący nazwę. * - * \param arg Wskaźnik na strukturę \c gg_resolver_pthread_data + * \param arg Wskaźnik na strukturę \c gg_resolver_pthread_params */ static void *gg_resolver_pthread_thread(void *arg) { - struct gg_resolver_pthread_data *data = arg; + struct gg_resolver_pthread_params *params = arg; + int res; - if (gg_resolver_run(data->wfd, data->hostname, 1) == -1) - pthread_exit((void*) -1); - else - pthread_exit(NULL); + pthread_cleanup_push(gg_resolver_pthread_params_cleanup, params); + + /* Powiadom wątek główny, że już odebraliśmy parametry. */ + pthread_barrier_wait(params->init_barrier); + + res = gg_resolver_run(params->wfd, params->hostname, 1); + pthread_cleanup_pop(1); + + pthread_exit((void*)(intptr_t)res); return NULL; /* żeby kompilator nie marudził */ } @@ -561,7 +594,9 @@ static int gg_resolver_pthread_start(int *fd, void **priv_data, const char *hostname) { struct gg_resolver_pthread_data *data = NULL; - int pipes[2], new_errno; + struct gg_resolver_pthread_params *params = NULL; + int pipes[2], pipe_ready = 0, new_errno; + pthread_barrier_t init_barrier; gg_debug(GG_DEBUG_FUNCTION, "** gg_resolver_pthread_start(%p, %p, \"%s\");\n", fd, priv_data, hostname); @@ -572,51 +607,75 @@ } data = malloc(sizeof(struct gg_resolver_pthread_data)); - if (data == NULL) { - gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() out of memory for resolver data\n"); - return -1; + gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() " + "out of memory for resolver data\n"); + goto cleanup; + } + + params = malloc(sizeof(struct gg_resolver_pthread_params)); + if (params == NULL) { + gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() " + "out of memory for resolver parameters\n"); + goto cleanup; + } + + params->hostname = strdup(hostname); + if (params->hostname == NULL) { + gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() " + "out of memory for hostname\n"); + goto cleanup; } if (socketpair(AF_LOCAL, SOCK_STREAM, 0, pipes) == -1) { gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() unable " "to create pipes (errno=%d, %s)\n", errno, strerror(errno)); - free(data); - return -1; + goto cleanup; } + params->wfd = pipes[1]; + pipe_ready = 1; - data->hostname = strdup(hostname); - - if (data->hostname == NULL) { - gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() out of memory\n"); - new_errno = errno; + if (pthread_barrier_init(&init_barrier, NULL, 2) != 0) { + gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() " + "can't create barrier\n"); goto cleanup; } + params->init_barrier = &init_barrier; - data->wfd = pipes[1]; - - if (pthread_create(&data->thread, NULL, gg_resolver_pthread_thread, data)) { - gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() unable to create thread\n"); - new_errno = errno; + if (pthread_create(&data->thread, NULL, gg_resolver_pthread_thread, params)) { + gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() " + "unable to create thread\n"); + pthread_barrier_destroy(&init_barrier); goto cleanup; } gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() %p\n", data); + /* Poczekaj, aż wątek rozwiązywania nazw potwierdzi odebranie + * parametrów, aby mieć pewność, że go nie zabijemy zanim je zwolni. + */ + pthread_barrier_wait(&init_barrier); + pthread_barrier_destroy(&init_barrier); + *fd = pipes[0]; *priv_data = data; return 0; cleanup: - if (data != NULL) - free(data->hostname); + new_errno = errno; free(data); - close(pipes[0]); - close(pipes[1]); + if (params != NULL) + free(params->hostname); + free(params); + + if (pipe_ready) { + close(pipes[0]); + close(pipes[1]); + } errno = new_errno; @@ -822,10 +881,10 @@ return 0; } -#ifdef GG_CONFIG_HAVE_PTHREAD - type = GG_RESOLVER_PTHREAD; -#elif defined(_WIN32) +#ifdef _WIN32 type = GG_RESOLVER_WIN32; +#elif defined(GG_CONFIG_HAVE_PTHREAD) + type = GG_RESOLVER_PTHREAD; #elif defined(GG_CONFIG_HAVE_FORK) type = GG_RESOLVER_FORK; #endif @@ -949,10 +1008,10 @@ return 0; } -#ifdef GG_CONFIG_HAVE_PTHREAD - type = GG_RESOLVER_PTHREAD; -#elif defined(_WIN32) +#ifdef _WIN32 type = GG_RESOLVER_WIN32; +#elif defined(GG_CONFIG_HAVE_PTHREAD) + type = GG_RESOLVER_PTHREAD; #elif defined(GG_CONFIG_HAVE_FORK) type = GG_RESOLVER_FORK; #endif diff -Nru libgadu-1.12.1/src/sha1.c libgadu-1.12.2/src/sha1.c --- libgadu-1.12.1/src/sha1.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/sha1.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2007 Wojtek Kaniewski * @@ -26,13 +24,12 @@ * \brief Funkcje wyznaczania skrótu SHA1 */ +#include "internal.h" + #include #include -#include "libgadu.h" -#include "internal.h" #include "fileio.h" -#include "config.h" /** \cond ignore */ @@ -305,6 +302,9 @@ if (res == -1 && errno != EINTR) break; + if (res == 0) + break; + if (res != -1) { if (!SHA1_Update(ctx, buf, res)) { res = -1; diff -Nru libgadu-1.12.1/src/tvbuff.c libgadu-1.12.2/src/tvbuff.c --- libgadu-1.12.1/src/tvbuff.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/tvbuff.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2012 Tomek Wasilczyk * @@ -24,13 +22,13 @@ * \brief Bufor wspierający obsługę pakietów typu Type-Value(s) */ +#include "internal.h" + #include #include #include "tvbuff.h" -#include "internal.h" - struct gg_tvbuff { const char *buffer; diff -Nru libgadu-1.12.1/src/tvbuilder.c libgadu-1.12.2/src/tvbuilder.c --- libgadu-1.12.1/src/tvbuilder.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/src/tvbuilder.c 2017-01-21 17:57:03.000000000 +0000 @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * (C) Copyright 2012 Tomek Wasilczyk * @@ -24,12 +22,13 @@ * \brief Bufor wspierający budowanie pakietów typu Type-Value(s) */ +#include "internal.h" + #include #include #include "tvbuilder.h" -#include "internal.h" #include "fileio.h" #include diff -Nru libgadu-1.12.1/test/automatic/connect.c libgadu-1.12.2/test/automatic/connect.c --- libgadu-1.12.1/test/automatic/connect.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/test/automatic/connect.c 2017-01-21 17:57:03.000000000 +0000 @@ -16,6 +16,8 @@ * USA. */ +#include "internal.h" + #include #include #include @@ -26,17 +28,17 @@ #include #include #include -#include "config.h" #if defined(GG_CONFIG_HAVE_PTHREAD) # include #elif defined(_WIN32) # define GG_SIMULATE_WIN32_PTHREAD +#else +/* pthreads are required to run server thread */ +# error "pthreads missing" #endif -#include "libgadu.h" #include "network.h" -#include "internal.h" #ifdef GG_CONFIG_HAVE_GNUTLS #include @@ -298,7 +300,7 @@ #undef gethostbyname #ifdef _WIN32 -static struct hostent *my_gethostbyname(const char *name) +static struct hostent * WSAAPI my_gethostbyname(const char *name) #else struct hostent *gethostbyname(const char *name) #endif @@ -375,7 +377,7 @@ #ifdef _WIN32 static gg_win32_hook_data_t connect_hook; -static int my_connect(SOCKET socket, const struct sockaddr *address, int address_len) +static int WSAAPI my_connect(SOCKET socket, const struct sockaddr *address, int address_len) #else int connect(int socket, const struct sockaddr *address, socklen_t address_len) #endif @@ -536,7 +538,7 @@ #ifdef _WIN32 static gg_win32_hook_data_t get_last_error_hook; -static int my_get_last_error(void) +static int WSAAPI my_get_last_error(void) { int result; diff -Nru libgadu-1.12.1/test/automatic/endian1.c libgadu-1.12.2/test/automatic/endian1.c --- libgadu-1.12.1/test/automatic/endian1.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/test/automatic/endian1.c 2017-01-21 17:57:03.000000000 +0000 @@ -16,14 +16,12 @@ * USA. */ +#include "internal.h" + #include #include #include -#include "config.h" -#include "libgadu.h" -#include "internal.h" - static void test_gg_fix64(void) { const char *source = "\xff\xee\xdd\xcc\xbb\xaa\x99\x88"; diff -Nru libgadu-1.12.1/test/automatic/hash.c libgadu-1.12.2/test/automatic/hash.c --- libgadu-1.12.1/test/automatic/hash.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/test/automatic/hash.c 2017-01-21 17:57:03.000000000 +0000 @@ -16,13 +16,13 @@ * USA. */ +#include "internal.h" + #include #include #include #include -#include "libgadu.h" -#include "internal.h" #include "fileio.h" static inline int @@ -33,7 +33,7 @@ file_mask = S_IRWXO | S_IRWXG; old_umask = umask(file_mask); -#if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) +#ifdef HAVE_MKSTEMP ret = mkstemp(path); #else #ifdef _WIN32 @@ -131,7 +131,7 @@ char name[32]; uint8_t result[20]; - strcpy(name, "hash.XXXXXX"); + strcpy(name, "hashdata.XXXXXX"); fd = gg_mkstemp(name); diff -Nru libgadu-1.12.1/test/automatic/Makefile.am libgadu-1.12.2/test/automatic/Makefile.am --- libgadu-1.12.1/test/automatic/Makefile.am 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/test/automatic/Makefile.am 2017-01-21 17:57:03.000000000 +0000 @@ -1,29 +1,21 @@ -TESTS = convert endian1 message2 message1 hash packet resolver $(OPTIONAL_TESTS_PERL) - -if HAVE_GLIBC -if HAVE_GNUTLS_TESTS -TESTS += connect -endif -else -if HAVE_MINGW -TESTS += connect -endif -endif - -if HAVE_PERL -TESTS += protocol -endif +TESTS = connect convert endian1 hash message1 message2 packet protocol resolver check_PROGRAMS = $(TESTS) -EXTRA_PROGRAMS = convert endian1 message2 message1 hash resolver packet connect protocol AM_CPPFLAGS = -DGG_IGNORE_DEPRECATED -I$(top_srcdir)/include -I$(top_srcdir)/test AM_LDFLAGS = @LDFLAGS_NO_INSTALL@ +EXTRA_DIST = protocol.txt connect.txt connect.pem wine-wrapper.sh skipped.c + +if HAVE_PERL protocol_SOURCES = protocol.c nodist_protocol_SOURCES = script.c libgadu-network.c protocol_CFLAGS = -I$(top_srcdir)/test/automatic/script protocol_LDADD = $(top_builddir)/src/libgadu.la +else +EXTRA_DIST += protocol.c +nodist_protocol_SOURCES = skipped.c +endif convert_SOURCES = convert.c nodist_convert_SOURCES = libgadu-encoding.c @@ -41,27 +33,33 @@ endian1_SOURCES = endian1.c nodist_endian1_SOURCES = libgadu-endian.c +if BUILD_CONNECT_TEST connect_SOURCES = connect.c nodist_connect_SOURCES = libgadu-network.c connect_LDADD = $(top_builddir)/src/libgadu.la @GNUTLS_LIBS@ connect_CFLAGS = @GNUTLS_CFLAGS@ +else +EXTRA_DIST += connect.c +nodist_connect_SOURCES = skipped.c +endif packet_LDADD = $(top_builddir)/src/libgadu.la resolver_LDADD = $(top_builddir)/src/libgadu.la -EXTRA_DIST = protocol.txt connect.txt connect.pem wine-wrapper.sh - SUBDIRS = script script.c: $(wildcard script/*.scr) script/compile $(AM_V_GEN)$(PERL) $(top_srcdir)/test/automatic/script/compile $(top_srcdir)/test/automatic/script/*.scr > script.c clean-local: - rm -f *-valgrind.log *-valgrind script.c libgadu-*.c + rm -f *-valgrind.log *-valgrind script.c skipped.c libgadu-*.c check-local: $(check_PROGRAMS) for i in $(check_PROGRAMS); do ln -sf ../valgrind $${i}-valgrind; done libgadu-%.c: ../../src/%.c $(AM_V_GEN)cat "$<" > "$@" + +skipped.c: + echo 'int main() { return 77; }' > $@ diff -Nru libgadu-1.12.1/test/automatic/message2.c libgadu-1.12.2/test/automatic/message2.c --- libgadu-1.12.1/test/automatic/message2.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/test/automatic/message2.c 2017-01-21 17:57:03.000000000 +0000 @@ -21,7 +21,6 @@ #include #include "libgadu.h" #include "message.h" -#include "config.h" #ifdef HAVE_LIBXML2 #include #include @@ -430,6 +429,13 @@ { size_t i; +#ifdef HAVE_LIBXML2 + if (xmlFindCharEncodingHandler("windows-1250") == NULL) { + printf("WARNING: CP1250 support is missing, forcing ISO-8859-1\n"); + xmlAddEncodingAlias("iso-8859-1", "windows-1250"); + } +#endif + for (i = 0; i < sizeof(text_to_html) / sizeof(text_to_html[0]); i++) { test_text_to_html(text_to_html[i].src, (const unsigned char*) text_to_html[i].attr, diff -Nru libgadu-1.12.1/test/automatic/packet.c libgadu-1.12.2/test/automatic/packet.c --- libgadu-1.12.1/test/automatic/packet.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/test/automatic/packet.c 2017-01-21 17:57:03.000000000 +0000 @@ -16,13 +16,13 @@ * USA. */ +#include "internal.h" + #include #include #include #include -#include "libgadu.h" #include "network.h" -#include "internal.h" enum { EXPECT_NOTHING = 0, @@ -104,7 +104,7 @@ #undef recv #ifdef _WIN32 -static int my_recv(SOCKET fd, char *buf, int len, int flags) +static int WSAAPI my_recv(SOCKET fd, char *buf, int len, int flags) #else ssize_t recv(int fd, void *buf, size_t len, int flags) #endif @@ -255,7 +255,7 @@ #undef send #ifdef _WIN32 -static int my_send(SOCKET fd, const char *buf, int len, int flags) +static int WSAAPI my_send(SOCKET fd, const char *buf, int len, int flags) #else ssize_t send(int fd, const void *buf, size_t len, int flags) #endif @@ -381,7 +381,7 @@ #ifdef _WIN32 -static int my_get_last_error(void) +static int WSAAPI my_get_last_error(void) { return errno; } diff -Nru libgadu-1.12.1/test/automatic/resolver.c libgadu-1.12.2/test/automatic/resolver.c --- libgadu-1.12.1/test/automatic/resolver.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/test/automatic/resolver.c 2017-01-21 17:57:03.000000000 +0000 @@ -16,15 +16,15 @@ * USA. */ +#include "internal.h" + #include -#include "libgadu.h" #include #include #include #include #include "network.h" -#include "internal.h" /* must be different from INADDR_LOOPBACK=127.0.0.1 */ #define LOCALHOST "127.0.0.2" @@ -34,7 +34,7 @@ #undef gethostbyname #ifdef _WIN32 -static inline struct hostent *my_gethostbyname(const char *name) +static struct hostent * WSAAPI my_gethostbyname(const char *name) #else struct hostent *gethostbyname(const char *name) #endif @@ -98,7 +98,7 @@ #ifdef _WIN32 static gg_win32_hook_data_t connect_hook; -static inline int my_connect(int fd, const struct sockaddr *sa, socklen_t sa_len) +static int WSAAPI my_connect(SOCKET s, const struct sockaddr *sa, int sa_len) { int ret; struct sockaddr_in *sin = (struct sockaddr_in *)sa; @@ -111,7 +111,7 @@ } gg_win32_hook_set_enabled(&connect_hook, 0); - ret = connect(fd, sa, sa_len); + ret = connect(s, sa, sa_len); gg_win32_hook_set_enabled(&connect_hook, 1); return ret; @@ -410,6 +410,7 @@ gg_free_session(gs); +#ifdef GG_CONFIG_HAVE_PTHREAD /* Test globalnych ustawień + lokalne */ printf("Testing local pthread resolver\n"); @@ -427,6 +428,7 @@ } gg_free_session(gs); +#endif /* GG_CONFIG_HAVE_PTHREAD */ #endif /* GG_CONFIG_HAVE_FORK */ #ifdef GG_CONFIG_HAVE_PTHREAD diff -Nru libgadu-1.12.1/test/automatic/wine-wrapper.sh libgadu-1.12.2/test/automatic/wine-wrapper.sh --- libgadu-1.12.1/test/automatic/wine-wrapper.sh 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/test/automatic/wine-wrapper.sh 2017-01-21 17:57:03.000000000 +0000 @@ -10,3 +10,7 @@ fi done $newcmd + +# bug: _mktemp_s run on wine creates 0444 chmoded file, +# so it can't remove temp files by itself +rm -rf hashdata.* diff -Nru libgadu-1.12.1/test/manual/dcc7.c libgadu-1.12.2/test/manual/dcc7.c --- libgadu-1.12.1/test/manual/dcc7.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/test/manual/dcc7.c 2017-01-21 17:57:03.000000000 +0000 @@ -16,6 +16,8 @@ * USA. */ +#include "internal.h" + #include #include #include @@ -26,9 +28,7 @@ #include #include -#include "libgadu.h" #include "network.h" -#include "internal.h" #include "userconfig.h" int test_mode; diff -Nru libgadu-1.12.1/test/manual/lib/base64.c libgadu-1.12.2/test/manual/lib/base64.c --- libgadu-1.12.1/test/manual/lib/base64.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/test/manual/lib/base64.c 2017-01-21 17:57:03.000000000 +0000 @@ -19,9 +19,10 @@ #include #include -#include "base64.h" #include "config.h" +#include "base64.h" + #ifdef HAVE_OPENSSL #include @@ -30,7 +31,7 @@ #include #include -char *gg_base64_encode(const char *input, ssize_t len) +char *gg_base64_encode2(const char *input, ssize_t len) { BIO *bmem, *b64; BUF_MEM *bptr; diff -Nru libgadu-1.12.1/test/manual/lib/oauth.c libgadu-1.12.2/test/manual/lib/oauth.c --- libgadu-1.12.1/test/manual/lib/oauth.c 2014-12-20 12:09:17.000000000 +0000 +++ libgadu-1.12.2/test/manual/lib/oauth.c 2017-01-21 17:57:03.000000000 +0000 @@ -16,6 +16,8 @@ * USA. */ +#include "internal.h" + #include #include #include @@ -28,76 +30,71 @@ #include "base64.h" #include "oauth_parameter.h" #include "fileio.h" -#include "internal.h" #ifdef _WIN32 #include #endif +#ifdef HAVE_GNUTLS_2_12 +# include +# include +#elif defined(GG_CONFIG_HAVE_OPENSSL) +# include +#endif + char *gg_oauth_static_nonce; /* dla unit testów */ char *gg_oauth_static_timestamp; /* dla unit testów */ /* copy-paste from common.c */ #define gg_debug(...) -static int gg_rand(void *buff, size_t len) +int gg_rand(void *buff, size_t len) { -#ifdef _WIN32 - HCRYPTPROV hProvider = 0; - int res = 0; +#ifdef HAVE_GNUTLS_2_12 + int res; - if (!CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - { + if (gnutls_global_init() != GNUTLS_E_SUCCESS) { gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR, "// gg_rand() " - "couldn't acquire crypto context\n"); - return -1; + "gnutls init failed\n"); + return 0; } - if (!CryptGenRandom(hProvider, len, buff)) { + res = gnutls_rnd(GNUTLS_RND_NONCE, buff, len); + gnutls_global_deinit(); + + if (res != GNUTLS_E_SUCCESS) { gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR, "// gg_rand() " - "couldn't fill random buffer\n"); - res = -1; + "gnutls rand failed\n"); + return 0; } - CryptReleaseContext(hProvider, 0); - - return res; -#else - uint8_t *buff_b = buff; - - int fd = open("/dev/random", O_RDONLY); - if (fd < 0) - fd = open("/dev/urandom", O_RDONLY); - if (fd < 0) { + return 1; +#elif defined(GG_CONFIG_HAVE_OPENSSL) + if (RAND_bytes(buff, len) != 1) { gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR, "// gg_rand() " - "couldn't open random device\n"); - return -1; + "openssl rand failed\n"); + return 0; } - while (len > 0) { - /* TODO: handle EINTR */ - ssize_t got_data = read(fd, buff_b, len); - if (got_data < 0) { - gg_debug(GG_DEBUG_MISC | GG_DEBUG_ERROR, "// gg_rand() " - "couldn't read from random device\n"); - close(fd); - return -1; - } + return 1; +#else + size_t i; + uint8_t *bytebuff = buff; - buff_b += got_data; - len -= got_data; + for (i = 0; i < len; i++) { + /* This is not the most efficient way, + * but rand is not a preferred way too. + */ + bytebuff[i] = rand() & 0xFF; } - close(fd); - - return 0; + return 1; #endif } #undef gg_debug static int uniform_rand_10(void) { - uint8_t rval; + uint8_t rval = 255; do { if (gg_rand(&rval, sizeof(rval)) != 0)