Coverage Report

Created: 2026-04-12 07:00

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