Coverage Report

Created: 2023-06-07 06:15

/src/neomutt/attach/attach.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file
3
 * Handling of email attachments
4
 *
5
 * @authors
6
 * Copyright (C) 1996-2000,2002,2013 Michael R. Elkins <me@mutt.org>
7
 * Copyright (C) 1999-2004,2006 Thomas Roessler <roessler@does-not-exist.org>
8
 *
9
 * @copyright
10
 * This program is free software: you can redistribute it and/or modify it under
11
 * the terms of the GNU General Public License as published by the Free Software
12
 * Foundation, either version 2 of the License, or (at your option) any later
13
 * version.
14
 *
15
 * This program is distributed in the hope that it will be useful, but WITHOUT
16
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18
 * details.
19
 *
20
 * You should have received a copy of the GNU General Public License along with
21
 * this program.  If not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
/**
25
 * @page attach_attach Email attachments
26
 *
27
 * Handling of email attachments
28
 */
29
30
#include "config.h"
31
#include <string.h>
32
#include "mutt/lib.h"
33
#include "email/lib.h"
34
#include "attach.h"
35
36
/**
37
 * mutt_aptr_new - Create a new Attachment Pointer
38
 * @retval ptr New Attachment Pointer
39
 */
40
struct AttachPtr *mutt_aptr_new(void)
41
0
{
42
0
  return mutt_mem_calloc(1, sizeof(struct AttachPtr));
43
0
}
44
45
/**
46
 * mutt_aptr_free - Free an Attachment Pointer
47
 * @param[out] ptr Attachment Pointer
48
 */
49
void mutt_aptr_free(struct AttachPtr **ptr)
50
0
{
51
0
  if (!ptr || !*ptr)
52
0
    return;
53
54
0
  struct AttachPtr *aptr = *ptr;
55
0
  FREE(&aptr->tree);
56
57
0
  FREE(ptr);
58
0
}
59
60
/**
61
 * mutt_actx_add_attach - Add an Attachment to an Attachment Context
62
 * @param actx   Attachment context
63
 * @param attach Attachment to add
64
 */
65
void mutt_actx_add_attach(struct AttachCtx *actx, struct AttachPtr *attach)
66
0
{
67
0
  const int grow = 5;
68
69
0
  if (!actx || !attach)
70
0
    return;
71
72
0
  if (actx->idxlen == actx->idxmax)
73
0
  {
74
0
    actx->idxmax += grow;
75
0
    mutt_mem_realloc(&actx->idx, actx->idxmax * sizeof(struct AttachPtr *));
76
0
    mutt_mem_realloc(&actx->v2r, actx->idxmax * sizeof(short));
77
78
0
    memset(&actx->idx[actx->idxlen], 0, grow * sizeof(struct AttachPtr *));
79
0
    memset(&actx->v2r[actx->idxlen], 0, grow * sizeof(short));
80
0
  }
81
82
0
  actx->idx[actx->idxlen++] = attach;
83
0
}
84
85
/**
86
 * mutt_actx_ins_attach - Insert an Attachment into an Attachment Context at Specified Index
87
 * @param actx   Attachment context
88
 * @param attach Attachment to insert
89
 * @param aidx   Index to insert attachment at
90
 */
91
void mutt_actx_ins_attach(struct AttachCtx *actx, struct AttachPtr *attach, int aidx)
92
0
{
93
0
  if (!actx || !attach)
94
0
    return;
95
96
0
  if ((aidx < 0) || (aidx > actx->idxmax))
97
0
    return;
98
99
0
  if (actx->idxlen == actx->idxmax)
100
0
  {
101
0
    actx->idxmax += 5;
102
0
    mutt_mem_realloc(&actx->idx, sizeof(struct AttachPtr *) * actx->idxmax);
103
0
    mutt_mem_realloc(&actx->v2r, sizeof(short) * actx->idxmax);
104
0
    for (int i = actx->idxlen; i < actx->idxmax; i++)
105
0
      actx->idx[i] = NULL;
106
0
  }
107
108
0
  actx->idxlen++;
109
110
0
  for (int i = actx->idxlen - 1; i > aidx; i--)
111
0
    actx->idx[i] = actx->idx[i - 1];
112
113
0
  actx->idx[aidx] = attach;
114
0
}
115
116
/**
117
 * mutt_actx_add_fp - Save a File handle to the Attachment Context
118
 * @param actx   Attachment context
119
 * @param fp_new File handle to save
120
 */
121
void mutt_actx_add_fp(struct AttachCtx *actx, FILE *fp_new)
122
0
{
123
0
  if (!actx || !fp_new)
124
0
    return;
125
126
0
  if (actx->fp_len == actx->fp_max)
127
0
  {
128
0
    actx->fp_max += 5;
129
0
    mutt_mem_realloc(&actx->fp_idx, sizeof(FILE *) * actx->fp_max);
130
0
    for (int i = actx->fp_len; i < actx->fp_max; i++)
131
0
      actx->fp_idx[i] = NULL;
132
0
  }
133
134
0
  actx->fp_idx[actx->fp_len++] = fp_new;
135
0
}
136
137
/**
138
 * mutt_actx_add_body - Add an email body to an Attachment Context
139
 * @param actx     Attachment context
140
 * @param new_body Email Body to add
141
 */
142
void mutt_actx_add_body(struct AttachCtx *actx, struct Body *new_body)
143
0
{
144
0
  if (!actx || !new_body)
145
0
    return;
146
147
0
  if (actx->body_len == actx->body_max)
148
0
  {
149
0
    actx->body_max += 5;
150
0
    mutt_mem_realloc(&actx->body_idx, sizeof(struct Body *) * actx->body_max);
151
0
    for (int i = actx->body_len; i < actx->body_max; i++)
152
0
      actx->body_idx[i] = NULL;
153
0
  }
154
155
0
  actx->body_idx[actx->body_len++] = new_body;
156
0
}
157
158
/**
159
 * mutt_actx_entries_free - Free entries in an Attachment Context
160
 * @param actx Attachment context
161
 */
162
void mutt_actx_entries_free(struct AttachCtx *actx)
163
0
{
164
0
  if (!actx)
165
0
    return;
166
167
0
  for (int i = 0; i < actx->idxlen; i++)
168
0
  {
169
0
    if (actx->idx[i]->body)
170
0
      actx->idx[i]->body->aptr = NULL;
171
0
    mutt_aptr_free(&actx->idx[i]);
172
0
  }
173
0
  actx->idxlen = 0;
174
0
  actx->vcount = 0;
175
176
0
  for (int i = 0; i < actx->fp_len; i++)
177
0
    mutt_file_fclose(&actx->fp_idx[i]);
178
0
  actx->fp_len = 0;
179
180
0
  for (int i = 0; i < actx->body_len; i++)
181
0
    mutt_body_free(&actx->body_idx[i]);
182
0
  actx->body_len = 0;
183
0
}
184
185
/**
186
 * mutt_actx_new - Create a new Attachment Context
187
 * @retval ptr New Attachment Context
188
 */
189
struct AttachCtx *mutt_actx_new(void)
190
0
{
191
0
  return mutt_mem_calloc(1, sizeof(struct AttachCtx));
192
0
}
193
194
/**
195
 * mutt_actx_free - Free an Attachment Context
196
 * @param[out] ptr Attachment context
197
 */
198
void mutt_actx_free(struct AttachCtx **ptr)
199
0
{
200
0
  if (!ptr || !*ptr)
201
0
    return;
202
203
0
  struct AttachCtx *actx = *ptr;
204
205
0
  mutt_actx_entries_free(actx);
206
0
  FREE(&actx->idx);
207
0
  FREE(&actx->v2r);
208
0
  FREE(&actx->fp_idx);
209
0
  FREE(&actx->body_idx);
210
0
  FREE(ptr);
211
0
}