Coverage Report

Created: 2026-07-30 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pigeonhole/src/lib-sieve/plugins/enotify/vmodf-encodeurl.c
Line
Count
Source
1
/* Copyright (c) Pigeonhole authors, see top-level COPYING file */
2
3
#include "lib.h"
4
#include "unichar.h"
5
#include "str.h"
6
7
#include "sieve-common.h"
8
#include "sieve-code.h"
9
10
#include "sieve-ext-variables.h"
11
12
#include "ext-enotify-common.h"
13
14
/*
15
 * Encodeurl modifier
16
 */
17
18
static bool
19
mod_encodeurl_modify(const struct sieve_variables_modifier *modf,
20
         string_t *in, string_t **result);
21
22
const struct sieve_variables_modifier_def encodeurl_modifier = {
23
  SIEVE_OBJECT("encodeurl", &encodeurl_operand, 0),
24
  15,
25
  mod_encodeurl_modify,
26
};
27
28
/*
29
 * Modifier operand
30
 */
31
32
static const struct sieve_extension_objects ext_enotify_modifiers =
33
  SIEVE_VARIABLES_DEFINE_MODIFIER(encodeurl_modifier);
34
35
const struct sieve_operand_def encodeurl_operand = {
36
  .name = "modifier",
37
  .ext_def = &enotify_extension,
38
  .class = &sieve_variables_modifier_operand_class,
39
  .interface = &ext_enotify_modifiers,
40
};
41
42
/*
43
 * Modifier implementation
44
 */
45
46
static const char _uri_reserved_lookup[256] = {
47
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 00
48
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 10
49
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1,  // 20
50
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,  // 30
51
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 40
52
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,  // 50
53
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 60
54
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,  // 70
55
56
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 80
57
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 90
58
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A0
59
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B0
60
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C0
61
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D0
62
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E0
63
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // F0
64
};
65
66
static bool
67
mod_encodeurl_modify(const struct sieve_variables_modifier *modf,
68
         string_t *in, string_t **result)
69
0
{
70
0
  size_t max_val_size =
71
0
    sieve_variables_get_max_value_size(modf->var_ext);
72
0
  const unsigned char *p, *poff, *pend;
73
0
  size_t new_size;
74
75
0
  if (str_len(in) == 0) {
76
0
    *result = in;
77
0
    return TRUE;
78
0
  }
79
80
  /* allocate new string */
81
0
  new_size = str_len(in) + 32;
82
0
  if (new_size > max_val_size)
83
0
    new_size = max_val_size;
84
0
  *result = t_str_new(new_size + 1);
85
86
  /* escape string */
87
0
  p = str_data(in);
88
0
  pend = p + str_len(in);
89
0
  poff = p;
90
0
  while (p < pend) {
91
0
    unsigned int i, n = uni_utf8_char_bytes(*p);
92
93
0
    if (n > 1 || (_uri_reserved_lookup[*p] & 0x01) != 0) {
94
0
      str_append_data(*result, poff, p - poff);
95
0
      poff = p;
96
97
0
      if (str_len(*result) + 3 * n > max_val_size)
98
0
        break;
99
100
0
      str_printfa(*result, "%%%02X", *p);
101
0
      for (i = 1; i < n && p < pend; i++) {
102
0
        p++;
103
0
        poff++;
104
0
        str_printfa(*result, "%%%02X", *p);
105
0
      }
106
107
0
      poff++;
108
0
    } else if ((str_len(*result) + (p - poff) + 1) > max_val_size) {
109
0
      break;
110
0
    }
111
0
    p++;
112
0
  }
113
114
0
  str_append_data(*result, poff, p - poff);
115
0
  return TRUE;
116
0
}