bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen/* If we have quoted-specials (<">, <\>) in a string, the minimum quoted-string
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen overhead is 3 bytes ("\") while the minimum literal overhead is 5 bytes
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen ("{n}\r\n"). But the literal overhead also depends on the string size. If
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen the string length is less than 10, literal catches up to quoted-string after
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen 3 quoted-specials. If the string length is 10..99, it catches up after 4
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen quoted-specials, and so on. We'll assume that the string lengths are usually
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen in double digits, so we'll switch to literals after seeing 4
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen quoted-specials. */
169d60e9729b7a047ed17e82607101e20c69dcb1Timo Sirainenvoid imap_append_string(string_t *dest, const char *src)
0b1929455dec03c97d35e5286a17a8c7bd1a633bTimo Sirainenvoid imap_append_astring(string_t *dest, const char *src)
0b1929455dec03c97d35e5286a17a8c7bd1a633bTimo Sirainen unsigned int i;
1e430b62d5bb21dc0d227b06a7a322283d75c452Timo Sirainen /* don't mix up NIL and "NIL"! */
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainenimap_append_literal(string_t *dest, const char *src, unsigned int pos)
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen str_printfa(dest, "{%"PRIuSIZE_T"}\r\n", full_len);
169d60e9729b7a047ed17e82607101e20c69dcb1Timo Sirainenvoid imap_append_nstring(string_t *dest, const char *src)
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen /* first check if we can (or want to) write this as quoted or
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen quoted-specials = DQUOTE / "\"
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen QUOTED-CHAR = <any TEXT-CHAR except quoted-specials> /
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen "\" quoted-specials
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen TEXT-CHAR = <any CHAR except CR and LF>
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen switch (src[i]) {
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen /* fall through */
44c6d46cefc24daee032d2a0f95f8576fa10889aSergey Kitovstatic void remove_newlines_and_append(string_t *dest, const char *src)
44c6d46cefc24daee032d2a0f95f8576fa10889aSergey Kitov /* ensure whitespace between lines if new line doesn't start with whitespace */
44c6d46cefc24daee032d2a0f95f8576fa10889aSergey Kitovvoid imap_append_nstring_nolf(string_t *dest, const char *src)
be0c9927cd9856b1a37c9c8c6b73bd7e5a75737cSergey Kitov if (src == NULL || strpbrk(src, "\r\n") == NULL)
44c6d46cefc24daee032d2a0f95f8576fa10889aSergey Kitov else if (buffer_get_pool(dest)->datastack_pool)
2ca9d7b51853007c0edd3bd373375792f2c8272fTimo Sirainenvoid imap_append_quoted(string_t *dest, const char *src)
ed8256349d7106b2d2accdf1ec390cc6a903d887Timo Sirainen /* not allowed */
6764705326c7187d703b784b8e86083c08363549Timo Sirainen /* 8bit input not allowed in dquotes */
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainenvoid imap_append_string_for_humans(string_t *dest,
d8ce48fb2b068ceae03f8df3610e254c3ccd2b2eTimo Sirainen bool whitespace_prefix = TRUE, last_lwsp = TRUE, modify = FALSE;
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen /* first check if there is anything to change */
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen for (i = 0; i < size; i++) {
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen switch (src[i]) {
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen /* convert NUL to #0x80 */
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen /* fall through */
d8ce48fb2b068ceae03f8df3610e254c3ccd2b2eTimo Sirainen if (last_lwsp && i > 0 && !whitespace_prefix) {
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen /* fast path: we can simply write it as quoted string
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen without any escaping */
d8ce48fb2b068ceae03f8df3610e254c3ccd2b2eTimo Sirainen /* contained only whitespace */
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen str_printfa(dest, "{%"PRIuSIZE_T"}\r\n", size - remove_count);
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen for (i = 0; i < size; i++) {
eea128bec7b5af0ece444e0c3b35297cd1e2b31cTimo Sirainen switch (src[i]) {