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/plugins/variables/ext-variables-dump.c
Line
Count
Source
1
/* Copyright (c) Pigeonhole authors, see top-level COPYING file */
2
3
#include "lib.h"
4
#include "str.h"
5
6
#include "sieve-common.h"
7
#include "sieve-dump.h"
8
#include "sieve-binary.h"
9
#include "sieve-code.h"
10
11
#include "ext-variables-common.h"
12
#include "ext-variables-dump.h"
13
14
/*
15
 * Code dumper extension
16
 */
17
18
static void
19
ext_variables_code_dumper_free(struct sieve_code_dumper *dumper, void *context);
20
21
static const struct sieve_code_dumper_extension
22
variables_dump_extension = {
23
  &variables_extension,
24
  ext_variables_code_dumper_free,
25
};
26
27
/*
28
 * Code dump context
29
 */
30
31
struct ext_variables_dump_context {
32
  struct sieve_variable_scope *local_scope;
33
  ARRAY(struct sieve_variable_scope *) ext_scopes;
34
};
35
36
static void
37
ext_variables_code_dumper_free(struct sieve_code_dumper *dumper ATTR_UNUSED,
38
             void *context)
39
0
{
40
0
  struct ext_variables_dump_context *dctx =
41
0
    (struct ext_variables_dump_context *)context;
42
43
0
  if (dctx == NULL || dctx->local_scope == NULL)
44
0
    return;
45
46
0
  sieve_variable_scope_unref(&dctx->local_scope);
47
0
}
48
49
static struct ext_variables_dump_context *
50
ext_variables_dump_get_context(const struct sieve_extension *this_ext,
51
             const struct sieve_dumptime_env *denv)
52
0
{
53
0
  struct sieve_code_dumper *dumper = denv->cdumper;
54
0
  struct ext_variables_dump_context *dctx;
55
0
  pool_t pool;
56
57
0
  i_assert(sieve_extension_is(this_ext, variables_extension));
58
0
  dctx = sieve_dump_extension_get_context(dumper, this_ext);
59
60
0
  if (dctx == NULL) {
61
    /* Create dumper context */
62
0
    pool = sieve_code_dumper_pool(dumper);
63
0
    dctx = p_new(pool, struct ext_variables_dump_context, 1);
64
0
    p_array_init(&dctx->ext_scopes, pool,
65
0
           sieve_extensions_get_count(this_ext->svinst));
66
67
0
    sieve_dump_extension_register(dumper, this_ext,
68
0
                &variables_dump_extension, dctx);
69
0
  }
70
0
  return dctx;
71
0
}
72
73
bool ext_variables_code_dump(const struct sieve_extension *ext,
74
           const struct sieve_dumptime_env *denv,
75
           sieve_size_t *address)
76
0
{
77
0
  struct ext_variables_dump_context *dctx;
78
0
  struct sieve_variable_scope *local_scope;
79
80
0
  local_scope = sieve_variable_scope_binary_dump(ext->svinst, ext, NULL,
81
0
                   denv, address);
82
83
0
  dctx = ext_variables_dump_get_context(ext, denv);
84
0
  dctx->local_scope = local_scope;
85
86
0
  return TRUE;
87
0
}
88
89
/*
90
 * Scope registry
91
 */
92
93
void sieve_ext_variables_dump_set_scope(const struct sieve_extension *var_ext,
94
          const struct sieve_dumptime_env *denv,
95
          const struct sieve_extension *ext,
96
          struct sieve_variable_scope *scope)
97
0
{
98
0
  struct ext_variables_dump_context *dctx =
99
0
    ext_variables_dump_get_context(var_ext, denv);
100
101
0
  if (ext->id < 0)
102
0
    return;
103
104
0
  array_idx_set(&dctx->ext_scopes, (unsigned int) ext->id, &scope);
105
0
}
106
107
/*
108
 * Variable identifier dump
109
 */
110
111
const char *
112
ext_variables_dump_get_identifier(const struct sieve_extension *var_ext,
113
          const struct sieve_dumptime_env *denv,
114
          const struct sieve_extension *ext,
115
          unsigned int index)
116
0
{
117
0
  struct ext_variables_dump_context *dctx =
118
0
    ext_variables_dump_get_context(var_ext, denv);
119
0
  struct sieve_variable_scope *scope;
120
0
  struct sieve_variable *var;
121
122
0
  if (ext == NULL)
123
0
    scope = dctx->local_scope;
124
0
  else {
125
0
    struct sieve_variable_scope *const *ext_scope;
126
127
0
    if (ext->id < 0 ||
128
0
        ext->id >= (int) array_count(&dctx->ext_scopes))
129
0
      return NULL;
130
131
0
    ext_scope = array_idx(&dctx->ext_scopes,
132
0
              (unsigned int)ext->id);
133
0
    scope = *ext_scope;
134
0
  }
135
136
0
  if (scope == NULL)
137
0
    return NULL;
138
139
0
  var = sieve_variable_scope_get_indexed(scope, index);
140
0
  return var->identifier;
141
0
}