Coverage Report

Created: 2026-05-16 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pigeonhole/src/lib-sieve/sieve-binary-private.h
Line
Count
Source
1
#ifndef SIEVE_BINARY_PRIVATE_H
2
#define SIEVE_BINARY_PRIVATE_H
3
4
#include "sieve-common.h"
5
#include "sieve-binary.h"
6
#include "sieve-extensions.h"
7
8
#include <sys/stat.h>
9
10
0
#define SIEVE_BINARY_FILE_LOCK_TIMEOUT 10
11
12
/*
13
 * Binary file
14
 */
15
16
enum SIEVE_BINARY_FLAGS {
17
  SIEVE_BINARY_FLAG_RESOURCE_LIMIT = BIT(0),
18
};
19
20
struct sieve_binary_header {
21
  uint32_t magic;
22
  uint16_t version_major;
23
  uint16_t version_minor;
24
  uint32_t blocks;
25
26
  uint32_t hdr_size;
27
  uint32_t flags;
28
29
  struct {
30
    uint64_t update_time;
31
    uint32_t cpu_time_msecs;
32
  } resource_usage;
33
};
34
35
struct sieve_binary_file {
36
  pool_t pool;
37
  const char *path;
38
  struct sieve_binary *sbin;
39
40
  struct stat st;
41
  int fd;
42
  off_t offset;
43
};
44
45
void sieve_binary_file_close(struct sieve_binary_file **_file);
46
47
/*
48
 * Internal structures
49
 */
50
51
/* Extension registration */
52
53
struct sieve_binary_extension_reg {
54
  /* The identifier of the extension within this binary */
55
  int index;
56
57
  /* Global extension object */
58
  const struct sieve_extension *extension;
59
60
  /* Extension to the binary; typically used to manage extension-specific
61
     blocks in the binary and as a means to get a binary_free notification
62
     to release references held by extensions.
63
   */
64
  const struct sieve_binary_extension *binext;
65
66
  /* Context data associated to the binary by this extension */
67
  void *context;
68
69
  /* Main block for this extension */
70
  unsigned int block_id;
71
};
72
73
/* Block */
74
75
struct sieve_binary_block {
76
  struct sieve_binary *sbin;
77
  unsigned int id;
78
  int ext_index;
79
80
  buffer_t *data;
81
82
  uoff_t offset;
83
};
84
85
/*
86
 * Binary object
87
 */
88
89
struct sieve_binary {
90
  pool_t pool;
91
  int refcount;
92
  struct sieve_instance *svinst;
93
  struct event *event;
94
95
  struct sieve_script *script;
96
97
  struct sieve_binary_file *file;
98
  struct sieve_binary_header header;
99
  struct sieve_resource_usage rusage;
100
101
  /* When the binary is loaded into memory or when it is being constructed
102
     by the generator, extensions can be associated to the binary. The
103
     extensions array is a sequential list of all linked extensions. The
104
     extension_index array is a mapping ext_id -> binary_extension. This
105
     is used to obtain the index code associated with an extension for
106
     this particular binary. The linked_extensions list all extensions
107
     linked to this binary object other than the preloaded language
108
     features implemented as 'extensions'.
109
110
     All arrays refer to the same extension registration objects. Upon
111
     loading a binary, the 'require'd extensions will sometimes need to
112
     associate context data to the binary object in memory. This is stored
113
     in these registration objects as well.
114
   */
115
  ARRAY(struct sieve_binary_extension_reg *) extensions;
116
  ARRAY(struct sieve_binary_extension_reg *) extension_index;
117
  ARRAY(struct sieve_binary_extension_reg *) linked_extensions;
118
119
  /* Attributes of a loaded binary */
120
  const char *path;
121
122
  /* Blocks */
123
  ARRAY(struct sieve_binary_block *) blocks;
124
125
  bool rusage_updated:1;
126
};
127
128
void sieve_binary_update_event(struct sieve_binary *sbin, const char *new_path)
129
             ATTR_NULL(2);
130
131
struct sieve_binary *
132
sieve_binary_create(struct sieve_instance *svinst, struct sieve_script *script);
133
134
/* Blocks management */
135
136
static inline struct sieve_binary_block *
137
sieve_binary_block_index(struct sieve_binary *sbin, unsigned int id)
138
0
{
139
0
  struct sieve_binary_block *const *sblock;
140
141
0
  if (id >= array_count(&sbin->blocks))
142
0
    return NULL;
143
144
0
  sblock = array_idx(&sbin->blocks, id);
145
0
  if (*sblock == NULL)
146
0
    return NULL;
147
0
  return *sblock;
148
0
}
Unexecuted instantiation: sieve-binary.c:sieve_binary_block_index
Unexecuted instantiation: sieve-binary-file.c:sieve_binary_block_index
Unexecuted instantiation: sieve-binary-code.c:sieve_binary_block_index
Unexecuted instantiation: sieve-binary-dumper.c:sieve_binary_block_index
Unexecuted instantiation: sieve-binary-debug.c:sieve_binary_block_index
149
150
static inline size_t
151
_sieve_binary_block_get_size(const struct sieve_binary_block *sblock)
152
0
{
153
0
  return buffer_get_used_size(sblock->data);
154
0
}
Unexecuted instantiation: sieve-binary.c:_sieve_binary_block_get_size
Unexecuted instantiation: sieve-binary-file.c:_sieve_binary_block_get_size
Unexecuted instantiation: sieve-binary-code.c:_sieve_binary_block_get_size
Unexecuted instantiation: sieve-binary-dumper.c:_sieve_binary_block_get_size
Unexecuted instantiation: sieve-binary-debug.c:_sieve_binary_block_get_size
155
156
struct sieve_binary_block *
157
sieve_binary_block_create_id(struct sieve_binary *sbin, unsigned int id);
158
159
buffer_t *sieve_binary_block_get_buffer(struct sieve_binary_block *sblock);
160
161
/* Extension registration */
162
163
static inline struct sieve_binary_extension_reg *
164
sieve_binary_extension_create_reg(struct sieve_binary *sbin,
165
          const struct sieve_extension *ext)
166
0
{
167
0
  int index = array_count(&sbin->extensions);
168
0
  struct sieve_binary_extension_reg *ereg;
169
170
0
  if (ext->id < 0)
171
0
    return NULL;
172
173
0
  ereg = p_new(sbin->pool, struct sieve_binary_extension_reg, 1);
174
0
  ereg->index = index;
175
0
  ereg->extension = ext;
176
177
0
  array_idx_set(&sbin->extensions, (unsigned int) index, &ereg);
178
0
  array_idx_set(&sbin->extension_index, (unsigned int) ext->id, &ereg);
179
180
0
  return ereg;
181
0
}
Unexecuted instantiation: sieve-binary.c:sieve_binary_extension_create_reg
Unexecuted instantiation: sieve-binary-file.c:sieve_binary_extension_create_reg
Unexecuted instantiation: sieve-binary-code.c:sieve_binary_extension_create_reg
Unexecuted instantiation: sieve-binary-dumper.c:sieve_binary_extension_create_reg
Unexecuted instantiation: sieve-binary-debug.c:sieve_binary_extension_create_reg
182
183
static inline struct sieve_binary_extension_reg *
184
sieve_binary_extension_get_reg(struct sieve_binary *sbin,
185
             const struct sieve_extension *ext,
186
             bool create)
187
0
{
188
0
  struct sieve_binary_extension_reg *reg = NULL;
189
190
0
  if (ext->id >= 0 &&
191
0
      ext->id < (int)array_count(&sbin->extension_index)) {
192
0
    struct sieve_binary_extension_reg *const *ereg =
193
0
      array_idx(&sbin->extension_index,
194
0
          (unsigned int)ext->id);
195
196
0
    reg = *ereg;
197
0
  }
198
199
  /* Register if not known */
200
0
  if (reg == NULL && create)
201
0
    return sieve_binary_extension_create_reg(sbin, ext);
202
0
  return reg;
203
0
}
Unexecuted instantiation: sieve-binary.c:sieve_binary_extension_get_reg
Unexecuted instantiation: sieve-binary-file.c:sieve_binary_extension_get_reg
Unexecuted instantiation: sieve-binary-code.c:sieve_binary_extension_get_reg
Unexecuted instantiation: sieve-binary-dumper.c:sieve_binary_extension_get_reg
Unexecuted instantiation: sieve-binary-debug.c:sieve_binary_extension_get_reg
204
205
static inline int
206
sieve_binary_extension_register(struct sieve_binary *sbin,
207
        const struct sieve_extension *ext,
208
        struct sieve_binary_extension_reg **reg_r)
209
0
{
210
0
  struct sieve_binary_extension_reg *ereg;
211
212
0
  if ((ereg = sieve_binary_extension_get_reg(sbin, ext, FALSE)) == NULL) {
213
0
    ereg = sieve_binary_extension_create_reg(sbin, ext);
214
215
0
    if (ereg == NULL)
216
0
      return -1;
217
218
0
    array_append(&sbin->linked_extensions, &ereg, 1);
219
0
  }
220
221
0
  if (reg_r != NULL)
222
0
    *reg_r = ereg;
223
0
  return ereg->index;
224
0
}
Unexecuted instantiation: sieve-binary.c:sieve_binary_extension_register
Unexecuted instantiation: sieve-binary-file.c:sieve_binary_extension_register
Unexecuted instantiation: sieve-binary-code.c:sieve_binary_extension_register
Unexecuted instantiation: sieve-binary-dumper.c:sieve_binary_extension_register
Unexecuted instantiation: sieve-binary-debug.c:sieve_binary_extension_register
225
226
/* Load/Save */
227
228
bool sieve_binary_load_block(struct sieve_binary_block *);
229
230
/*
231
 * Resource limits
232
 */
233
234
bool sieve_binary_check_resource_usage(struct sieve_binary *sbin);
235
236
int sieve_binary_file_update_resource_usage(struct sieve_binary *sbin,
237
              enum sieve_error *error_code_r);
238
239
#endif