cpw.nader.asynclogging-3: 707a4975: Fixed crashes related to reading and lis...
morshed.nader at gmail.com
morshed.nader at gmail.com
Thu Jan 5 15:27:07 EST 2012
----------------------------------------------------------------------
Revision: 707a4975a14984ae2de9ed5c0167adb94a2b893d
Parent: 0b4e54874f6ee7b4bc331766d5cc0b2864e8f8e6
Author: morshed.nader at gmail.com
Date: 01/05/12 07:15:07
Branch: im.pidgin.cpw.nader.asynclogging-3
URL: http://d.pidgin.im/viewmtn/revision/info/707a4975a14984ae2de9ed5c0167adb94a2b893d
Changelog:
Fixed crashes related to reading and listing logs
Fixed listing logs giving incorrect, invalid file paths
Made purple_common_log_list use the same GFileEnumerator code that the _async function uses
Got rid of all the purple_log_get_log_sets code (Now only maintaining the purple_logs... functions)
Fixed some cases where g_return_if_fail was seeing invalid purplelog objects
Changed the get_log_sets_fn code to not require the dummy log object
Changes against parent 0b4e54874f6ee7b4bc331766d5cc0b2864e8f8e6
patched libpurple/commonlog.c
patched libpurple/log.c
patched libpurple/log.h
patched libpurple/oldlog.c
-------------- next part --------------
============================================================
--- libpurple/log.c eefff1f79e8aaf2ab538f0ff41fdd24071ec14b8
+++ libpurple/log.c af903bd8912e9b48f73a8c55b3e92fc0131730ee
@@ -130,8 +130,8 @@ static gssize purple_log_real_total_size
static GList *purple_log_real_list_logs_finish(GAsyncResult *, GError **);
static GList *purple_log_real_list_syslog_finish(GAsyncResult *, GError **);
static gssize purple_log_real_total_size_finish(GAsyncResult *, GError **);
-static GHashTable *purple_log_real_get_log_sets_finish(PurpleLog *,
- GAsyncResult *, GError **);
+static GHashTable *purple_log_real_get_log_sets_finish(GAsyncResult *,
+ GError **);
static GHashTable *log_get_log_sets_common(GCancellable *, GError **);
static void log_get_log_sets_common_async(gint, GCancellable *,
@@ -1151,73 +1151,13 @@ steal_log_sets(gpointer key, gpointer va
return TRUE;
}
-GHashTable *
-purple_log_get_log_sets(PurpleLog *log, GCancellable *cancellable,
- GError **error)
-{
- PurpleLogClass *class;
-
- g_return_val_if_fail(PURPLE_IS_LOG(log), NULL);
-
- class = PURPLE_LOG_GET_CLASS(log);
-
- if (class->get_log_sets_fn == NULL) {
- g_set_error_literal(error,
- G_IO_ERROR,
- G_IO_ERROR_NOT_SUPPORTED,
- _("Operation not supported"));
-
- return NULL;
- }
-
- return class->get_log_sets_fn(log, cancellable, error);
-}
-
-void
-purple_log_get_log_sets_async(PurpleLog *log, gint io_priority,
- GCancellable *cancellable, GAsyncReadyCallback cb, gpointer userdata)
-{
- PurpleLogClass *class;
-
- g_return_if_fail(PURPLE_IS_LOG(log));
-
- class = PURPLE_LOG_GET_CLASS(log);
-
- if (class->get_log_sets_async == NULL)
- _notify_not_supported(G_OBJECT(log), cb, userdata);
- else
- class->get_log_sets_async(log, io_priority, cancellable, cb, userdata);
-}
-
static GHashTable *
-purple_log_real_get_log_sets_finish(PurpleLog *log, GAsyncResult *res,
- GError **error)
+purple_log_real_get_log_sets_finish(GAsyncResult *res, GError **error)
{
return g_hash_table_ref(g_simple_async_result_get_op_res_gpointer(G_SIMPLE_ASYNC_RESULT(res)));
}
GHashTable *
-purple_log_get_log_sets_finish(PurpleLog *log, GAsyncResult *res,
- GError **error)
-{
- g_return_val_if_fail(log == NULL || PURPLE_IS_LOG(log), NULL);
- g_return_val_if_fail(G_IS_ASYNC_RESULT(res), NULL);
-
- if (G_IS_SIMPLE_ASYNC_RESULT(res)) {
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT(res);
-
- if (g_simple_async_result_propagate_error(simple, error))
- return NULL;
- }
-
- if (log == NULL)
- /* Result of purple_log_common */
- return g_hash_table_ref(g_simple_async_result_get_op_res_gpointer(G_SIMPLE_ASYNC_RESULT(res)));
- else
- return PURPLE_LOG_GET_CLASS(log)->get_log_sets_finish(log, res, error);
-}
-
-GHashTable *
purple_logs_get_log_sets(GCancellable *cancellable, GError **error)
{
GArray *array;
@@ -1231,28 +1171,21 @@ purple_logs_get_log_sets(GCancellable *c
array = purple_log_logger_get_all();
for (i = 0; i < array->len; i++) {
- PurpleLog *log;
- GType log_type = g_array_index(array, GType, i);
+ PurpleLogClass *klass = g_array_index(array, PurpleLogClass *, i);
- log = g_object_new(log_type, NULL);
- one_set = purple_log_get_log_sets(log, cancellable, &err);
+ if (klass->get_log_sets_fn == NULL)
+ continue;
- if (one_set == NULL) {
- g_object_unref(log);
+ one_set = klass->get_log_sets_fn(cancellable, &err);
- if (err->code == G_IO_ERROR_NOT_SUPPORTED) {
- g_clear_error(&err);
- continue;
- } else {
- g_propagate_error(error, err);
- g_hash_table_destroy(sets);
- return NULL;
- }
+ if (one_set == NULL) {
+ g_propagate_error(error, err);
+ g_hash_table_destroy(sets);
+ return NULL;
}
g_hash_table_foreach_steal(one_set, steal_log_sets, sets);
g_hash_table_destroy(one_set);
- g_object_unref(log);
}
one_set = log_get_log_sets_common(cancellable, error);
@@ -1289,11 +1222,15 @@ purple_logs_get_log_sets_async(gint io_p
/* Get the log sets from all the loggers. */
for (i = 0; i < array->len; i++) {
- GType log_type = g_array_index(array, GType, i);
- PurpleLog *log = g_object_new(log_type, NULL);
+ PurpleLogClass *klass = g_array_index(array, PurpleLogClass *, i);
- purple_log_get_log_sets_async(log, io_priority, cancellable,
- log_hash_cb, callback_data);
+ if (klass->get_log_sets_async == NULL) {
+ callback_data->counter--;
+ continue;
+ }
+
+ klass->get_log_sets_async(io_priority, cancellable, log_hash_cb,
+ callback_data);
}
log_get_log_sets_common_async(io_priority, cancellable, log_hash_cb,
@@ -1723,7 +1660,7 @@ purple_log_system_init(void)
{
void *handle = purple_log_system_get_handle();
- loggers = g_array_sized_new(FALSE, FALSE, sizeof(GType), 3);
+ loggers = g_array_sized_new(FALSE, FALSE, sizeof(PurpleLogClass *), 3);
purple_prefs_add_none("/purple/logging");
purple_prefs_add_bool("/purple/logging/log_ims", TRUE);
@@ -2169,17 +2106,14 @@ log_hash_cb(GObject *object, GAsyncResul
log_hash_cb(GObject *object, GAsyncResult *res, gpointer userdata)
{
_purple_log_sets_callback_data *callback_data = userdata;
- PurpleLog *log = PURPLE_LOG(object);
GError *error = NULL;
GHashTable *one_set;
- one_set = purple_log_get_log_sets_finish(log, res, &error);
+ one_set = purple_logs_get_log_sets_finish(res, &error);
if (one_set == NULL) {
- if (error->code != G_IO_ERROR_NOT_SUPPORTED)
- purple_debug_error("log", "Error getting log sets for %s: %s\n",
- log != NULL ? PURPLE_LOG_GET_CLASS(log)->logger_name : "log_list_log_sets_common",
- error->message);
+ purple_debug_error("log", "Error getting log sets: %s\n",
+ error->message);
} else {
g_hash_table_foreach_steal(one_set, steal_log_sets,
callback_data->sets);
============================================================
--- libpurple/log.h 614b8c711936fe92f5efed11d1b470b7fb02a9a8
+++ libpurple/log.h 2e5e14c1a81e72c3d90381b6830cd71815edc6b9
@@ -217,16 +217,14 @@ struct _PurpleLogClass {
* Loggers which implement this function must create a PurpleLogSet,
* then call @a cb with @a sets and the newly created PurpleLogSet.
*/
- GHashTable * (* get_log_sets_fn) (PurpleLog *log, GCancellable *cancellable,
- GError **error);
+ GHashTable * (* get_log_sets_fn) (GCancellable *cancellable, GError **error);
/** Asynchronously gets all available log sets */
- void (* get_log_sets_async) (PurpleLog *log, gint io_priority,
- GCancellable *cancellable, GAsyncReadyCallback cb, gpointer userdata);
+ void (* get_log_sets_async) (gint io_priority, GCancellable *cancellable,
+ GAsyncReadyCallback cb, gpointer userdata);
/** Finishes an asynchronous get log sets operation */
- GHashTable * (* get_log_sets_finish) (PurpleLog *log, GAsyncResult *res,
- GError **error);
+ GHashTable * (* get_log_sets_finish) (GAsyncResult *res, GError **error);
/** Removes a log */
gboolean (* remove_fn) (PurpleLog *log, GCancellable *cancellable,
@@ -643,59 +641,6 @@ gssize purple_logs_get_total_size_finish
gssize purple_logs_get_total_size_finish(GAsyncResult *res, GError **error);
/**
- * Returns a hash table of log sets.
- *
- * A "log set" here means the information necessary to gather the
- * PurpleLogs for a given buddy/chat. This information would be passed
- * to purple_log_get_log to get a list of logs.
- *
- * The primary use of this function is to get a list of everyone the
- * user has ever talked to (assuming he or she uses logging).
- *
- * The table that's returned will free all log sets in it when
- * destroyed. If a log set is removed from the table, it
- * must be freed with purple_log_set_free().
- *
- * @param log A dummy log of the type of logger to use
- * @param cancellable (allow-none): GCancellable object
- * @param error (out) (allow-none): a GError location to store the error
- *
- * @return A table of all available unique log sets
- */
-GHashTable *purple_log_get_log_sets(PurpleLog *log, GCancellable *cancellable,
- GError **error);
-
-/**
- * Asychronously gets a hash table of log sets.
- * For more details, see purple_log_get_log_sets().
- *
- * @param log A dummy log of the type of logger to use
- * @param io_priority The io priority of the request
- * @param cancellable (allow-none): GCancellable object
- * @param cb (allow-none): A GAsyncReadyCallback to call when the
- request is satisfied
- * @param userdata (allow-none): The data to pass to callback function
- *
- * @since 3.0.0
- */
-void purple_log_get_log_sets_async(PurpleLog *log, gint io_priority,
- GCancellable *cancellable, GAsyncReadyCallback cb, gpointer userdata);
-
-/**
- * Finishes asynchronously getting a hash table of log sets
- *
- * @param log A dummy log of the type of logger to use
- * @param res A GAsyncResult
- * @param error (out) (allow-none): a GError location to store the error
- *
- * @return The hash table of log sets or %NULL on error
- *
- * @since 3.0.0
- */
-GHashTable *purple_log_get_log_sets_finish(PurpleLog *log, GAsyncResult *res,
- GError **error);
-
-/**
* Gets a hash table for the combined log sets of all accounts.
* See purple_log_get_log_sets() for more details.
*
============================================================
--- libpurple/oldlog.c acd0976061d273561c46e7af9ce9a56f037bf90a
+++ libpurple/oldlog.c d269cc7cc81e499e0b5e0a326c1e3823e94fb363
@@ -31,39 +31,10 @@ PurpleLogClass *old_klass = NULL;
G_DEFINE_TYPE (PurpleOldLog, purple_old_log, PURPLE_TYPE_COMMON_LOG)
PurpleLogClass *old_klass = NULL;
-static GList *purple_old_log_list(PurpleLogChatType, const gchar *,
- PurpleAccount *, GCancellable *, GError **);
-static gint purple_old_log_total_size(PurpleLogChatType,
- const gchar *, PurpleAccount *, GCancellable *, GError **);
-static gchar *purple_old_log_read(PurpleLog *, PurpleLogReadFlags *,
- GCancellable *, GError **);
-static GHashTable *purple_old_log_get_log_sets(PurpleLog *, GCancellable *,
- GError **);
-
-
/**
* The old logger doesn't write logs, only reads them. This is to include
* old logs in the log viewer transparently.
*/
-static void
-purple_old_log_class_init(PurpleOldLogClass *class)
-{
- PurpleLogClass *log_class = PURPLE_LOG_CLASS(class);
-
- log_class->logger_name = _("Old flat format");
- log_class->logger_id = "old";
-
- log_class->list_fn = purple_old_log_list;
- log_class->read_fn = purple_old_log_read;
- log_class->total_size_fn = purple_old_log_total_size;
- log_class->get_log_sets_fn = purple_old_log_get_log_sets;
-}
-
-static void
-purple_old_log_init(PurpleOldLog *old_log)
-{
-}
-
/* XXX: Needs testing!!! */
static GList *
purple_old_log_list(PurpleLogChatType chat_type, const gchar *sn,
@@ -473,8 +444,7 @@ static GHashTable *
}
static GHashTable *
-purple_old_log_get_log_sets(PurpleLog *log, GCancellable *cancellable,
- GError **error)
+purple_old_log_get_log_sets(GCancellable *cancellable, GError **error)
{
PurpleBlistNode *gnode, *cnode, *bnode;
PurpleBuddy *buddy;
@@ -589,6 +559,25 @@ purple_old_log_get_log_sets(PurpleLog *l
return sets;
}
+static void
+purple_old_log_class_init(PurpleOldLogClass *class)
+{
+ PurpleLogClass *log_class = PURPLE_LOG_CLASS(class);
+
+ log_class->logger_name = _("Old flat format");
+ log_class->logger_id = "old";
+
+ log_class->list_fn = purple_old_log_list;
+ log_class->read_fn = purple_old_log_read;
+ log_class->total_size_fn = purple_old_log_total_size;
+ log_class->get_log_sets_fn = purple_old_log_get_log_sets;
+}
+
+static void
+purple_old_log_init(PurpleOldLog *old_log)
+{
+}
+
void
purple_old_log_system_init(void)
{
============================================================
--- libpurple/commonlog.c 7757634c9565ef02ad7fd522d588cd7852a7c99c
+++ libpurple/commonlog.c 368445850bb030be3cc0b4d8d30a7a3a4802189e
@@ -771,7 +771,8 @@ purple_common_log_read_async_2(GIOChanne
return FALSE;
}
- memcpy(data->contents + data->size, buffer, bytes);
+ data->contents = tmp;
+ memcpy(data->contents + data->size, buffer, sizeof(gchar) * bytes);
data->size += bytes;
return TRUE;
@@ -829,19 +830,21 @@ static PurpleLog *
/* XXX: Poorly named */
static PurpleLog *
-create_log(const gchar *dir, const gchar *filename, PurpleLogChatType chat_type,
- const gchar *name, PurpleAccount *account, PurpleLogClass *klass)
+create_log(const gchar *path, PurpleLogChatType chat_type, const gchar *name,
+ PurpleAccount *account, PurpleLogClass *klass)
{
PurpleLog *log;
- gchar *tmp;
+ gchar *basename;
struct tm tm;
#if defined (HAVE_TM_GMTOFF) && defined (HAVE_STRUCT_TM_TM_ZONE)
long tz_off;
const gchar *rest, *end;
time_t stamp;
- stamp = purple_str_to_time(purple_unescape_filename(filename),
+ basename = g_path_get_basename(path);
+ stamp = purple_str_to_time(purple_unescape_filename(basename),
FALSE, &tm, &tz_off, &rest);
+ g_free(basename);
/**
* As zero is a valid offset, PURPLE_NO_TZ_OFF means no offset was
@@ -864,15 +867,17 @@ create_log(const gchar *dir, const gchar
g_free(tmp);
}
#else
- time_t stamp = purple_str_to_time(filename, FALSE, &tm, NULL, NULL);
+ time_t stamp;
+ basename = g_path_get_basename(path);
+ stamp = purple_str_to_time(basename, FALSE, &tm, NULL, NULL);
+ g_free(basename);
+
log = purple_log_new(klass, chat_type, name, account, NULL,
stamp, (stamp != 0) ? &tm : NULL);
#endif
- tmp = g_build_filename(dir, filename, NULL);
- purple_common_log_set_path(PURPLE_COMMON_LOG(log), tmp);
- g_free(tmp);
+ purple_common_log_set_path(PURPLE_COMMON_LOG(log), path);
return log;
}
@@ -882,10 +887,11 @@ purple_common_log_list(PurpleLogChatType
PurpleAccount *account, const gchar *ext, PurpleLogClass *klass,
GCancellable *cancellable, GError **error)
{
- GDir *dir;
GError *err = NULL;
+ GFile *dir;
+ GFileEnumerator *enumerator;
+ GFileInfo *info;
GList *list = NULL;
- const gchar *filename;
gchar *path;
g_return_val_if_fail(name != NULL, NULL);
@@ -904,42 +910,53 @@ purple_common_log_list(PurpleLogChatType
return NULL;
}
- dir = g_dir_open(path, 0, &err);
+ dir = g_file_new_for_path(path);
+ g_free(path);
- if (dir == NULL) {
+ enumerator = g_file_enumerate_children(dir, G_FILE_ATTRIBUTE_STANDARD_NAME,
+ G_FILE_QUERY_INFO_NONE, cancellable, &err);
+
+ if (enumerator == NULL) {
if (err->code == G_FILE_ERROR_NOENT)
g_clear_error(&err);
else
g_propagate_error(error, err);
- g_free(path);
+ g_object_unref(dir);
return NULL;
}
g_clear_error(&err);
- while ((filename = g_dir_read_name(dir)) != NULL) {
- if (g_cancellable_set_error_if_cancelled(cancellable, error)) {
- g_dir_close(dir);
- g_free(path);
- purple_log_list_free(list);
+ while ((info = g_file_enumerator_next_file(enumerator, cancellable, &err)) != NULL) {
+ GFile *child_file;
+ PurpleLog *log;
+ gchar *child_path;
- return NULL;
+ child_file = g_file_get_child(dir, g_file_info_get_name(info));
+ child_path = g_file_get_path(child_file);
+ g_object_unref(child_file);
+
+ if (!purple_str_has_suffix(child_path, ext)) {
+ g_free(child_path);
+ continue;
}
- if (purple_str_has_suffix(filename, ext) &&
- strlen(filename) >= (17 + strlen(ext))) /* XXX: ? */
- {
- PurpleLog *log = create_log(path, filename, chat_type, name,
- account, klass);
- list = g_list_prepend(list, log);
- }
+ log = create_log(child_path, chat_type, name, account, klass);
+
+ g_free(child_path);
+ list = g_list_prepend(list, log);
}
- g_dir_close(dir);
- g_free(path);
+ g_object_unref(dir);
+ g_object_unref(enumerator);
+ if (err != NULL) {
+ g_propagate_error(error, err);
+ return NULL;
+ }
+
return list;
}
@@ -1041,7 +1058,7 @@ purple_common_log_list_async_3(GObject *
continue;
}
- log = create_log(dir_path, child_path, data->chat_type, data->name,
+ log = create_log(child_path, data->chat_type, data->name,
data->account, data->klass);
g_free(child_path);
More information about the Commits
mailing list