/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 | | |