Fix resource leak
[claws.git] / src / jpilot.c
index d049314ca2c4cd33829393616d627d6d70f12998..43f58f45e4ff34c6f8a1d714c1f1b2d04b08d75d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001-2007 Match Grun and the Claws Mail team
+ * Copyright (C) 2001-2012 Match Grun and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
+#include "claws-features.h"
 #endif
 
 #ifdef USE_JPILOT
@@ -208,30 +209,30 @@ JPilotFile *jpilot_create_path( const gchar *path ) {
 * Properties...
 */
 void jpilot_set_name( JPilotFile* pilotFile, const gchar *value ) {
-       g_return_if_fail( pilotFile != NULL );
+       cm_return_if_fail( pilotFile != NULL );
        addrcache_set_name( pilotFile->addressCache, value );
 }
 void jpilot_set_file( JPilotFile* pilotFile, const gchar *value ) {
-       g_return_if_fail( pilotFile != NULL );
+       cm_return_if_fail( pilotFile != NULL );
        addrcache_refresh( pilotFile->addressCache );
        pilotFile->readMetadata = FALSE;
        pilotFile->path = mgu_replace_string( pilotFile->path, value );
 }
 void jpilot_set_accessed( JPilotFile *pilotFile, const gboolean value ) {
-       g_return_if_fail( pilotFile != NULL );
+       cm_return_if_fail( pilotFile != NULL );
        pilotFile->addressCache->accessFlag = value;
 }
 
 gint jpilot_get_status( JPilotFile *pilotFile ) {
-       g_return_val_if_fail( pilotFile != NULL, -1 );
+       cm_return_val_if_fail( pilotFile != NULL, -1 );
        return pilotFile->retVal;
 }
 ItemFolder *jpilot_get_root_folder( JPilotFile *pilotFile ) {
-       g_return_val_if_fail( pilotFile != NULL, NULL );
+       cm_return_val_if_fail( pilotFile != NULL, NULL );
        return addrcache_get_root_folder( pilotFile->addressCache );
 }
 gchar *jpilot_get_name( JPilotFile *pilotFile ) {
-       g_return_val_if_fail( pilotFile != NULL, NULL );
+       cm_return_val_if_fail( pilotFile != NULL, NULL );
        return addrcache_get_name( pilotFile->addressCache );
 }
 
@@ -241,7 +242,7 @@ gchar *jpilot_get_name( JPilotFile *pilotFile ) {
  * \return <i>TRUE</i> if file was read.
  */
 gboolean jpilot_get_read_flag( JPilotFile *pilotFile ) {
-       g_return_val_if_fail( pilotFile != NULL, FALSE );
+       cm_return_val_if_fail( pilotFile != NULL, FALSE );
        return pilotFile->addressCache->dataRead;
 }
 
@@ -252,7 +253,7 @@ gboolean jpilot_get_read_flag( JPilotFile *pilotFile ) {
 void jpilot_clear_custom_labels( JPilotFile *pilotFile ) {
        GList *node;
 
-       g_return_if_fail( pilotFile != NULL );
+       cm_return_if_fail( pilotFile != NULL );
 
        /* Release custom labels */
        mgu_free_dlist( pilotFile->customLabels );
@@ -277,7 +278,7 @@ void jpilot_clear_custom_labels( JPilotFile *pilotFile ) {
  * \param pilotFile  JPilot control data.
  */
 void jpilot_add_custom_label( JPilotFile *pilotFile, const gchar *labelName ) {
-       g_return_if_fail( pilotFile != NULL );
+       cm_return_if_fail( pilotFile != NULL );
 
        if( labelName ) {
                gchar *labelCopy = g_strdup( labelName );
@@ -302,7 +303,7 @@ GList *jpilot_get_custom_labels( JPilotFile *pilotFile ) {
        GList *retVal = NULL;
        GList *node;
 
-       g_return_val_if_fail( pilotFile != NULL, NULL );
+       cm_return_val_if_fail( pilotFile != NULL, NULL );
 
        node = pilotFile->customLabels;
        while( node ) {
@@ -352,7 +353,7 @@ static gchar *jpilot_get_pc3_file( JPilotFile *pilotFile ) {
  */
 static gboolean jpilot_mark_files( JPilotFile *pilotFile ) {
        gboolean retVal = FALSE;
-       struct stat filestat;
+       GStatBuf filestat;
        gchar *pcFile;
 
        /* Mark PDB file cache */
@@ -363,7 +364,7 @@ static gboolean jpilot_mark_files( JPilotFile *pilotFile ) {
        pilotFile->pc3ModifyTime = 0;
        pcFile = jpilot_get_pc3_file( pilotFile );
        if( pcFile == NULL ) return retVal;
-       if( 0 == stat( pcFile, &filestat ) ) {
+       if( 0 == g_stat( pcFile, &filestat ) ) {
                pilotFile->havePC3 = TRUE;
                pilotFile->pc3ModifyTime = filestat.st_mtime;
                retVal = TRUE;
@@ -380,7 +381,7 @@ static gboolean jpilot_mark_files( JPilotFile *pilotFile ) {
  */
 static gboolean jpilot_check_files( JPilotFile *pilotFile ) {
        gboolean retVal = TRUE;
-       struct stat filestat;
+       GStatBuf filestat;
        gchar *pcFile;
 
        /* Check main file */
@@ -392,7 +393,7 @@ static gboolean jpilot_check_files( JPilotFile *pilotFile ) {
        pcFile = jpilot_get_pc3_file( pilotFile );
        if( pcFile == NULL ) return FALSE;
 
-       if( 0 == stat( pcFile, &filestat ) ) {
+       if( 0 == g_stat( pcFile, &filestat ) ) {
                if( filestat.st_mtime == pilotFile->pc3ModifyTime ) retVal = FALSE;
        }
        g_free( pcFile );
@@ -404,12 +405,12 @@ static gboolean jpilot_check_files( JPilotFile *pilotFile ) {
 * Return: TRUE if file was modified.
 */
 gboolean jpilot_get_modified( JPilotFile *pilotFile ) {
-       g_return_val_if_fail( pilotFile != NULL, FALSE );
+       cm_return_val_if_fail( pilotFile != NULL, FALSE );
        pilotFile->addressCache->modified = jpilot_check_files( pilotFile );
        return pilotFile->addressCache->modified;
 }
 gboolean jpilot_get_accessed( JPilotFile *pilotFile ) {
-       g_return_val_if_fail( pilotFile != NULL, FALSE );
+       cm_return_val_if_fail( pilotFile != NULL, FALSE );
        return pilotFile->addressCache->accessFlag;
 }
 
@@ -418,7 +419,7 @@ gboolean jpilot_get_accessed( JPilotFile *pilotFile ) {
  * \param pilotFile  JPilot control data.
  */
 void jpilot_free( JPilotFile *pilotFile ) {
-       g_return_if_fail( pilotFile != NULL );
+       cm_return_if_fail( pilotFile != NULL );
 
        /* Release custom labels */
        jpilot_clear_custom_labels( pilotFile );
@@ -535,9 +536,12 @@ static int jpilot_get_info_size( FILE *in, int *size ) {
        DBHeader dbh;
        unsigned int offset;
        record_header rh;
+       int r;
 
        fseek(in, 0, SEEK_SET);
-       fread(&rdbh, sizeof(RawDBHeader), 1, in);
+       r = fread(&rdbh, sizeof(RawDBHeader), 1, in);
+       if (r < 1)
+               return MGU_ERROR_READ;
        if (feof(in)) {
                return MGU_EOF;
        }
@@ -557,7 +561,10 @@ static int jpilot_get_info_size( FILE *in, int *size ) {
                return MGU_SUCCESS;
        }
 
-       fread(&rh, sizeof(record_header), 1, in);
+       r = fread(&rh, sizeof(record_header), 1, in);
+       if (r < 1)
+               return MGU_ERROR_READ;
+
        offset = ((rh.Offset[0]*256+rh.Offset[1])*256+rh.Offset[2])*256+rh.Offset[3];
        *size=offset - dbh.app_info_offset;
 
@@ -613,7 +620,10 @@ static gint jpilot_get_file_info( JPilotFile *pilotFile, unsigned char **buf, in
                return MGU_ERROR_READ;
        }
 
-       fseek(in, dbh.app_info_offset, SEEK_SET);
+       if (fseek(in, dbh.app_info_offset, SEEK_SET) < 0) {
+               fclose(in);
+               return MGU_ERROR_READ;
+       }
        *buf = ( char * ) malloc(rec_size);
        if (!(*buf)) {
                fclose(in);
@@ -674,6 +684,8 @@ static int read_header(FILE *pc_in, PC3RecordHeader *header) {
        unsigned char packed_header[256];
        int num;
 
+       memset(header, 0, sizeof(PC3RecordHeader));
+
        num = fread(&l, sizeof(l), 1, pc_in);
        if (feof(pc_in)) {
                return -1;
@@ -683,7 +695,7 @@ static int read_header(FILE *pc_in, PC3RecordHeader *header) {
        }
        memcpy(packed_header, &l, sizeof(l));
        len=ntohl(l);
-       if (len > 255) {
+       if (len > 255 || len < sizeof(l)) {
                return -1;
        }
        num = fread(packed_header+sizeof(l), len-sizeof(l), 1, pc_in);
@@ -716,12 +728,12 @@ static gint jpilot_read_next_pc( FILE *in, buf_rec *br ) {
        }
        num = read_header( in, &header );
        if( num < 1 ) {
-               if( ferror( in ) ) {
+               if( ferror( in ) )
                        return MGU_ERROR_READ;
-               }
-               if( feof( in ) ) {
+               else if( feof( in ) )
                        return MGU_EOF;
-               }
+               else
+                       return -1;
        }
        rec_len = header.rec_len;
        record = malloc( rec_len );
@@ -758,11 +770,11 @@ static gint jpilot_read_db_files( JPilotFile *pilotFile, GList **records ) {
        char *buf;
        GList *temp_list;
        int num_records, recs_returned, i, num, r;
-       unsigned int offset, prev_offset, next_offset, rec_size;
+       unsigned int offset, prev_offset, next_offset = 0, rec_size;
        int out_of_order;
        long fpos;  /*file position indicator */
-       unsigned char attrib;
-       unsigned int unique_id;
+       unsigned char attrib = '\0';
+       unsigned int unique_id = 0;
        mem_rec_header *mem_rh, *temp_mem_rh, *last_mem_rh;
        record_header rh;
        RawDBHeader rdbh;
@@ -810,6 +822,8 @@ static gint jpilot_read_db_files( JPilotFile *pilotFile, GList **records ) {
                        }
                        if( feof( in ) ) {
                                fclose( in );
+                               if (mem_rh)
+                                       free_mem_rec_header( &mem_rh );
                                return MGU_EOF;
                        }
                }
@@ -857,7 +871,11 @@ static gint jpilot_read_db_files( JPilotFile *pilotFile, GList **records ) {
                                unique_id = mem_rh->unique_id;
                        }
                }
-               fseek( in, next_offset, SEEK_SET );
+               if (fseek( in, next_offset, SEEK_SET ) < 0) {
+                       free_mem_rec_header( &mem_rh );
+                       fclose(in);
+                       return MGU_ERROR_READ;
+               }
                while( ! feof( in ) ) {
                        fpos = ftell( in );
                        if( out_of_order ) {
@@ -1039,7 +1057,7 @@ static void jpilot_parse_label( JPilotFile *pilotFile, gchar *labelEntry, ItemPe
 
        if( labelEntry ) {
                *buffer = '\0';
-               strcpy( buffer, labelEntry );
+               g_strlcpy( buffer, labelEntry, sizeof(buffer) );
                node = list = jpilot_parse_email( buffer );
                while( node ) {
                        email = addritem_create_item_email();
@@ -1087,7 +1105,6 @@ static void jpilot_load_address(
        gchar *labelEntry;
        GList *node;
        gchar* extID;
-       struct AddressAppInfo *ai;
        gchar **firstName = NULL;
        gchar **lastName = NULL;
 #if (PILOT_LINK_MAJOR > 11)
@@ -1165,19 +1182,9 @@ static void jpilot_load_address(
        g_free( extID );
        extID = NULL;
 
-       /* Pointer to address metadata. */
-       ai = & pilotFile->addrInfo;
-
        /* Add entry for each email address listed under phone labels. */
        indPhoneLbl = addr.phoneLabel;
        for( k = 0; k < JPILOT_NUM_ADDR_PHONE; k++ ) {
-               gint ind;
-
-               ind = indPhoneLbl[k];
-               /*
-               * g_print( "%d : %d : %20s : %s\n", k, ind,
-               * ai->phoneLabels[ind], addrEnt[3+k] );
-               */
                if( indPhoneLbl[k] == IND_PHONE_EMAIL ) {
                        labelEntry = addrEnt[ OFFSET_PHONE_LABEL + k ];
                        jpilot_parse_label( pilotFile, labelEntry, person );
@@ -1203,17 +1210,10 @@ static void jpilot_load_address(
        }
 
        if( person->listEMail ) {
-               if( cat_id > -1 && cat_id < JPILOT_NUM_CATEG ) {
-                       /* Add to specified category */
-                       addrcache_folder_add_person(
-                               pilotFile->addressCache,
-                               folderInd[cat_id], person );
-               }
-               else {
-                       /* Add to root folder */
-                       addrcache_add_person(
-                               pilotFile->addressCache, person );
-               }
+               /* Add to specified category */
+               addrcache_folder_add_person(
+                       pilotFile->addressCache,
+                       folderInd[cat_id], person );
        }
        else {
                addritem_free_item_person( person );
@@ -1256,7 +1256,7 @@ static gint jpilot_read_metadata( JPilotFile *pilotFile ) {
        unsigned char *buf;
        int num;
 
-       g_return_val_if_fail( pilotFile != NULL, -1 );
+       cm_return_val_if_fail( pilotFile != NULL, -1 );
 
        pilotFile->readMetadata = FALSE;
        addrcache_clear( pilotFile->addressCache );
@@ -1292,7 +1292,7 @@ static gboolean jpilot_setup_labels( JPilotFile *pilotFile ) {
        struct AddressAppInfo *ai;
        GList *node;
 
-       g_return_val_if_fail( pilotFile != NULL, -1 );
+       cm_return_val_if_fail( pilotFile != NULL, -1 );
 
        /* Release indexes */
        node = pilotFile->labelInd;
@@ -1346,7 +1346,7 @@ static gboolean jpilot_setup_labels( JPilotFile *pilotFile ) {
 GList *jpilot_load_custom_label( JPilotFile *pilotFile, GList *labelList ) {
        gint i;
 
-       g_return_val_if_fail( pilotFile != NULL, NULL );
+       cm_return_val_if_fail( pilotFile != NULL, NULL );
 
        if( pilotFile->readMetadata ) {
                struct AddressAppInfo *ai = & pilotFile->addrInfo;
@@ -1526,7 +1526,7 @@ gint jpilot_read_data( JPilotFile *pilotFile ) {
                name_order = FAMILY_FIRST;
        }
 
-       g_return_val_if_fail( pilotFile != NULL, -1 );
+       cm_return_val_if_fail( pilotFile != NULL, -1 );
 
        pilotFile->retVal = MGU_SUCCESS;
        pilotFile->addressCache->accessFlag = FALSE;
@@ -1553,7 +1553,7 @@ gint jpilot_read_data( JPilotFile *pilotFile ) {
  * \return List of persons.
  */
 GList *jpilot_get_list_person( JPilotFile *pilotFile ) {
-       g_return_val_if_fail( pilotFile != NULL, NULL );
+       cm_return_val_if_fail( pilotFile != NULL, NULL );
        return addrcache_get_list_person( pilotFile->addressCache );
 }
 
@@ -1567,7 +1567,7 @@ GList *jpilot_get_list_person( JPilotFile *pilotFile ) {
  * \return List of ItemFolder objects. This should not be freed.
  */
 GList *jpilot_get_list_folder( JPilotFile *pilotFile ) {
-       g_return_val_if_fail( pilotFile != NULL, NULL );
+       cm_return_val_if_fail( pilotFile != NULL, NULL );
        return addrcache_get_list_folder( pilotFile->addressCache );
 }
 
@@ -1580,7 +1580,7 @@ GList *jpilot_get_list_folder( JPilotFile *pilotFile ) {
  * \return List of items, or NULL if none.
  */
 GList *jpilot_get_all_persons( JPilotFile *pilotFile ) {
-       g_return_val_if_fail( pilotFile != NULL, NULL );
+       cm_return_val_if_fail( pilotFile != NULL, NULL );
        return addrcache_get_all_persons( pilotFile->addressCache );
 }
 
@@ -1594,14 +1594,14 @@ GList *jpilot_get_all_persons( JPilotFile *pilotFile ) {
  */
 gchar *jpilot_find_pilotdb( void ) {
        const gchar *homedir;
-       gchar str[ WORK_BUFLEN ];
+       gchar str[ WORK_BUFLEN + 1 ];
        gint len;
        FILE *fp;
 
        homedir = get_home_dir();
        if( ! homedir ) return g_strdup( "" );
 
-       strcpy( str, homedir );
+       g_strlcpy( str, homedir , sizeof(str));
        len = strlen( str );
        if( len > 0 ) {
                if( str[ len-1 ] != G_DIR_SEPARATOR ) {
@@ -1609,9 +1609,9 @@ gchar *jpilot_find_pilotdb( void ) {
                        str[ ++len ] = '\0';
                }
        }
-       strcat( str, JPILOT_DBHOME_DIR );
-       strcat( str, G_DIR_SEPARATOR_S );
-       strcat( str, JPILOT_DBHOME_FILE );
+       strncat( str, JPILOT_DBHOME_DIR, WORK_BUFLEN - strlen(str) );
+       strncat( str, G_DIR_SEPARATOR_S, WORK_BUFLEN - strlen(str) );
+       strncat( str, JPILOT_DBHOME_FILE, WORK_BUFLEN - strlen(str) );
 
        /* Attempt to open */
        if( ( fp = g_fopen( str, "rb" ) ) != NULL ) {
@@ -1634,7 +1634,7 @@ gboolean jpilot_test_custom_label( JPilotFile *pilotFile, const gchar *labelName
        gboolean retVal;
        GList *node;
 
-       g_return_val_if_fail( pilotFile != NULL, FALSE );
+       cm_return_val_if_fail( pilotFile != NULL, FALSE );
 
        retVal = FALSE;
        if( labelName ) {