src/stringpair.c
author Edouard Tisserant
Sat, 09 Jul 2016 15:20:23 +0200
changeset 812 786f03e0cae4
parent 786 cd0c6d03e539
child 831 1d2fc388c491
permissions -rw-r--r--
fix #95 : Double free - Incorrect memory allocation in stringpair_list_append()
vb@125
     1
#include "pEp_internal.h"
vb@125
     2
vb@98
     3
#include <stdlib.h>
vb@98
     4
#include <assert.h>
vb@98
     5
#include <string.h>
vb@98
     6
vb@98
     7
#include "stringpair.h"
vb@98
     8
vb@98
     9
DYNAMIC_API stringpair_t * new_stringpair(const char *key, const char *value)
vb@98
    10
{
vb@98
    11
    stringpair_t *pair = NULL;
vb@98
    12
vb@98
    13
    assert(key);
vb@98
    14
    assert(value),
vb@98
    15
vb@98
    16
    pair = calloc(1, sizeof(stringpair_t));
vb@98
    17
    assert(pair);
vb@98
    18
    if (pair == NULL)
vb@98
    19
        goto enomem;
vb@98
    20
vb@98
    21
    pair->key = strdup(key);
vb@98
    22
    assert(pair->key);
vb@98
    23
    if (pair->key == NULL)
vb@98
    24
        goto enomem;
vb@98
    25
vb@98
    26
    pair->value = strdup(value);
vb@98
    27
    assert(pair->value);
vb@98
    28
    if (pair->value == NULL)
vb@98
    29
        goto enomem;
vb@98
    30
vb@98
    31
    return pair;
vb@98
    32
vb@98
    33
enomem:
vb@98
    34
    free_stringpair(pair);
vb@98
    35
    return NULL;
vb@98
    36
}
vb@98
    37
vb@98
    38
DYNAMIC_API void free_stringpair(stringpair_t * pair)
vb@98
    39
{
vb@98
    40
    if (pair) {
vb@98
    41
        free(pair->key);
vb@98
    42
        free(pair->value);
vb@98
    43
        free(pair);
vb@98
    44
    }
vb@98
    45
}
vb@98
    46
vb@98
    47
DYNAMIC_API stringpair_t * stringpair_dup(const stringpair_t *src)
vb@98
    48
{
vb@98
    49
    assert(src);
vb@98
    50
    return new_stringpair(src->key, src->value);
vb@98
    51
}
vb@98
    52
vb@281
    53
DYNAMIC_API stringpair_list_t *new_stringpair_list(stringpair_t *value)
vb@98
    54
{
vb@107
    55
    stringpair_list_t *result = calloc(1, sizeof(stringpair_list_t));
vb@109
    56
    assert(result);
vb@109
    57
vb@281
    58
    if (result && value)
vb@281
    59
        result->value = value;
vb@109
    60
vb@98
    61
    return result;
vb@98
    62
}
vb@98
    63
vb@98
    64
DYNAMIC_API stringpair_list_t *stringpair_list_dup(
vb@98
    65
        const stringpair_list_t *src
vb@98
    66
    )
vb@98
    67
{
vb@98
    68
    assert(src);
vb@98
    69
    if (src == NULL)
vb@98
    70
        return NULL;
vb@98
    71
vb@98
    72
    stringpair_list_t *dst = new_stringpair_list(src->value);
vb@98
    73
    if (dst == NULL)
vb@98
    74
        return NULL;
vb@98
    75
vb@98
    76
    if (src->next) {
vb@98
    77
        dst->next = stringpair_list_dup(src->next);
vb@98
    78
        if (dst->next == NULL) {
vb@98
    79
            free_stringpair_list(dst);
vb@98
    80
            return NULL;
vb@98
    81
        }
vb@98
    82
    }
vb@98
    83
vb@98
    84
    return dst;
vb@98
    85
}
vb@98
    86
vb@98
    87
DYNAMIC_API stringpair_list_t *stringpair_list_add(
vb@98
    88
        stringpair_list_t *stringpair_list,
vb@281
    89
        stringpair_t *value
vb@98
    90
    )
vb@98
    91
{
vb@98
    92
    assert(value);
vb@98
    93
vb@98
    94
    if (stringpair_list == NULL)
vb@98
    95
        return new_stringpair_list(value);
vb@98
    96
vb@281
    97
    if (stringpair_list->next)
vb@98
    98
        return stringpair_list_add(stringpair_list->next, value);
vb@281
    99
vb@98
   100
    if (stringpair_list->value == NULL) {
roker@786
   101
        assert(stringpair_list->next == NULL);
vb@281
   102
        stringpair_list->value = value;
vb@98
   103
        return stringpair_list;
vb@98
   104
    }
vb@98
   105
vb@98
   106
    stringpair_list->next = new_stringpair_list(value);
vb@98
   107
    if (stringpair_list->next == NULL)
vb@98
   108
        return NULL;
vb@98
   109
vb@98
   110
    return stringpair_list->next;
vb@98
   111
}
vb@98
   112
vb@98
   113
DYNAMIC_API stringpair_list_t *stringpair_list_append(
vb@98
   114
        stringpair_list_t *stringpair_list,
vb@98
   115
        stringpair_list_t *second
vb@98
   116
    )
vb@98
   117
{
vb@98
   118
    assert(stringpair_list);
vb@98
   119
vb@98
   120
    if (second == NULL || second->value == NULL)
vb@98
   121
        return stringpair_list;
vb@98
   122
vb@98
   123
    stringpair_list_t *_s = stringpair_list;
vb@98
   124
    stringpair_list_t *_s2;
vb@98
   125
    for (_s2 = second; _s2 != NULL; _s2 = _s2->next) {
Edouard@812
   126
        stringpair_t *_sp = stringpair_dup(_s2->value);
Edouard@812
   127
        if (_sp == NULL)
vb@98
   128
            return NULL;
Edouard@812
   129
        _s = stringpair_list_add(_s, _sp);
Edouard@812
   130
        if (_s == NULL){
Edouard@812
   131
            free_stringpair(_sp);
Edouard@812
   132
            return NULL;
Edouard@812
   133
        }
vb@98
   134
    }
vb@98
   135
    return _s;
vb@98
   136
}
vb@98
   137
vb@98
   138
DYNAMIC_API int stringpair_list_length(
vb@98
   139
        const stringpair_list_t *stringpair_list
vb@98
   140
    )
vb@98
   141
{
vb@301
   142
    int len = 0;
vb@98
   143
vb@302
   144
    const stringpair_list_t *_sl;
vb@301
   145
    for (_sl = stringpair_list; _sl && _sl->value; _sl = _sl->next)
vb@301
   146
        len++;
vb@98
   147
vb@98
   148
    return len;
vb@98
   149
}
vb@98
   150
vb@98
   151
DYNAMIC_API void free_stringpair_list(stringpair_list_t *stringpair_list)
vb@98
   152
{
vb@98
   153
    if (stringpair_list) {
vb@98
   154
        free_stringpair_list(stringpair_list->next);
vb@98
   155
        free_stringpair(stringpair_list->value);
vb@98
   156
        free(stringpair_list);
vb@98
   157
    }
vb@98
   158
}
vb@98
   159
vb@104
   160
DYNAMIC_API stringpair_list_t *stringpair_list_find(
vb@98
   161
        stringpair_list_t *stringpair_list,
vb@98
   162
        const char *key
vb@98
   163
    )
vb@98
   164
{
vb@98
   165
    assert(key);
vb@98
   166
vb@104
   167
    stringpair_list_t *_l;
vb@104
   168
    for (_l = stringpair_list; _l; _l = _l->next) {
vb@104
   169
        if (strcoll(key, _l->value->key) == 0)
vb@104
   170
            return _l;
vb@104
   171
    }
vb@98
   172
vb@104
   173
    return NULL;
vb@98
   174
}
vb@98
   175