From: <svn...@op...> - 2010-01-23 16:49:59
|
Author: scriptor Date: Sat Jan 23 17:49:49 2010 New Revision: 6019 URL: http://www.opensync.org/changeset/6019 Log: I have removed some leaks. I have also reenabled the destroy function. This was not possible, until I added a copy function. After all, the formats I throw around are container formats: structs with pointers to the actual data. Therefore the name of the struct: "glist_container" ;-) Modified: plugins/ldap-sync/misc/ldap_format_convert.c plugins/ldap-sync/src/ldap_format.c plugins/ldap-sync/src/ldap_format.h plugins/ldap-sync/src/ldap_plugin.h plugins/ldap-sync/tests/check_do_convert_from_to.c Modified: plugins/ldap-sync/misc/ldap_format_convert.c ============================================================================== --- plugins/ldap-sync/misc/ldap_format_convert.c Fri Jan 22 16:45:55 2010 (r6018) +++ plugins/ldap-sync/misc/ldap_format_convert.c Sat Jan 23 17:49:49 2010 (r6019) @@ -27,6 +27,16 @@ #include <errno.h> +#include <glib.h> +#include <libxml/parser.h> +#include <libxml/tree.h> +#include <libxml/xmlmemory.h> +#include <libxml/xmlreader.h> +#include <libxml/xmlschemas.h> +#include <libxml/xpath.h> +#include <libxslt/xslt.h> +#include <libxslt/xsltutils.h> +#include <libxslt/transform.h> #include <opensync/opensync.h> #include <opensync/opensync-data.h> #include <opensync/opensync-format.h> @@ -857,6 +867,9 @@ osync_trace(TRACE_INTERNAL, "Edge converter: \"%s\"\n", osync_objformat_get_name(osync_converter_get_targetformat(l->data))); } } + + osync_list_free(list); + list = NULL; } else { osync_trace(TRACE_ERROR, "%s:%i: WARNING: list = NULL.", __FILE__, __LINE__); } @@ -871,6 +884,9 @@ osync_trace(TRACE_INTERNAL, "Converter: \"%s\"\n", osync_objformat_get_name(osync_converter_get_targetformat(l->data))); } } + + osync_list_free(list); + list = NULL; } else { osync_trace(TRACE_INTERNAL, "%s:%i: WARNING: list = NULL.", __FILE__, __LINE__); } @@ -1238,6 +1254,10 @@ if (format_env) osync_format_env_unref(format_env); + if (result) + osync_free(result); + + xmlCleanupParser(); out: osync_trace(TRACE_EXIT, "%s", __func__); @@ -1253,6 +1273,10 @@ if (format_env) osync_format_env_unref(format_env); + if (result) + osync_free(result); + + xmlCleanupParser(); if (!osync_error_is_set(&error)) { osync_error_set(&error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: Unknown reason.\n", __FILE__, __LINE__); Modified: plugins/ldap-sync/src/ldap_format.c ============================================================================== --- plugins/ldap-sync/src/ldap_format.c Fri Jan 22 16:45:55 2010 (r6018) +++ plugins/ldap-sync/src/ldap_format.c Sat Jan 23 17:49:49 2010 (r6019) @@ -238,6 +238,27 @@ + +void ldap_format_call_free_ldap_entry_function(void *data, void *user_data) +{ + osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, data, user_data); + + + if (data == NULL) { + ldap_plugin_printf("%s:%i: ERROR: data == NULL. Returning.", __FILE__, __LINE__); + osync_trace(TRACE_EXIT_ERROR, "%s: ERROR: data = NULL.", __func__); + return; + } + + + ldap_format_free_ldap_entry(data); + + osync_trace(TRACE_EXIT, "%s", __func__); +} + + + + /** * @brief Frees all data allocated by a GList entry list * @param entrylist List of LDAP entries to be freed. @@ -245,12 +266,6 @@ */ static void ldap_format_free_ldap_entries (GList **entrylist) { - unsigned int i; - - - osync_trace(TRACE_ENTRY, "%s(%p)", __func__, (void *)entrylist); - - if (entrylist == NULL) { goto out; } @@ -260,56 +275,24 @@ } if (g_list_length(*entrylist) < 1) { - goto out; - } - -/* - for (i = 0 ; i < g_list_length(*entrylist) ; i++) - { - ldap_entry *ptr = g_list_nth_data(*entrylist, i); - - ldap_plugin_printf("\n\n%u: About to call ldap_format_free_ldap_entry() for ptr = %p\n\n", i, ptr); + g_list_free(*entrylist); + *entrylist = NULL; - if (ptr) { - ldap_format_free_ldap_entry (ptr); - } - - *entrylist = g_list_remove(*entrylist, ptr); + goto out; } -*/ - GList *list = NULL; - i = 0; - for (list = g_list_first(*entrylist); list; list = g_list_next(list)) { - if (g_list_length(*entrylist) < 1) { - break; - } + // Free the elements of the list: + g_list_foreach(*entrylist, ldap_format_call_free_ldap_entry_function, NULL); - ldap_entry *ptr = list->data; - - ldap_plugin_printf("\n%u: About to call ldap_format_free_ldap_entry() for ptr = %p\n", i, ptr); - - if (ptr) { - ldap_format_free_ldap_entry (ptr); - } - - *entrylist = g_list_remove(*entrylist, ptr); - - i++; - } - - - - - /* Free GList */ + // Now, free the list itself: g_list_free(*entrylist); *entrylist = NULL; + out: - osync_trace(TRACE_EXIT, "%s", __func__); return; } @@ -593,28 +576,227 @@ } + + + + + +/** + * This is NOT just a "shallow" copy of the source_entry. Everything will + * be allocated freshly. + * + */ +osync_bool ldap_format_copy_ldap_entry(const ldap_entry *source_entry, ldap_entry **destination_entry, OSyncError **error) +{ + unsigned int i = 0, j = 0; + + + osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, (void *)source_entry, (void *)destination_entry, (void *)error); + + + if (source_entry == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: source_entry = NULL.", __FILE__, __LINE__); + + goto error; + } + + if (destination_entry == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: destination_entry = NULL.", __FILE__, __LINE__); + + goto error; + } + + + + // We copy the source LDAP entries by creating a destination LDAP entry. + // The memory regions used by the source and the destination LDAP entries + // must be independent from each other, so that they can be freed + // separately. + *destination_entry = (ldap_entry *)g_malloc0(sizeof(ldap_entry)); + if (*destination_entry == NULL) { + ldap_plugin_printf("%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); + osync_trace(TRACE_ERROR, "%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); + exit(1); + } + + memset(*destination_entry, 0, sizeof(ldap_entry)); + + if (source_entry->id) { + (*destination_entry)->id = g_strdup(source_entry->id); + } else { + osync_trace(TRACE_ERROR, "%s:%i: WARNING: source_entry->id = NULL. Ignoring.\n", __FILE__, __LINE__); + (*destination_entry)->id = NULL; + } + + if (source_entry->dn) { + unsigned int len = strlen(source_entry->dn); + gsize n = len > 1024 ? len : 1024; + (*destination_entry)->dn = g_strndup(source_entry->dn, n); + } else { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: source_entry->dn = NULL. Ignoring.\n", __FILE__, __LINE__); + (*destination_entry)->dn = NULL; + } + + + // Count the number of mods: + unsigned int counter; + for ( + counter = 0; + source_entry && source_entry->mods && source_entry->mods[counter]; + counter++ + ) + { + // sic! + ; + } + + + // There are counter plus 1 elements in the mods array. + + // At first, allocate memory just for the pointers to the LDAPMod's. + (*destination_entry)->mods = (LDAPMod **)g_malloc0((counter + 2) * sizeof(LDAPMod *)); + if ((*destination_entry)->mods == NULL) { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: g_malloc0() problem. Exiting.\n", __FILE__, __LINE__); + ldap_plugin_printf("%s:%i: ERROR: g_malloc0() problem. Exiting.", __FILE__, __LINE__); + exit(1); + } + + memset((*destination_entry)->mods, 0, (counter + 2) * sizeof(LDAPMod *)); + + if (counter == 0) { + (*destination_entry)->mods[0] = NULL; + (*destination_entry)->mods[1] = NULL; + } + + + for (j = 0, i = 0; j < counter; j++) + { + LDAPMod *mod = source_entry->mods[j]; + + + (*destination_entry)->mods[i] = NULL; // This will become a real LDAPMod + (*destination_entry)->mods[i + 1] = NULL; // And this is the terminating NULL. + + if (mod) { + // Then allocate memory for the struct LDAPMod. + (*destination_entry)->mods[i] = g_malloc0(sizeof(LDAPMod)); + if ((*destination_entry)->mods[i] == NULL) { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); + ldap_plugin_printf("%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); + exit(1); + } + + memset((*destination_entry)->mods[i], 0, sizeof(LDAPMod)); + + if ((*destination_entry)->mods[i]) { + (*destination_entry)->mods[i]->mod_op = LDAP_MOD_BVALUES; + (*destination_entry)->mods[i]->mod_type = g_strdup(mod->mod_type); + + // Allocate memory just for the pointers to the struct berval's: + (*destination_entry)->mods[i]->mod_bvalues = (struct berval **)g_malloc0(2 * sizeof(struct berval *)); + if ((*destination_entry)->mods[i]->mod_bvalues == NULL) { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); + ldap_plugin_printf("%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); + exit(1); + } + + memset((*destination_entry)->mods[i]->mod_bvalues, 0, 2 * sizeof(struct berval *)); + + if ((*destination_entry)->mods[i]->mod_bvalues) { + (*destination_entry)->mods[i]->mod_bvalues[1] = NULL; // terminating NULL. + // And now allocate memory for the structs themselves: + (*destination_entry)->mods[i]->mod_bvalues[0] = (struct berval *)g_malloc0(sizeof(struct berval)); + if ((*destination_entry)->mods[i]->mod_bvalues[0]) { + memset((*destination_entry)->mods[i]->mod_bvalues[0], 0, sizeof(struct berval)); + (*destination_entry)->mods[i]->mod_bvalues[0]->bv_val = g_strdup(mod->mod_bvalues[0]->bv_val); + (*destination_entry)->mods[i]->mod_bvalues[0]->bv_len = mod->mod_bvalues[0]->bv_len; + } else { + osync_trace(TRACE_ERROR, "%s:%i: g_malloc0() problem. Exiting.", __FILE__, __LINE__); + ldap_plugin_printf("%s:%i: g_malloc0() problem. Exiting.", __FILE__, __LINE__); + exit(1); + } + } else { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); + ldap_plugin_printf("%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); + exit(1); + } + + // Advance in loop + i = i + 1; + + // Safety check + if (i > counter) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: i = %i, counter = %i, j = %i", __FILE__, __LINE__, i, counter, j); + goto error; + } + } // if ((*destination_entry)->mods[i]) + else { + ldap_plugin_printf("%s:%i: ERROR: g_malloc0() problem. Exiting.", __FILE__, __LINE__); + osync_trace(TRACE_ERROR, "%s:%i: ERROR: g_malloc0() problem. Exiting.", __FILE__, __LINE__); + exit(1); + } + } else { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: mod = NULL. Ignoring. i = %i, j = %i\n", __FILE__, __LINE__, i, j); + } + } // for (j = 0, i = 0; j < counter; j++) + + + osync_trace(TRACE_EXIT, "%s", __func__); + return TRUE; + +error: + if (!osync_error_is_set(error)) + osync_error_set(error, OSYNC_ERROR_GENERIC, "Unknown reason.\n"); + + osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); + return FALSE; +} + + + + + + + + + + + + + + + + + + + + + + + + /** * @brief This function creates a GList of ldap entries a GList of * any possible ldap subentries out of list of ldapmods * * @param dn The distinguished name (DN) of the LDAP entry. - * This is the location in the DIT where the entry and - * its subentries are to be stored. - * @param ldapmods - * @param potential_subentries The resulting list of LDAP subentries. They have + * This is the location in the DIT where the entry and + * its subentries are to be stored. + * @param ldapmods These LDAPMod's are the result from having parsed the + * XML file. + * @param potential_subentries The list of LDAP subentries. They have * id and dn set, already. - * @param ldap_entries The resulting list of LDAP entries. None of them - * has set id and dn, yet. + * @param ldap_entries As a result of this function this list of LDAP entries + * will be created. None of them has set id and dn, yet. * @param error The libopensync error pointer. * * @returns TRUE on success, FALSE in case of any error. */ -static osync_bool ldap_format_create_ldap_entries_list_from_ldapmods(const char *dn, GList *ldapmods, GList **potential_subentries, GList **ldap_entries, OSyncError **error) +static osync_bool ldap_format_create_ldap_entries_list_from_ldapmods(const char *dn, GList *ldapmods, GList *potential_subentries, GList **ldap_entries, OSyncError **error) { ldap_entry *entry = NULL; GList *list = NULL; - unsigned int i = 0; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %p)", __func__, (void *)dn, (void *)ldapmods, (void *)potential_subentries, (void *)ldap_entries, (void *)error); @@ -631,10 +813,13 @@ goto error; } +// Uhmmm, this can be NULL, can't it? +/* if (potential_subentries == NULL) { osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: potential_subentries = NULL.\n", __FILE__, __LINE__); goto error; } +*/ if (ldap_entries == NULL) { osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_entries = NULL.\n", __FILE__, __LINE__); @@ -649,10 +834,7 @@ } - if (ldapmods) { - ldap_format_free_ldapmods_list(ldapmods); - ldapmods = NULL; - } + @@ -672,111 +854,19 @@ - - - // Any further entries are subentries one level below of this // base entry in the DIT. // Walk through the source list of LDAP entries. - for (list = g_list_first(*potential_subentries); list; list = g_list_next(list)) { + for (list = g_list_first(potential_subentries); list; list = g_list_next(list)) { ldap_entry *single_entry = NULL; if (list->data) { - // We copy the source LDAP entries by creating a destination LDAP entry. - // The memory regions used by the source and the destination LDAP entries - // must be independent from each other, so that they can be freed - // separately. - single_entry = (ldap_entry *)g_malloc0(sizeof(ldap_entry)); - if (single_entry == NULL) { - ldap_plugin_printf("%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); - osync_trace(TRACE_ERROR, "%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); - exit(1); - } - - if (((ldap_entry *)(list->data))->id) { - single_entry->id = g_strdup(((ldap_entry *)(list->data))->id); - } else { - osync_trace(TRACE_ERROR, "%s:%i: WARNING: (list->data)->id = NULL. Ignoring.\n", __FILE__, __LINE__); - single_entry->id = NULL; - } - - if (((ldap_entry *)(list->data))->dn) { - single_entry->dn = g_strdup(((ldap_entry *)(list->data))->dn); - } else { - osync_trace(TRACE_ERROR, "%s:%i: ERROR: (list->data)->dn = NULL. Ignoring.\n", __FILE__, __LINE__); - single_entry->dn = NULL; - } - - - // Count the number of mods: - unsigned int counter; - for (counter = 0; ((ldap_entry *)(list->data))->mods[counter]; counter++) - ; - - - // There are counter plus 1 elements in the mods array. + if (!ldap_format_copy_ldap_entry((ldap_entry *)(list->data), &single_entry, error)) { + if (!osync_error_is_set(error)) + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_format_copy_ldap_entry() has failed.", __FILE__, __LINE__); - // At first, allocate memory just for the pointers to the LDAPMod's. - single_entry->mods = (LDAPMod **)g_malloc0((counter + 2) * sizeof(LDAPMod *)); - if (single_entry->mods == NULL) { - osync_trace(TRACE_ERROR, "%s:%i: ERROR: g_malloc0() problem. Exiting.\n", __FILE__, __LINE__); - ldap_plugin_printf("%s:%i: ERROR: g_malloc0() problem. Exiting.", __FILE__, __LINE__); - exit(1); + goto error; } - - unsigned int j = 0; - for (j = 0, i = 0; j < counter; j++) - { - LDAPMod *mod = ((ldap_entry *)(list->data))->mods[j]; - - - if (mod) { - // Then allocate memory for the struct LDAPMod. - single_entry->mods[i] = g_malloc0(sizeof(LDAPMod)); - if (single_entry->mods[i] == NULL) { - osync_trace(TRACE_ERROR, "%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); - ldap_plugin_printf("%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); - exit(1); - } - - if (single_entry->mods[i]) { - single_entry->mods[i]->mod_op = LDAP_MOD_BVALUES; - single_entry->mods[i]->mod_type = g_strdup(mod->mod_type); - single_entry->mods[i]->mod_bvalues = (struct berval **)g_malloc0(2 * sizeof(struct berval *)); - if (single_entry->mods[i]->mod_bvalues) { - single_entry->mods[i]->mod_bvalues[1] = NULL; // terminating NULL. - single_entry->mods[i]->mod_bvalues[0] = (struct berval *)g_malloc0(sizeof(struct berval)); - if (single_entry->mods[i]->mod_bvalues[0]) { - single_entry->mods[i]->mod_bvalues[0]->bv_val = g_strdup(mod->mod_bvalues[0]->bv_val); - single_entry->mods[i]->mod_bvalues[0]->bv_len = mod->mod_bvalues[0]->bv_len; - } else { - osync_trace(TRACE_ERROR, "%s:%i: g_malloc0() problem. Exiting.", __FILE__, __LINE__); - ldap_plugin_printf("%s:%i: g_malloc0() problem. Exiting.", __FILE__, __LINE__); - exit(1); - } - } else { - osync_trace(TRACE_ERROR, "%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); - ldap_plugin_printf("%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); - exit(1); - } - - i = i + 1; - - if (i > counter) { - osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: i = %i, counter = %i, j = %i", __FILE__, __LINE__, i, counter, j); - goto error; - } - } // if (single_entry->mods[i]) - else { - ldap_plugin_printf("%s:%i: ERROR: g_malloc0() problem. Exiting.", __FILE__, __LINE__); - osync_trace(TRACE_ERROR, "%s:%i: ERROR: g_malloc0() problem. Exiting.", __FILE__, __LINE__); - exit(1); - } - } else { - osync_trace(TRACE_ERROR, "%s:%i: ERROR: mod = NULL. Ignoring. i = %i, j = %i\n", __FILE__, __LINE__, i, j); - } - } // for (j = 0, i = 0; j < counter; j++) - } else { osync_trace(TRACE_ERROR, "%s:%i: ERROR: list->data = NULL. Ignoring.\n", __FILE__, __LINE__); } @@ -786,13 +876,13 @@ - + // Add the resulting subentry to the GList of ldap_entry structs: if (single_entry) { *ldap_entries = g_list_append(*ldap_entries, single_entry); } else { osync_trace(TRACE_ERROR, "%s:%i: ERROR: single_entry = NULL. The whole copy procedure has failed. Ignoring.\n", __FILE__, __LINE__); } - } // for (GList *list = g_list_first(*potential_subentries); list; list = g_list_next(list)) + } // for (GList *list = g_list_first(potential_subentries); list; list = g_list_next(list)) @@ -1697,7 +1787,6 @@ osync_error_set(error, OSYNC_ERROR_GENERIC, "Unknown reason.\n"); osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); - return FALSE; } @@ -1937,7 +2026,6 @@ osync_error_set(error, OSYNC_ERROR_GENERIC, "Unknown reason.\n"); osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); - return FALSE; } @@ -2445,7 +2533,7 @@ } - +#if 0 /** * @note * The following call to osync_xmlformat_copy() is a workaround for @@ -2494,6 +2582,8 @@ goto error; } +#endif + // Report the results to the calling function *output = (char *) xmlformat; @@ -3545,6 +3635,7 @@ if (name) { if (name[0]) { if (!strncmp((char *)name, "EMail", 5)) { + xmlFree(name); name = xmlStrdup((xmlChar *)"EMail"); } } @@ -3556,6 +3647,7 @@ if (name) { if (name[0]) { if (!strncmp((char *)name, "AddressLabel", 12)) { + xmlFree(name); name = xmlStrdup((xmlChar *)"AddressLabel"); } } @@ -3567,6 +3659,7 @@ if (name) { if (name[0]) { if (!strncmp((char *)name, "Telephone", 9)) { + xmlFree(name); name = xmlStrdup((xmlChar *)"Telephone"); } } @@ -4404,7 +4497,7 @@ GList *ldapmods = NULL; - // Parse child nodes of root + // Parse child nodes of root and write them to potential_subentries GList and to the ldapmods list. if (!ldap_format_parse_xmlinternal_child_nodes(xmlnode, objtype, dn, &complex_element_lists, potential_subentries, &ldapmods, error)) { if (!osync_error_is_set(error)) { osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_format_parse_child_nodes() has failed.\n", __FILE__, __LINE__); @@ -4413,9 +4506,14 @@ } + if (potential_subentries == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: potential_subentries has become NULL after having called ldap_format_parse_xmlinternal_child_nodes(). Returning NULL.\n", __FILE__, __LINE__); + goto error; + } + // Create a list of LDAP entries and a list of LDAP subentries out of these ldapmods: - if (!ldap_format_create_ldap_entries_list_from_ldapmods(dn, ldapmods, potential_subentries, ldap_entries, error)) { + if (!ldap_format_create_ldap_entries_list_from_ldapmods(dn, ldapmods, *potential_subentries, ldap_entries, error)) { if (!osync_error_is_set(error)) { osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR ldap_format_ldap_entry_from_ldapmods_wrapper() has failed.", __FILE__, __LINE__); } @@ -4442,11 +4540,20 @@ ldap_format_free_complex_element_lists(&complex_element_lists.address); ldap_format_free_complex_element_lists(&complex_element_lists.telephone); + if (ldapmods) { + ldap_format_free_ldapmods_list(ldapmods); + ldapmods = NULL; + } osync_trace(TRACE_EXIT, "%s", __func__); return TRUE; error: + if (ldapmods) { + ldap_format_free_ldapmods_list(ldapmods); + ldapmods = NULL; + } + if (!osync_error_is_set(error)) osync_error_set(error, OSYNC_ERROR_GENERIC, "Unknown reason.\n"); @@ -4755,6 +4862,13 @@ * Problem: This does not seem to work. I have always set it to FALSE. * But libopensync does not care about it. * See also ldap_format_destroy_format1() + * The problem lies in osync_format_env_detect_objformat_full(), + * which does not take notice of free_input: + * + * 1127 // Make a copy of the data + * 1128 new_data = osync_data_clone(input, error); + * (...) + * 1164 osync_data_unref(new_data); * * @param ldap_format_name The name of the source format. * @param xmlformat_name The name of the target format. @@ -4835,7 +4949,7 @@ ldap_plugin_printf("%s:%i: ERROR: inpsize = %i. Calling abort()\n", __FILE__, __LINE__, inpsize); abort(); #else - osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: inpsize = %i.\n", __FILE__, __LINE__, inpsize); + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i:%s(): ERROR: inpsize = %i.\n", __FILE__, __LINE__, __func__, inpsize); goto error; #endif @@ -4926,6 +5040,11 @@ if (!osync_error_is_set(error)) osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_format_parse_ldif() has failed.\n", __FILE__, __LINE__); + if (ldap_entries) { + ldap_format_free_ldap_entries(&ldap_entries); + ldap_entries = NULL; + } + goto error; } @@ -4940,10 +5059,21 @@ if (!osync_error_is_set(error)) osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_format_pre_stylesheet() has failed.\n", __FILE__, __LINE__); + if (ldap_entries) { + ldap_format_free_ldap_entries(&ldap_entries); + ldap_entries = NULL; + } + goto error; } + // Free ldap_entries + if (ldap_entries) { + ldap_format_free_ldap_entries(&ldap_entries); + ldap_entries = NULL; + } + // Now, xmlbuff and size should be set: goto applying_stylesheet; @@ -4960,7 +5090,7 @@ } goto error; - } + } // if (inpsize != sizeof(glist_container)) // Assuming it is a glist_container struct: @@ -4999,7 +5129,9 @@ goto error; } - + + + applying_stylesheet: if (xmlbuff == NULL) { osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: xmlbuff = NULL. Nothing to do here.\n", __FILE__, __LINE__); @@ -5023,9 +5155,9 @@ } - osync_trace(TRACE_INTERNAL, "%s:%i: Setting *free_input to FALSE.", __FILE__, __LINE__); + osync_trace(TRACE_INTERNAL, "%s:%i:%s(): Setting *free_input to FALSE.", __FILE__, __LINE__, __func__); *free_input = FALSE; // But the destroy function is called, anyway??? - + // *free_input = TRUE; // Clean up if (xmlbuff) { @@ -5343,7 +5475,7 @@ *outpsize = sizeof(glist_container); - osync_trace(TRACE_INTERNAL, "%s:%i: Setting *free_input to FALSE.", __FILE__, __LINE__); + osync_trace(TRACE_INTERNAL, "%s:%i:%s(): Setting *free_input to FALSE.", __FILE__, __LINE__, __func__); *free_input = FALSE; // But the destroy function is called, anyway??? @@ -5909,20 +6041,29 @@ osync_trace(TRACE_INTERNAL, "%s:%i:%s():\n\n\ndestroy function has been called for input = %p\n\n\n", __FILE__, __LINE__, __func__, (void *)input); - // First off, try and find out what type of data has been casted to char * + if (input == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: input = NULL.", __FILE__, __LINE__); + goto error; + } + +#ifdef DEBUG_destroy_function + ldap_plugin_printf("\n%s:%i:%s(): input = %p\n", __FILE__, __LINE__, __func__, (void *)input); +#endif + + // First off, print some bytes of input to the trace files. osync_trace(TRACE_INTERNAL, "%s:%i: What is input? inpsize = %u", __FILE__, __LINE__, inpsize); GString *str = NULL; ldap_plugin_dump_bytes((unsigned char *)input, inpsize < 128 ? inpsize : 128, &str, error); if (str == NULL) { - osync_trace(TRACE_ERROR, "%s:%i: ERROR: str = NULL.", __FILE__, __LINE__); - return FALSE; + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: str = NULL.", __FILE__, __LINE__); + goto error; } if (str->str == NULL) { - osync_trace(TRACE_ERROR, "%s:%i: ERROR: str->str = NULL.", __FILE__, __LINE__); - return FALSE; + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: str->str = NULL.", __FILE__, __LINE__); + goto error; } osync_trace(TRACE_INTERNAL, "%s:%i:\n\"%s\"\n", __FILE__, __LINE__, (char *)(str->str)); @@ -5931,6 +6072,8 @@ g_string_free(str, TRUE); + + // Try and find out what type of data has been casted to char * if (inpsize == osync_xmlformat_size()) { osync_trace(TRACE_INTERNAL, "Looks like the opensync specific xmlformat.\n"); @@ -5941,40 +6084,304 @@ osync_trace(TRACE_INTERNAL, "Looks like an xmlDoc."); } else if (inpsize == sizeof(glist_container)) { + glist_container *tmp = NULL; + + osync_trace(TRACE_INTERNAL, "Looks like a glist_container."); + tmp = (glist_container *)input; + if (tmp->magic) { + if (!strncmp(tmp->magic, "glist_container", 15)) { + osync_trace(TRACE_INTERNAL, "It is a glist_container."); + if (tmp->format_name) { + osync_trace(TRACE_INTERNAL, "format_name = \"%s\"", tmp->format_name); + } + + osync_trace(TRACE_INTERNAL, "Address of glist: %p", (void *)(tmp->list)); +#ifdef DEBUG_destroy_function + ldap_plugin_printf("%s:%i:%s(): Address of glist: %p", __FILE__, __LINE__, __func__, (void *)(tmp->list)); +#endif + + if (tmp->list) { + osync_trace(TRACE_INTERNAL, "Number of elements: %i", g_list_length(tmp->list)); +#ifdef DEBUG_destroy_function + ldap_plugin_printf("%s:%i:%s(): Number of elements: %i\n\n", __FILE__, __LINE__, __func__, g_list_length(tmp->list)); +#endif + + +#if 0 +/* + +When number of elements is just 1, I got: + +Number of elements: 1 + + +==14006== Thread 5: +==14006== Invalid free() / delete / delete[] +==14006== at 0x4A04D72: free (vg_replace_malloc.c:325) +==14006== by 0x58D7A69: ldap_format_free_ldap_entry_function (ldap_format.c:192) +==14006== by 0x58D7CDD: ldap_format_call_free_ldap_entry (ldap_format.c:254) +==14006== by 0x38EA636C1B: g_list_foreach (in /lib64/libglib-2.0.so.0.2200.2) +==14006== by 0x58E45B1: ldap_format_destroy_format1 (ldap_format.c:6117) +==14006== by 0x4C7162A: osync_objformat_destroy (opensync_objformat.c:152) +==14006== by 0x4C576E7: osync_data_unref (opensync_data.c:65) +==14006== by 0x4C56AE8: osync_change_unref (opensync_change.c:60) +==14006== by 0x4C4BA7A: _osync_client_handle_commit_change (opensync_client.c:1378) +==14006== by 0x4C4C1EF: _osync_client_message_handler (opensync_client.c:1574) +==14006== by 0x4C81825: _incoming_dispatch (opensync_queue.c:391) +==14006== by 0x38EA63922D: g_main_context_dispatch (in /lib64/libglib-2.0.so.0.2200.2) +==14006== by 0x38EA63CC17: ??? (in /lib64/libglib-2.0.so.0.2200.2) +==14006== by 0x38EA63D064: g_main_loop_run (in /lib64/libglib-2.0.so.0.2200.2) +==14006== by 0x38EA662133: ??? (in /lib64/libglib-2.0.so.0.2200.2) +==14006== by 0x38E9606A39: start_thread (in /lib64/libpthread-2.11.so) +==14006== Address 0xa16e9a0 is 416 bytes inside a block of size 496 alloc'd +==14006== at 0x4A04360: memalign (vg_replace_malloc.c:532) +==14006== by 0x4A043B9: posix_memalign (vg_replace_malloc.c:660) +==14006== by 0x38EA655D51: ??? (in /lib64/libglib-2.0.so.0.2200.2) +==14006== by 0x38EA656DF1: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.2) +==14006== by 0x38EA637145: g_list_append (in /lib64/libglib-2.0.so.0.2200.2) +==14006== by 0x741C272: vformat_attribute_get_values_decoded (vformat.c:1663) +==14006== by 0x741C598: vformat_attribute_get_nth_value (vformat.c:1737) +==14006== by 0x740A53C: handle_telephone_attribute (xmlformat-vcard.c:689) +==14006== by 0x7407991: handle_attribute (xmlformat-common.c:379) +==14006== by 0x740B7E8: conv_vcard_to_xmlformat (xmlformat-vcard.c:1037) +==14006== by 0x4C6BBAF: osync_converter_invoke (opensync_converter.c:194) +==14006== by 0x4C70BB0: osync_format_env_convert (opensync_format_env.c:1213) +==14006== by 0x4C6EC16: osync_format_env_find_path_fn (opensync_format_env.c:638) +==14006== by 0x4C7113D: osync_format_env_find_path_formats_with_detectors (opensync_format_env.c:1308) +==14006== by 0x4C64FD3: osync_entry_engine_convert (opensync_mapping_entry_engine.c:237) +==14006== by 0x4C69C34: osync_sink_engine_convert_to_dest (opensync_sink_engine.c:196) +==14006== by 0x4C69269: osync_obj_engine_prepare_write (opensync_obj_engine.c:1469) +==14006== by 0x4C68913: osync_obj_engine_command (opensync_obj_engine.c:1217) +==14006== by 0x4C608AB: osync_engine_event (opensync_engine.c:2045) +==14006== by 0x4C5E139: _osync_engine_generate_multiplied_event (opensync_engine.c:1208) +==14006== by 0x4C5F30A: _osync_engine_generate_event (opensync_engine.c:1536) +==14006== by 0x4C5F411: _osync_engine_event_callback (opensync_engine.c:1570) +==14006== by 0x4C68C47: osync_obj_engine_event (opensync_obj_engine.c:1315) +==14006== by 0x4C688FB: osync_obj_engine_command (opensync_obj_engine.c:1212) +==14006== by 0x4C601C4: osync_engine_command (opensync_engine.c:1884) +==14006== by 0x4C5B89C: _command_dispatch (opensync_engine.c:383) +==14006== by 0x38EA63922D: g_main_context_dispatch (in /lib64/libglib-2.0.so.0.2200.2) +==14006== by 0x38EA63CC17: ??? (in /lib64/libglib-2.0.so.0.2200.2) +==14006== by 0x38EA63D064: g_main_loop_run (in /lib64/libglib-2.0.so.0.2200.2) +==14006== by 0x38EA662133: ??? (in /lib64/libglib-2.0.so.0.2200.2) +==14006== + +*/ +#endif + + +/* + And with the following workaround - a pretty poor workaround, I should add - + I get: + +src/ldap_format.c:6059:ldap_format_destroy_format1(): input = 0x5032e10 + +src/ldap_format.c:6110:ldap_format_destroy_format1(): Address of glist: 0x9dd8180 +src/ldap_format.c:6114:ldap_format_destroy_format1(): Number of elements: 1 + + + +src/ldap_format.c:6059:ldap_format_destroy_format1(): input = 0xa1bcbf0 + +src/ldap_format.c:6110:ldap_format_destroy_format1(): Address of glist: 0x9dd8180 +src/ldap_format.c:6114:ldap_format_destroy_format1(): Number of elements: 1 + + +So these are two different glist_container structs, but in both cases +with the same address of the glist. This is a bug. Different glist_containers +should have different glist pointers, so that they can be free'd +independently. + +*/ + if (g_list_length(tmp->list) > 1) { + // Free the elements of the list: + g_list_foreach(tmp->list, ldap_format_call_free_ldap_entry_function, NULL); + + osync_trace(TRACE_INTERNAL, "Number of elements after having freed its elements: %i", g_list_length(tmp->list)); + + // Free the list itself: + g_list_free(tmp->list); + + // This should prevent the list and its elements from being freed + // for a second time... Well, who knows... + tmp->list = NULL; + + // And now, the glist_container itself: + memset(tmp, 0, sizeof(glist_container)); + g_free(tmp); + tmp = NULL; + + } else { + + osync_trace(TRACE_INTERNAL, "%s:%i:%s(): Skipping all the calls to the free() functions, because the number of elements is suspiciously low.", __FILE__, __LINE__, __func__); + + } + } // if (tmp->list) + + osync_trace(TRACE_INTERNAL, "\n\n"); + } // if (!strncmp(tmp->magic, "glist_container", 15)) + else + { + osync_trace(TRACE_INTERNAL, "%s:%i:%s(): WARNING: tmp->magic does NOT contain a valid magic string. So this is NOT a glist_container. Skipping all the calls to free any memory.", __FILE__, __LINE__, __func__); + } + } // if (tmp->magic) + else + { + osync_trace(TRACE_INTERNAL, "%s:%i:%s(): WARNING: tmp->magic = NULL. So this is NOT a glist_container. Skipping all the calls to free any memory.", __FILE__, __LINE__, __func__); + } + } else if (inpsize == sizeof(GList)) { unsigned int length = 0; GList *list = (GList *)input; + osync_trace(TRACE_INTERNAL, "Looks like a GList."); length = g_list_length(list); osync_trace(TRACE_INTERNAL, "With %u elements.", length); + if (input) { + if (g_list_length(list) > 0) { + ldap_plugin_printf("\n\n\n%s:%i:%s():\nAbout to call ldap_format_free_ldap_entries with input = %p\n\n\n", __FILE__, __LINE__, __func__, input); + ldap_format_free_ldap_entries((GList **)&input); // new + } + } + } else if (inpsize > 6 && ldap_format_check_xml((char *)input, (int)inpsize, error)) { + osync_trace(TRACE_INTERNAL, "Looks like a string with a human readable XML document."); + + } else if (inpsize > 6 && ldap_format_check_ldif((char *)input, (int)inpsize, FORMAT_LDAP_INETORGPERSON, error)) { + osync_trace(TRACE_INTERNAL, "Looks like a string with a human readable document in LDIF with data that belongs to the inetorgperson object class."); + + } else if (inpsize > 6 && ldap_format_check_ldif((char *)input, (int)inpsize, FORMAT_LDAP_EVOLUTIONPERSON, error)) { + osync_trace(TRACE_INTERNAL, "Looks like a string with a human readable document in LDIF with data that belongs to the evolutionperson object class."); + } else { - osync_trace(TRACE_INTERNAL, "Don't know."); + osync_trace(TRACE_INTERNAL, "%s:%i:%s(): Don't know, what that is. Returning without having freed anything.", __FILE__, __LINE__, __func__); } - // Temporarily disabled because of bugs in libopensync. -/* - if (input) { - GList *list = (GList *)input; - if (g_list_length(list) > 0) { - ldap_plugin_printf("\n\n\n%s:%i:%s():\nAbout to call ldap_format_free_ldap_entries with input = %p\n\n\n", __FILE__, __LINE__, __func__, input); - ldap_format_free_ldap_entries((GList **)&input); // new - } + osync_trace(TRACE_EXIT, "%s", __func__); + return TRUE; + +error: + if (!osync_error_is_set(error)) + osync_error_set(error, OSYNC_ERROR_GENERIC, "Unknown reason.\n"); + + osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); + return FALSE; +} + + + + + +osync_bool ldap_format_copy_format1(const char *input, unsigned int inpsize, char **output, unsigned int *outpsize, void *user_data, OSyncError **error) +{ + glist_container *real_input = (glist_container *)input; + glist_container *pre_output = NULL; + guint length = 0; + unsigned int i = 0; + + + osync_trace(TRACE_ENTRY, "%s(%p, %u, %p, %p, %p, %p) ", __func__, (void *)input, inpsize, (void *)output, (void *)outpsize, (void *)user_data, (void *)error); + + + if (input == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: input = NULL.", __FILE__, __LINE__); + goto error; } -*/ + if (strncmp(real_input->magic, "glist_container", 15)) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: input was NOT the glist_container that had been expected here in this function.", __FILE__, __LINE__); + goto error; + } + + if (output == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: output = NULL.", __FILE__, __LINE__); + goto error; + } + + if (outpsize == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: outpsize = NULL.", __FILE__, __LINE__); + goto error; + } + + + pre_output = (glist_container *)g_malloc0(sizeof(glist_container)); + if (pre_output == NULL) { + ldap_plugin_printf("%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); + osync_trace(TRACE_ERROR, "%s:%i: ERROR: g_malloc0 problem. Exiting.", __FILE__, __LINE__); + exit(1); + } + + memset(pre_output, 0, sizeof(glist_container)); + + pre_output->magic = "glist_container"; + pre_output->format_name = g_strdup(real_input->format_name); + pre_output->list = NULL; + + + length = g_list_length(real_input->list); + for (i = 0; i < length; i++) { + ldap_entry *source_entry = (ldap_entry *)g_list_nth_data(real_input->list, i); + ldap_entry *target_entry = NULL; + + + if (source_entry == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: source_entry = NULL.", __FILE__, __LINE__); + + goto error; + } + + + // Now, copy an ldap_entry struct. Allocate everything fresh. + // Not just a "shallow" copy. + if (!ldap_format_copy_ldap_entry(source_entry, &target_entry, error)) { + if (!osync_error_is_set(error)) + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: ldap_format_copy_ldap_entry() has failed.", __FILE__, __LINE__); + + goto error; + } + + + + if (target_entry == NULL) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: target_entry = NULL. ldap_format_copy_ldap_entry() must have failed.", __FILE__, __LINE__); + + goto error; + } + + + pre_output->list = g_list_append(pre_output->list, target_entry); + + } // for (i = 0; i < length; i++) + *output = (char *) pre_output; + *outpsize = sizeof(pre_output); + +#ifdef DEBUG_destroy_function + ldap_plugin_printf("\n%s:%i:%s(): *output = %p\n", __FILE__, __LINE__, __func__, (void *)pre_output); +#endif osync_trace(TRACE_EXIT, "%s", __func__); return TRUE; + +error: + if (!osync_error_is_set(error)) + osync_error_set(error, OSYNC_ERROR_GENERIC, "Unknown reason.\n"); + + osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); + return FALSE; } + + + + + /** * @brief Not implemented, yet. And I have not even understood the * following description: @@ -6060,7 +6467,7 @@ // First off, try and find out what type of data has been casted to char *: - if (size == sizeof(glist_container) && ((glist_container *)data)->magic && !strcmp(((glist_container *)data)->magic, "glist_container")) { + if (size == sizeof(glist_container) && ((glist_container *)data)->magic && !strncmp(((glist_container *)data)->magic, "glist_container", 15)) { if (!ldap_plugin_get_glist(data, &list, error)) { osync_trace(TRACE_ERROR, "%s:%i: ERROR: ldap_plugin_get_glist() has failed.\n", __FILE__, __LINE__); @@ -6337,6 +6744,9 @@ return rv; error: + if (regex) + g_regex_unref(regex); + if (!osync_error_is_set(error)) osync_error_set(error, OSYNC_ERROR_GENERIC, "Unknown reason.\n"); @@ -6374,6 +6784,7 @@ { GRegex *replace_regex = NULL; GError *gerror = NULL; + gchar *old_string = NULL; osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p)", __func__, (void *)string, (void *)replace_pattern, compile_options, (void *)target_pattern, (void *)error); @@ -6415,6 +6826,7 @@ } + old_string = *string; *string = g_regex_replace_literal(replace_regex, *string, -1, 0, target_pattern, 0, &gerror); if (gerror != NULL) { @@ -6429,11 +6841,26 @@ goto error; } + if (old_string != *string) { + g_free(old_string); + old_string = NULL; + } + + if (replace_regex) + g_regex_unref(replace_regex); osync_trace(TRACE_EXIT, "%s()", __func__); return TRUE; error: + if (replace_regex) + g_regex_unref(replace_regex); + + if (old_string) { + g_free(old_string); + old_string = NULL; + } + if (!osync_error_is_set(error)) osync_error_set(error, OSYNC_ERROR_GENERIC, "Unknown reason.\n"); @@ -6541,7 +6968,6 @@ osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return FALSE; - } @@ -6745,12 +7171,17 @@ gchar *id = NULL; if (dn) { gchar **tokens = g_strsplit(dn, ",", 0); + + if (tokens) { if (tokens[1]) { id = g_strdup(tokens[1]); } else { ldap_plugin_printf("%s:%i: ERROR: tokens[1] = NULL. Ignoring for now.", __FILE__, __LINE__); } + + g_strfreev(tokens); + tokens = NULL; } else { ldap_plugin_printf("%s:%i: ERROR: tokens = NULL. Ignoring for now.", __FILE__, __LINE__); } @@ -6783,6 +7214,17 @@ g_free (line); line = NULL; + + if (dn) { + g_free(dn); + dn = NULL; + } + + if (id) { + g_free(id); + id = NULL; + } + goto error; } @@ -6797,10 +7239,22 @@ if (single_ldap_entry == NULL) { osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: single_ldap_entry = NULL. ldap_format_create_ldap_entry_from_ldapmods() must have failed.", __FILE__, __LINE__); + + if (dn) { + g_free(dn); + dn = NULL; + } + + if (id) { + g_free(id); + id = NULL; + } + goto error; } single_ldap_entry->dn = g_strdup(dn); + single_ldap_entry->id = g_strdup(id); single_ldap_entry->subentries = NULL; @@ -6809,6 +7263,12 @@ dn = NULL; } + if (id) { + g_free(id); + id = NULL; + } + + if (ldap_entries) { *ldap_entries = g_list_append(*ldap_entries, single_ldap_entry); } else { @@ -6960,18 +7420,27 @@ goto error; } - if (*ldap_entries == NULL) { osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: *ldap_entries = NULL. ldap_format_read_ldap_entries_from_ldif() must have failed.", __FILE__, __LINE__); goto error; } + if (string) { + g_free(string); + string = NULL; + } osync_trace(TRACE_EXIT, "%s()", __func__); return TRUE; error: + if (string) { + g_free(string); + string = NULL; + } + + if (!osync_error_is_set(error)) osync_error_set(error, OSYNC_ERROR_GENERIC, "Unknown reason.\n"); @@ -7770,7 +8239,12 @@ if (!contact1_format) { - osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: contact_format = NULL.\n", __FILE__, __LINE__); + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: contact1_format = NULL.\n", __FILE__, __LINE__); + goto error; + } + + if (!contact2_format) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: contact2_format = NULL.\n", __FILE__, __LINE__); goto error; } @@ -7792,6 +8266,7 @@ osync_objformat_set_compare_func(contact1_format, ldap_format_compare_format1); + osync_objformat_set_copy_func(contact1_format, ldap_format_copy_format1); osync_objformat_set_destroy_func(contact1_format, ldap_format_destroy_format1); osync_objformat_set_duplicate_func(contact1_format, ldap_format_duplicate_format1); osync_objformat_set_print_func(contact1_format, ldap_format_print_format1); @@ -7800,6 +8275,7 @@ osync_objformat_set_compare_func(contact2_format, ldap_format_compare_format1); + osync_objformat_set_copy_func(contact2_format, ldap_format_copy_format1); osync_objformat_set_destroy_func(contact2_format, ldap_format_destroy_format1); osync_objformat_set_duplicate_func(contact2_format, ldap_format_duplicate_format1); osync_objformat_set_print_func(contact2_format, ldap_format_print_format1); @@ -7807,6 +8283,7 @@ osync_objformat_set_compare_func(event_format, ldap_format_compare_format1); + osync_objformat_set_copy_func(event_format, ldap_format_copy_format1); osync_objformat_set_destroy_func(event_format, ldap_format_destroy_format1); osync_objformat_set_duplicate_func(event_format, ldap_format_duplicate_format1); osync_objformat_set_print_func(event_format, ldap_format_print_format1); @@ -7814,6 +8291,7 @@ osync_objformat_set_compare_func(todo_format, ldap_format_compare_format1); + osync_objformat_set_copy_func(todo_format, ldap_format_copy_format1); osync_objformat_set_destroy_func(todo_format, ldap_format_destroy_format1); osync_objformat_set_duplicate_func(todo_format, ldap_format_duplicate_format1); osync_objformat_set_print_func(todo_format, ldap_format_print_format1); @@ -7821,6 +8299,7 @@ osync_objformat_set_compare_func(note_format, ldap_format_compare_format1); + osync_objformat_set_copy_func(note_format, ldap_format_copy_format1); osync_objformat_set_destroy_func(note_format, ldap_format_destroy_format1); osync_objformat_set_duplicate_func(note_format, ldap_format_duplicate_format1); osync_objformat_set_print_func(note_format, ldap_format_print_format1); Modified: plugins/ldap-sync/src/ldap_format.h ============================================================================== --- plugins/ldap-sync/src/ldap_format.h Fri Jan 22 16:45:55 2010 (r6018) +++ plugins/ldap-sync/src/ldap_format.h Sat Jan 23 17:49:49 2010 (r6019) @@ -49,6 +49,7 @@ static GList *ldap_format_append_ldapmod(GList *list, gchar *ldapattr, gchar *value); static osync_bool ldap_format_apply_stylesheet_workaround(char *input, unsigned int inpsize, char **output, unsigned int *outpsize, const char *config, void *userdata, const char *stylesheet, OSyncError **error); static int ldap_format_avoid_duplicate_attribute(GList *ldapmods, const char *name); +void ldap_format_call_free_ldap_entry_function(void *data, void *user_data); static osync_bool ldap_format_check_adequate_stylesheet(xmlNode *root_element, const char *stylesheet_file, OSyncError **error); osync_bool ldap_format_check_ldif(const char *data, int size, const char *format_name, OSyncError **error); static osync_bool ldap_format_check_root_element(const xmlDoc *xmldata, const char *objtype, const char *ldap_format_name, const gchar *dn, xmlNode **root, OSyncError **error); @@ -63,7 +64,9 @@ static osync_bool ldap_format_conv_xmlformat_note_to_ldap_note(char *input, unsigned int inpsize, char **output, unsigned int *outpsize, osync_bool *free_input, const char *config, void *userdata, OSyncError **error); static osync_bool ldap_format_conv_xmlformat_todo_to_ldap_todo(char *input, unsigned int inpsize, char **output, unsigned int *outpsize, osync_bool *free_input, const char *config, void *userdata, OSyncError **error); static osync_bool ldap_format_convert_xmlinternal2ldap (const xmlDoc *xmldata, const char *objtype, const char *ldap_format_name, const gchar *dn, GList **potential_subentries, GList **ldap_entries, OSyncError **error); -static osync_bool ldap_format_create_ldap_entries_list_from_ldapmods(const char *dn, GList *ldapmods, GList **potential_subentries, GList **ldap_entries, OSyncError **error); +osync_bool ldap_format_copy_format1(const char *input, unsigned int inpsize, char **output, unsigned int *outpsize, void *user_data, OSyncError **error); +osync_bool ldap_format_copy_ldap_entry(const ldap_entry *source_entry, ldap_entry **destination_entry, OSyncError **error); +static osync_bool ldap_format_create_ldap_entries_list_from_ldapmods(const char *dn, GList *ldapmods, GList *potential_subentries, GList **ldap_entries, OSyncError **error); static ldap_entry *ldap_format_create_ldap_entry_from_ldapmods(GList *ldapmods); osync_bool ldap_format_detect_plain_as_ldap_evolutionperson(const char *data, int size, void *userdata); Modified: plugins/ldap-sync/src/ldap_plugin.h ============================================================================== --- plugins/ldap-sync/src/ldap_plugin.h Fri Jan 22 16:45:55 2010 (r6018) +++ plugins/ldap-sync/src/ldap_plugin.h Sat Jan 23 17:49:49 2010 (r6019) @@ -167,6 +167,7 @@ #define DEBUG_detection 1 #define DEBUG_ldapdata_from_server 1 #define DEBUG_convert_ldap2xmlinternal 1 +#define DEBUG_destroy_function 1 #define DEBUG_do_apply_stylesheet 1 #define DEBUG_convert_xmlinternal2ldap 1 #define DEBUG_ldapdata_to_server 1 @@ -188,6 +189,7 @@ #undef DEBUG_detection #undef DEBUG_ldapdata_from_server #undef DEBUG_convert_ldap2xmlinternal +#undef DEBUG_destroy_function #undef DEBUG_do_apply_stylesheet #undef DEBUG_convert_xmlinternal2ldap #undef DEBUG_ldapdata_to_server Modified: plugins/ldap-sync/tests/check_do_convert_from_to.c ============================================================================== --- plugins/ldap-sync/tests/check_do_convert_from_to.c Fri Jan 22 16:45:55 2010 (r6018) +++ plugins/ldap-sync/tests/check_do_convert_from_to.c Sat Jan 23 17:49:49 2010 (r6019) @@ -27,6 +27,16 @@ #include <errno.h> +#include <glib.h> +#include <libxml/parser.h> +#include <libxml/tree.h> +#include <libxml/xmlmemory.h> +#include <libxml/xmlreader.h> +#include <libxml/xmlschemas.h> +#include <libxml/xpath.h> +#include <libxslt/xslt.h> +#include <libxslt/xsltutils.h> +#include <libxslt/transform.h> #include <opensync/opensync.h> #include <opensync/opensync-data.h> #include <opensync/opensync-format.h> @@ -857,6 +867,9 @@ osync_trace(TRACE_INTERNAL, "Edge converter: \"%s\"\n", osync_objformat_get_name(osync_converter_get_targetformat(l->data))); } } + + osync_list_free(list); + list = NULL; } else { osync_trace(TRACE_ERROR, "%s:%i: WARNING: list = NULL.", __FILE__, __LINE__); } @@ -871,6 +884,9 @@ osync_trace(TRACE_INTERNAL, "Converter: \"%s\"\n", osync_objformat_get_name(osync_converter_get_targetformat(l->data))); } } + + osync_list_free(list); + list = NULL; } else { osync_trace(TRACE_INTERNAL, "%s:%i: WARNING: list = NULL.", __FILE__, __LINE__); } @@ -1184,6 +1200,11 @@ unsigned int buf_size = 0; + if (osync_error_is_set(&error)) + { + osync_trace(TRACE_ERROR, "%s:%i: ERROR: %s", __FILE__, __LINE__, osync_error_print(&error)); + } + osync_trace(TRACE_ERROR, "%s:%i: WARNING: result = NULL. Has the conversion failed?", __FILE__, __LINE__); osync_trace(TRACE_ERROR, "%s:%i: Resulting format = \"%s\"", __FILE__, __LINE__, (char *)osync_objformat_get_name(osync_data_get_objformat(data))); osync_trace(TRACE_ERROR, "%s:%i: Resulting objtype = \"%s\"", __FILE__, __LINE__, osync_data_get_objtype (data)); @@ -1233,6 +1254,10 @@ if (format_env) osync_format_env_unref(format_env); + if (result) + osync_free(result); + + xmlCleanupParser(); out: osync_trace(TRACE_EXIT, "%s", __func__); @@ -1248,6 +1273,10 @@ if (format_env) osync_format_env_unref(format_env); + if (result) + osync_free(result); + + xmlCleanupParser(); if (!osync_error_is_set(&error)) { osync_error_set(&error, OSYNC_ERROR_GENERIC, "%s:%i: ERROR: Unknown reason.\n", __FILE__, __LINE__); |