~hkdb/geary/disco-3.34.1

« back to all changes in this revision

Viewing changes to src/engine/imap/message/imap-data-format.vala

  • Committer: hkdb
  • Date: 2019-10-08 10:54:21 UTC
  • Revision ID: hkdb@3df.io-20191008105421-3dkwnpnhcamm77to
Tags: upstream-3.34.1-disco
ImportĀ upstreamĀ versionĀ 3.34.1-disco

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2016 Software Freedom Conservancy Inc.
 
2
 *
 
3
 * This software is licensed under the GNU Lesser General Public License
 
4
 * (version 2.1 or later).  See the COPYING file in this distribution.
 
5
 */
 
6
 
 
7
namespace Geary.Imap.DataFormat {
 
8
 
 
9
private const char[] ATOM_SPECIALS = {
 
10
    '(', ')', '{', ' ', // CTL chars are handled by is_special_char
 
11
    '%', '*',           // list-wildcards
 
12
    '"', '\\',          // quoted-specials
 
13
    ']'                 // resp-specials
 
14
};
 
15
 
 
16
private const char[] TAG_SPECIALS = {
 
17
    '(', ')', '{', '%', '\"', '\\', '+'
 
18
};
 
19
 
 
20
public enum Quoting {
 
21
    REQUIRED,
 
22
    OPTIONAL,
 
23
    UNALLOWED
 
24
}
 
25
 
 
26
private bool is_special_char(char ch, char[] ar, string? exceptions) {
 
27
    // Check for CTL chars
 
28
    if (ch <= 0x1F || ch >= 0x7F) {
 
29
        return true;
 
30
    }
 
31
 
 
32
    if (ch in ar) {
 
33
        return (exceptions != null) ? Ascii.index_of(exceptions, ch) < 0 : true;
 
34
    }
 
35
 
 
36
    return false;
 
37
}
 
38
 
 
39
/**
 
40
 * Returns true if the character is considered an atom special.  Note that while documentation
 
41
 * indicates that the backslash cannot be used in an atom, they *are* used for message flags and
 
42
 * thus must be special cased by the caller.
 
43
 */
 
44
public inline bool is_atom_special(char ch, string? exceptions = null) {
 
45
    return is_special_char(ch, ATOM_SPECIALS, exceptions);
 
46
}
 
47
 
 
48
/**
 
49
 * Tag specials are like atom specials but include the continuation character ('+').  Also, the
 
50
 * star character is allowed, although technically only correct in the context of a status response;
 
51
 * it's the responsibility of the caller to catch this.
 
52
 */
 
53
public bool is_tag_special(char ch, string? exceptions = null) {
 
54
    return is_special_char(ch, TAG_SPECIALS, exceptions);
 
55
}
 
56
 
 
57
/**
 
58
 * Returns Quoting to indicate if the string must be quoted before sent on the wire, of if it
 
59
 * must be sent as a literal.
 
60
 */
 
61
public Quoting is_quoting_required(string str) {
 
62
    if (String.is_empty(str))
 
63
        return Quoting.REQUIRED;
 
64
 
 
65
    int index = 0;
 
66
    for (;;) {
 
67
        char ch = str[index++];
 
68
        if (ch == String.EOS)
 
69
            break;
 
70
 
 
71
        if (ch > 0x7F)
 
72
            return Quoting.UNALLOWED;
 
73
 
 
74
        switch (ch) {
 
75
            case '\n':
 
76
            case '\r':
 
77
                return Quoting.UNALLOWED;
 
78
 
 
79
            default:
 
80
                if (is_atom_special(ch))
 
81
                    return Quoting.REQUIRED;
 
82
            break;
 
83
        }
 
84
    }
 
85
 
 
86
    return Quoting.OPTIONAL;
 
87
}
 
88
 
 
89
 
 
90
}
 
91