recipient_item *oldlist = recipients_list;
int oldmax = recipients_list_max;
recipients_list_max = recipients_list_max ? 2*recipients_list_max : 50;
- recipients_list = store_get(recipients_list_max * sizeof(recipient_item));
+ recipients_list = store_get(recipients_list_max * sizeof(recipient_item), FALSE);
if (oldlist != NULL)
memcpy(recipients_list, oldlist, oldmax * sizeof(recipient_item));
}
if (LOGGING(pipelining) && f.smtp_in_pipelining_advertised)
{
g = string_catn(g, US" L", 2);
-#ifdef EXPERIMENTAL_PIPE_CONNECT
+#ifdef SUPPORT_PIPE_CONNECT
if (f.smtp_in_early_pipe_used)
g = string_catn(g, US"*", 1);
else if (f.smtp_in_early_pipe_advertised)
uschar *queued_by = NULL;
uschar *errmsg;
+rmark rcvd_log_reset_point;
gstring * g;
struct stat statbuf;
/* Working header pointers */
+rmark reset_point;
header_line *next;
/* Flags for noting the existence of certain headers (only one left) */
header. Temporarily mark it as "old", i.e. not to be used. We keep header_last
pointing to the end of the chain to make adding headers simple. */
-received_header = header_list = header_last = store_get(sizeof(header_line));
+received_header = header_list = header_last = store_get(sizeof(header_line), FALSE);
header_list->next = NULL;
header_list->type = htype_old;
header_list->text = NULL;
/* Control block for the next header to be read. */
-next = store_get(sizeof(header_line));
-next->text = store_get(header_size);
+reset_point = store_mark();
+next = store_get(sizeof(header_line), FALSE); /* not tainted */
+next->text = store_get(header_size, TRUE); /* tainted */
/* Initialize message id to be null (indicating no message read), and the
header names list to be the normal list. Indicate there is no data file open
goto OVERSIZE;
header_size *= 2;
- if (!store_extend(next->text, oldsize, header_size))
- next->text = store_newblock(next->text, header_size, ptr);
+ /* The data came from the message, so is tainted. */
+
+ if (!store_extend(next->text, TRUE, oldsize, header_size))
+ next->text = store_newblock(next->text, TRUE, header_size, ptr);
}
/* Cope with receiving a binary zero. There is dispute about whether
if (ch == '\n')
{
message_ended = END_DOT;
- store_reset(next);
+ reset_point = store_reset(reset_point);
next = NULL;
break; /* End character-reading loop */
}
if (ptr == 1)
{
- store_reset(next);
+ reset_point = store_reset(reset_point);
next = NULL;
break;
}
next->text[ptr] = 0;
next->slen = ptr;
- store_reset(next->text + ptr + 1);
+ store_release_above(next->text + ptr + 1);
/* Check the running total size against the overall message size limit. We
don't expect to fail here, but if the overall limit is set less than MESSAGE_
/* Set up for the next header */
+ reset_point = store_mark();
header_size = 256;
- next = store_get(sizeof(header_line));
- next->text = store_get(header_size);
+ next = store_get(sizeof(header_line), FALSE);
+ next->text = store_get(header_size, TRUE);
ptr = 0;
had_zero = 0;
prevlines_length = 0;
white space that follows the newline must not be removed - it is part
of the header. */
- pp = recipient = store_get(ss - s + 1);
+ pp = recipient = store_get(ss - s + 1, is_tainted(s));
for (uschar * p = s; p < ss; p++) if (*p != '\n') *pp++ = *p;
*pp = 0;
if (recipient == NULL && Ustrcmp(errmess, "empty address") != 0)
{
int len = Ustrlen(s);
- error_block *b = store_get(sizeof(error_block));
+ error_block *b = store_get(sizeof(error_block), FALSE);
while (len > 0 && isspace(s[len-1])) len--;
b->next = NULL;
b->text1 = string_printing(string_copyn(s, len));
if (LOGGING(received_recipients))
{
- raw_recipients = store_get(recipients_count * sizeof(uschar *));
+ raw_recipients = store_get(recipients_count * sizeof(uschar *), FALSE);
for (int i = 0; i < recipients_count; i++)
raw_recipients[i] = string_copy(recipients_list[i].address);
raw_recipients_count = recipients_count;
message id is actually an addr-spec, we can use the parse routine to canonicalize
it. */
+rcvd_log_reset_point = store_mark();
g = string_get(256);
g = string_append(g, 2,
g = add_host_info_for_log(g);
-#ifdef SUPPORT_TLS
+#ifndef DISABLE_TLS
if (LOGGING(tls_cipher) && tls_in.cipher)
+ {
g = string_append(g, 2, US" X=", tls_in.cipher);
+# ifdef EXPERIMENTAL_TLS_RESUME
+ if (LOGGING(tls_resumption) && tls_in.resumption & RESUME_USED)
+ g = string_catn(g, US"*", 1);
+# endif
+ }
if (LOGGING(tls_certificate_verified) && tls_in.cipher)
g = string_append(g, 2, US" CV=", tls_in.certificate_verified ? "yes":"no");
if (LOGGING(tls_peerdn) && tls_in.peerdn)
case '4': /* Temp-reject. Keep spoolfiles and accept, unless defer-pass mode.
... for which, pass back the exact error */
- if (cutthrough.defer_pass) smtp_reply = string_copy_malloc(msg);
+ if (cutthrough.defer_pass) smtp_reply = string_copy_perm(msg, TRUE);
cutthrough_done = TMP_REJ; /* Avoid the usual immediate delivery attempt */
break; /* message_id needed for SMTP accept below */
break; /* message_id needed for SMTP accept below */
case '5': /* Perm-reject. Do the same to the source. Dump any spoolfiles */
- smtp_reply = string_copy_malloc(msg); /* Pass on the exact error */
+ smtp_reply = string_copy_perm(msg, TRUE); /* Pass on the exact error */
cutthrough_done = PERM_REJ;
break;
}
}
f.receive_call_bombout = FALSE;
-store_reset(g); /* The store for the main log message can be reused */
+/* The store for the main log message can be reused */
+rcvd_log_reset_point = store_reset(rcvd_log_reset_point);
/* If the message is frozen, and freeze_tell is set, do the telling. */