Coverage Report

Created: 2026-08-31 07:00

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