Closed ocgltd closed 1 day ago
自动回复:已收到您的邮件
I tried again by connecting to a working mta, and now the class progresses further but again crashes (with SIGABRT), on the waitForMailSent method.
[SmtpClient] State: ConnectingState
[Socket] State: QAbstractSocket::HostLookupState
[Socket] State: QAbstractSocket::ConnectingState
[Socket] State: QAbstractSocket::ConnectedState
[SmtpClient] State: ConnectedState
[Socket] IN: "220 exchange.obfuscated.com Microsoft ESMTP MAIL Service ready at Tue, 11 Jun 2024 10:27:35 -0400\r\n"
[SmtpClient] State: _EHLO_State
[Socket] OUT: "EHLO localhost"
[Socket] IN: "250-exchange.obfuscated.com Hello [172.31.254.144]\r\n"
[Socket] IN: "250-SIZE 37748736\r\n"
[Socket] IN: "250-PIPELINING\r\n"
[Socket] IN: "250-DSN\r\n"
[Socket] IN: "250-ENHANCEDSTATUSCODES\r\n"
[Socket] IN: "250-STARTTLS\r\n"
[Socket] IN: "250-X-ANONYMOUSTLS\r\n"
[Socket] IN: "250-AUTH NTLM\r\n"
[Socket] IN: "250-X-EXPS GSSAPI NTLM\r\n"
[Socket] IN: "250-8BITMIME\r\n"
[Socket] IN: "250-BINARYMIME\r\n"
[Socket] IN: "250-CHUNKING\r\n"
[Socket] IN: "250-SMTPUTF8\r\n"
[Socket] IN: "250 XRDST\r\n"
[SmtpClient] State: _READY_Connected
[SmtpClient] State: ReadyState
[SmtpClient] State: MailSendingState
[SmtpClient] State: _MAIL_0_FROM
[Socket] OUT: "MAIL FROM:<sample@pbx1.mydomain.com>"
[SmtpClient] State: ConnectingState
[Socket] State: QAbstractSocket::HostLookupState
[Socket] State: QAbstractSocket::ConnectingState
[Socket] IN: "250 2.1.0 Sender OK\r\n"
[SmtpClient] State: _MAIL_1_RCPT_INIT
[SmtpClient] State: _MAIL_2_RCPT
[Socket] OUT: "RCPT TO:<support@mydomain.com>"
[Socket] State: QAbstractSocket::ConnectedState
[SmtpClient] State: ConnectedState
[Socket] IN: "550 5.7.54 SMTP; Unable to relay recipient in non-accepted domain\r\n"
free(): invalid pointer
[Socket] IN: "220 exchange.obfuscated.com Microsoft ESMTP MAIL Service ready at Tue, 11 Jun 2024 10:27:35 -0400\r\n"
[SmtpClient] State: _EHLO_State
[Socket] OUT: "EHLO localhost"
[Socket] IN: "250-exchange.obfuscated.com Hello [172.31.254.144]\r\n"
[Socket] IN: "250-SIZE 37748736\r\n"
[Socket] IN: "250-PIPELINING\r\n"
[Socket] IN: "250-DSN\r\n"
[Socket] IN: "250-ENHANCEDSTATUSCODES\r\n"
[Socket] IN: "250-STARTTLS\r\n"
[Socket] IN: "250-X-ANONYMOUSTLS\r\n"
[Socket] IN: "250-AUTH NTLM\r\n"
[Socket] IN: "250-X-EXPS GSSAPI NTLM\r\n"
[Socket] IN: "250-8BITMIME\r\n"
[Socket] IN: "250-BINARYMIME\r\n"
[Socket] IN: "250-CHUNKING\r\n"
[Socket] IN: "250-SMTPUTF8\r\n"
[Socket] IN: "250 XRDST\r\n"
[SmtpClient] State: _READY_Connected
[SmtpClient] State: ReadyState
[SmtpClient] State: MailSendingState
[SmtpClient] State: _MAIL_0_FROM
[Socket] OUT: "MAIL FROM:<example@pbx1.mydomain.com>"
[Socket] IN: "250 2.1.0 Sender OK\r\n"
[SmtpClient] State: _MAIL_1_RCPT_INIT
[SmtpClient] State: _MAIL_2_RCPT
[Socket] OUT: "RCPT TO:<support@mydomain.com>"
And here's the call stack upon crash:
1 __pthread_kill_implementation pthread_kill.c 44 0x7ffff6ea154c
2 __pthread_kill_internal pthread_kill.c 78 0x7ffff6ea15b3
3 __GI_raise raise.c 26 0x7ffff6e54d46
4 __GI_abort abort.c 79 0x7ffff6e287f3
5 __libc_message libc_fatal.c 150 0x7ffff6e29130
6 malloc_printerr malloc.c 5515 0x7ffff6eab617
7 _int_free malloc.c 4306 0x7ffff6eacecc
8 __GI___libc_free malloc.c 3258 0x7ffff6eaf955
9 MimePart::~MimePart mimepart.cpp 39 0x44e4f9
10 MimeMultiPart::~MimeMultiPart mimemultipart.cpp 48 0x44f2d3
11 MimeMultiPart::~MimeMultiPart mimemultipart.cpp 50 0x44f344
12 MimeMessage::~MimeMessage mimemessage.cpp 41 0x451606
13 Alert::send_email alert.cpp 118 0x44708f
14 Alert::send_alert_generic alert.cpp 324 0x448477
The error occurs in the delete line of the method below; I'm guessing a pointer problem?
MimeMultiPart::~MimeMultiPart() {
foreach (MimePart *part, parts) {
delete part;
}
}
Just in case I'm calling something wrong, I'll show my code...
MimeMessage message;
EmailAddress sender(programSettings->smtp_senderemail(),programSettings->smtp_sendername());
EmailAddress recipient( programSettings->alerts_recipientemail(),programSettings->alerts_recipientname());
message.setSender(sender);
message.addRecipient(recipient);
message.setSubject(email_subject);
MimeHtml html;
MimeText text;
// Create a MimeText object.
if (email_usehtml) {
html.setHtml(email_body);
message.addPart(&html);
} else {
text.setText(email_body);
message.addPart(&text);
}
SmtpClient smtp(programSettings->smtp_hostname(), programSettings->smtp_port(), programSettings>smtp_encryption());
smtp.connectToHost();
if (!smtp.waitForReadyConnected()) {
return false;
}
if (programSettings->smtp_useauthentication()) {
smtp.login(programSettings->smtp_username(),programSettings->smtp_password(),SmtpClient::AuthLogin);
if (!smtp.waitForAuthenticated()) {
return false;
}
}
smtp.sendMail(message);
if (!smtp.waitForMailSent()) {
return false;
}
smtp.quit();
return true;
and I should note that even if a message is successfully sent, the smtpclient crashes! Something in the MimeMultiPart seems to lose track of "parts" (MimePart classes).
Looking at the examples and source, the message.addpart(&mimetextpart) adds a part to the message. But internally it adds a pointer to the original object (which was created on the stack by the caller). But, the mimemultipart destructor tries to delete these MimeText variables. Why is it trying to delete an object from the stack created by the caller?
I tried modifying my code to call smtpclient with body parts created on the heap instead of stack (and not deleting them myself):
// Fill MimeMessage body
MimeHtml* htmlPtr = new MimeHtml;
MimeText* textPtr = new MimeText;
if (email_usehtml) {
htmlPtr->setHtml(email_body);
message.addPart(htmlPtr);
} else {
textPtr->setText(email_body);
message.addPart(textPtr);
}
// Do not delete MimeXXXX since smtp lib will delete these
... and now the code runs without crash. (But, valgrind reports the 2 MimeXXXX objects cause lost memory blocks). Does the smtpclient code need to be changed to make a copy of the mimepart sent to message.addPart ? Am I calling something wrong? Something isn't right here....
This should be fixed now. I changed the .addPart()
method to take ownership of the given part only if requested with the takeOwnership
argument.
See fourth post for cause of error and potential solution
I am building an SMTP client as per the wiki example, using Qt 6.5.0. I am trying to connect to localhost:25, but I do not have any mail server (nothing listening on that port). The smtp client crashes during the connectToHost method, and stderr/stdout shows:
I am sending an HTML body message, but this occurs with just text body as well.