bluetiger9 / SmtpClient-for-Qt

An SMTP Client writen in C++ for Qt. Allows applications to send emails (MIME with text, html, attachments, inline files, etc.) via SMTP. Supports SSL and SMTP authentication.
https://github.com/bluetiger9/SmtpClient-for-Qt/wiki
GNU Lesser General Public License v2.1
449 stars 226 forks source link

The SmtpClient object breaks when the smtp.quit() method is called; #150

Closed remizero closed 11 months ago

remizero commented 11 months ago

Hello friend, I have put the library to work correctly from the default v2.0 branch, although it sends the email correctly, it is generating the following error and the execution of the application is broken. This is the output generated by the SmtpClient library when executing the example code presented in the project readme file.

@bluetiger9

[SmtpClient] State: ConnectingState [Socket] State: QAbstractSocket::HostLookupState [Socket] State: QAbstractSocket::ConnectingState [Socket] State: QAbstractSocket::ConnectedState [SmtpClient] State: ConnectedState [Socket] IN: "220 MR1P264CA0032.outlook.office365.com Microsoft ESMTP MAIL Service ready at Wed, 4 Oct 2023 15:07:13 +0000\r\n" [SmtpClient] State: _EHLO_State [Socket] OUT: "EHLO localhost" [Socket] IN: "250-MR1P264CA0032.outlook.office365.com Hello [92.191.144.22]\r\n" [Socket] IN: "250-SIZE 157286400\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-8BITMIME\r\n" [Socket] IN: "250-BINARYMIME\r\n" [Socket] IN: "250-CHUNKING\r\n" [Socket] IN: "250 SMTPUTF8\r\n" [SmtpClient] State: _TLS_State [SmtpClient] State: _TLS_0_STARTTLS [Socket] OUT: "STARTTLS" [Socket] IN: "220 2.0.0 SMTP server ready\r\n" [SmtpClient] State: _TLS_1_ENCRYPT [SmtpClient] State: _TLS_2_EHLO [Socket] OUT: "EHLO localhost" [Socket] IN: "250-MR1P264CA0032.outlook.office365.com Hello [92.191.144.22]\r\n" [Socket] IN: "250-SIZE 157286400\r\n" [Socket] IN: "250-PIPELINING\r\n" [Socket] IN: "250-DSN\r\n" [Socket] IN: "250-ENHANCEDSTATUSCODES\r\n" [Socket] IN: "250-AUTH LOGIN XOAUTH2\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" [SmtpClient] State: _READY_Encrypted [SmtpClient] State: _READY_Connected [SmtpClient] State: ReadyState [SmtpClient] State: AuthenticatingState [SmtpClient] State: _AUTH_LOGIN_0 [Socket] OUT: "AUTH LOGIN" [Socket] IN: "334 VXNlcm5hbWU6\r\n" [SmtpClient] State: _AUTH_LOGIN_1_USER [Socket] OUT: "ZmlsemFhQGhvdG1haWwuY29t" [Socket] IN: "334 UGFzc3dvcmQ6\r\n" [SmtpClient] State: _AUTH_LOGIN_2_PASS [Socket] OUT: "SmFoR3VpYVlvNjY2" [Socket] IN: "235 2.7.0 Authentication successful\r\n" [SmtpClient] State: _READY_Authenticated [SmtpClient] State: ReadyState [SmtpClient] State: MailSendingState [SmtpClient] State: _MAIL_0_FROM [Socket] OUT: "MAIL FROM:username@domain.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:username@domain.com" [Socket] IN: "250 2.1.5 Recipient OK\r\n" [SmtpClient] State: _MAIL_2_RCPT [SmtpClient] State: _MAIL_1_RCPT_INIT [SmtpClient] State: _MAIL_2_RCPT [SmtpClient] State: _MAIL_1_RCPT_INIT [SmtpClient] State: _MAIL_2_RCPT [SmtpClient] State: _MAIL_1_RCPT_INIT [SmtpClient] State: _MAIL_3_DATA [Socket] OUT: "DATA" [Socket] IN: "354 Start mail input; end with .\r\n" [SmtpClient] State: _MAIL_4_SEND_DATA [Socket] OUT: "From: USERNAME username@domain.com\r\nTo: USERNAME username@domain.com\r\nSubject: SmtpClient for Qt - Demo\r\nMIME-Version: 1.0\r\nContent-Type: multipart/related; boundary=abae57cb562ecf295b4a37a76efe61fb\r\nContent-Transfer-Encoding: 8bit\r\n\r\n--abae57cb562ecf295b4a37a76efe61fb\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Transfer-Encoding: 8bit\r\n\r\nHi,\nThis is a simple email message.\n\r\n--abae57cb562ecf295b4a37a76efe61fb--\r\n" [Socket] OUT: "\r\n." [Socket] IN: "250 2.0.0 OK DS7PR05MB9828B825841F1220B77963EDD6CBA@DS7PR05MB9828.namprd05.prod.outlook.com [Hostname=DS7PR05MB9828.namprd05.prod.outlook.com]\r\n" [SmtpClient] State: _READY_MailSent [SmtpClient] State: ReadyState [SmtpClient] State: _QUITTING_State [Socket] OUT: "QUIT" munmap_chunk(): invalid pointer 17:07:16: /home/remizero/Proyectos/Qt/qtrcp-Debug/build/debug/Appventanaprincipal crashed.

remizero commented 11 months ago

Apparently the problem is at the destructor level, but I can't identify what the correct order of execution of the destructors should be. but what I have been able to identify is the following:

managing to enter SmtpClient::~SmtpClient() {} managing to enter inline QString::~QString() {} managing to enter QArrayDataPointer::~QArrayDataPointer() managing to enter inline QString::~QString() {} managing to enter QArrayDataPointer::~QArrayDataPointer() MimePart::~MimePart() { return; } Entering this last destructor breaks the object removal execution and ends up breaking the application execution at some point when exiting the next destroyer MimeMessage::~MimeMessage() { if (this->mimeContentAutoCreated) { delete this->content; } }

It should be noted that this is the code that I have used, the same one that appears in the project readme.

`MimeMessage message;

EmailAddress sender("your_email_address@host.com", "Your Name"); message.setSender(sender);

EmailAddress to("recipient@host.com", "Recipient's Name"); message.addRecipient(to);

message.setSubject("SmtpClient for Qt - Demo");

// Now add some text to the email. // First we create a MimeText object.

MimeText text;

text.setText("Hi,\nThis is a simple email message.\n");

// Now add it to the mail

message.addPart(&text);

// Now we can send the mail SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);

smtp.connectToHost(); if (!smtp.waitForReadyConnected()) { qDebug() << "Failed to connect to host!"; return -1; }

smtp.login("your_email_address@host.com", "your_password"); if (!smtp.waitForAuthenticated()) { qDebug() << "Failed to login!"; return -2; }

smtp.sendMail(message); if (!smtp.waitForMailSent()) { qDebug() << "Failed to send mail!"; return -3; }

smtp.quit();`

storozhev-i commented 11 months ago

I encountered the same error. The solution is to declare a MimeText object on the heap:

MimeText* text = new MimeText();

text.setText("Hi,\nThis is a simple email message.\n");

// Now add it to the mail

message.addPart(&text);

remizero commented 11 months ago

I have performed the suggested test. Although the application does not break, it does not send the email either, causing an authentication failure on the SMTP server.

But I solved it by doing the following

MimeText *text = new MimeText ( message + "\n" ); mimeMessage.addPart ( text );

remizero commented 11 months ago

Thanks for the help

storozhev-i commented 11 months ago

I had a similar problem. I solved it by increasing the timeout in the method if (!smtp.waitForMailSent(60000)) default timeout = 30000