title: libCURL: Crash on Uploading Data (Qt, SMTP)
body: <p>i am trying to implement a quite specialized email-client using libcurl (7.66) for sending the email.</p>
  
  <p>Sadly, it always crashes on calling curl_easy_perform(curl), no matter what i try whatsoever.</p>
  
  <p>Currently in the process_mail callback i have commented everything out; just returning 0. I am pretty shure, this should be enough for at least not crasing the app ...</p>
  
  <p>The real goal would be having the mail as a string in the memory and just copy it over to the stream.</p>
  
  <p>I really appreciate any kind of help ... i have quite a delay because of this issue.</p>
  
  <p>Here is the header-file:</p>
  
  <pre><code>#ifndef MAILMESSAGE_H
  #define MAILMESSAGE_H
  
  #include &lt;QObject&gt;
  #include &lt;QDebug&gt;
  
  #include &lt;QFile&gt;
  #include &lt;QIODevice&gt;
  #include &lt;QByteArray&gt;
  
  #include &lt;curl/curl.h&gt;
  #include &lt;stdio.h&gt;
  
  class MailMessage : public QObject
  {
      Q_OBJECT
  public:
      explicit MailMessage(QObject *parent = nullptr);
  
      void setSMTPPort(QString smtp_port);
      void setSMTPAddress(QString smtp_address);
      void setSMTPUser(QString smtp_user);
      void setSMTPPassword(QString smtp_password);
  
      void addTo(QString address_to);
      void setFrom(QString address_from);
      void setSubject(QString subject);
  
      void setAlternativeText(QString text);
      void setHTML(QString html);
      void addAttachment(QString attachment_path, QString filename);
  
      void generateMessage();
      // return POSIX-style: 0: ok; 1: error
      int sendMail();
  
      QString message;
      int message_size;
      const char* message_char;
  
      QString smtp_port;
      QString smtp_address;
      QString smtp_user;
      QString smtp_password;
      //QStringList addresses_to;
      QString address_to;
      QString address_from;
      QString subject;
      QString payload_text;
      QString payload_html;
      QStringList attachments_base64;
  
      double upload_speed;
      double upload_time;
  
  protected:
      static size_t process_mail(void *ptr, size_t size, size_t nmemb, void *userp);
  
  signals:
  
  public slots:
  };
  
  #endif // MAILMESSAGE_H
  </code></pre>
  
  <p>And the relevant parts of the implementation:</p>
  
  <pre><code>void MailMessage::generateMessage()
  {
      this-&gt;message = //"To: "+ this-&gt;address_to +"\r\n"
              "From: "+ this-&gt;address_from +"\r\n"
              "Subject: "+ this-&gt;subject +"\r\n"
              "Content-Type: multipart/mixed; boundary=MixedBoundary"
              "\r\n"
              "--MixedBoundary"
              "Content-Type: multipart/alternative; boundary=AlternativeBoundary"
              "\r\n"
              "--AlternativeBoundary"
              "Content-Type: text/plain; charset=\"utf-8\""
              "\r\n"+ this-&gt;payload_text +"\r\n"
              "--AlternativeBoundary"
              "Content-Type: text/html; charset=\"utf-8\""
              "\r\n"+ this-&gt;payload_html +"\r\n"
              "--AlternativeBoundary--"
              "\r\n"
              "--MixedBoundary";
      /*
              "Content-Type: application/pdf; name=\"HelloWorld.pdf\""
              "Content-Transfer-Encoding: base64"
              "Content-Disposition: attachment; filename=\"HelloWorld.pdf\"";
      */
      this-&gt;message.append("\r\n"
              "--MixedBoundary--");
  
      QByteArray array = this-&gt;message.toLocal8Bit();
      this-&gt;message_char = array.data();
      this-&gt;message_size = sizeof(this-&gt;message_char);
  }
  
  size_t MailMessage::process_mail(void *ptr, size_t size, size_t nmemb, void *userprocess)
  {
      size_t retcode = 0;
  
      /*
      MailMessage *self = reinterpret_cast&lt;MailMessage*&gt;(userprocess);
  
      if (sizeof(self-&gt;message_char) == 0)
          return retcode;
  
      retcode = (size * nmemb &gt;= sizeof(self-&gt;message_char)) ? sizeof(self-&gt;message_char) : size * nmemb;
  
  
      self-&gt;message_size -= retcode;
      memcpy(ptr, self-&gt;message_char, retcode);
      self-&gt;message_char += retcode;
      */
  
      return retcode;
  }
  
  int MailMessage::sendMail()
  {
      //qDebug() &lt;&lt; this-&gt;message;
  
      CURLcode res = CURLE_OK;
      CURL *curl = curl_easy_init();
      curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
      curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
      // CURLUSESSL_ALL, CURLUSESSL_NONE, CURLUSESSL_TRY, CURLUSESSL_CONTROL
      curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
      curl_easy_setopt(curl, CURLOPT_URL, this-&gt;smtp_address.toStdString().c_str());
      curl_easy_setopt(curl, CURLOPT_USERNAME, this-&gt;smtp_user.toStdString().c_str());
      curl_easy_setopt(curl, CURLOPT_PASSWORD, this-&gt;smtp_password.toStdString().c_str());
      curl_easy_setopt(curl, CURLOPT_MAIL_FROM, this-&gt;address_from.toStdString().c_str());
      curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, this-&gt;address_to.toStdString().c_str());
      curl_easy_setopt(curl, CURLOPT_READFUNCTION, &amp;MailMessage::process_mail);
      curl_easy_setopt(curl, CURLOPT_READDATA, this);
  
      /* Send the message */ 
      res = curl_easy_perform(curl);
  
      /* Check for errors */ 
      if(res != CURLE_OK)
      {
          fprintf(stderr, "curl_easy_perform() failed: %s\n",
                  curl_easy_strerror(res));
      }
      else
      {
          curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &amp;upload_speed);
          curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &amp;upload_time);
  
          qDebug() &lt;&lt; "Speed: "+QString::number(upload_speed) + " Time: "+QString::number(upload_time);
      }
  
      //curl_slist_free_all(this-&gt;address_to.toStdString().c_str());
      curl_easy_cleanup(curl);
  
      return 0;
  }
  </code></pre>
  
  <p>And finally some excerpt of the console output:</p>
  
  <pre><code>*  start date: May  8 08:01:21 2019 GMT
  *  expire date: May 13 23:59:59 2021 GMT
  *  subjectAltName: host "mail.gmx.net" matched cert's "mail.gmx.net"
  *  issuer: C=DE; O=T-Systems International GmbH; OU=T-Systems Trust Center; ST=Nordrhein Westfalen; postalCode=57250; L=Netphen; street=Untere Industriestr. 20; CN=TeleSec ServerPass Extended Validation Class 3 CA
  *  SSL certificate verify ok.
  &gt; EHLO cf-19
  * SMTP 0x5572580cd700 state change from UPGRADETLS to EHLO
  &lt; 250-gmx.com Hello cf-19 [2.202.204.204]
  * Curl_pp_readresp_ 55 bytes of trailing server response left
  &lt; 250-8BITMIME* Curl_pp_readresp_ 41 bytes of trailing server response left
  &lt; 250-AUTH LOGIN PLAIN
  * Curl_pp_readresp_ 19 bytes of trailing server response left
  &lt; 250 SIZE 69920427
  &gt; AUTH PLAIN
  * SASL 0x5572580cd780 state change from STOP to PLAIN
  * SMTP 0x5572580cd700 state change from EHLO to AUTH
  &lt; 334 
  &gt; AHNhbXVlbF9iZWNrZXJAZ214LmRlADI4OTZhY2Q2
  * SASL 0x5572580cd780 state change from PLAIN to FINAL
  &lt; 235 Authentication succeeded
  * SASL 0x5572580cd780 state change from FINAL to STOP
  * SMTP 0x5572580cd700 state change from AUTH to STOP
  * STATE: PROTOCONNECT =&gt; DO handle 0x5572580d0678; line 1701 (connection #0)
  * DO phase starts
  &gt; MAIL FROM:&lt;xxxxxxx@xxx.xx&gt;
  * SMTP 0x5572580cd700 state change from STOP to MAIL
  * STATE: DO =&gt; DOING handle 0x5572580d0678; line 1743 (connection #0)
  &lt; 250 Requested mail action okay, completed
  03:37:55: The program has unexpectedly finished.
  03:37:55: The process was ended forcefully.
  </code></pre>