cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: So close,... buffer overrun crash on ftp upload

From: Jan de Lint <jg.de.lint_at_hccnet.nl>
Date: Sun, 21 Nov 2004 17:01:47 +0100

Joseph, let me tell you where I got the read function which anyhow looks simpler than yours.
I downloaded: curl-7.12.2-win32-ssl-devel-mingw32.zip
It contains examples in docs/examples
At least one of those (I forgot which one) contains a read function that works straight out of the box for me. I think this example is not explicit on the cURL website.
Jan
----- Original Message -----
  From: joseph.tilley_at_atxinc.com
  To: curl-library_at_cool.haxx.se
  Sent: Sunday, November 21, 2004 2:47 PM
  Subject: So close,... buffer overrun crash on ftp upload

  Hi,

  First off Kudos to Daniel Stenberg for the very keen monitoring of this mailing list. Most companies I have worked with/for could only dream of having as professional support for thier products! Want to move to Northern Maine? ;-)

  Anyhow, on to my basic question. I am getting a buffer overrun when my CURLOPT_READFUNCTION returns. I did a search and didn't see anything jump out at me in the mailing archives on this, but I have probably overlooked something simple along the way. When I step through the my_fread call, it all seems to work nicely.

  I am on WinXP, with Curl version 7.11.1.0, connection to a simple FTP with SSL location.

  Again, any insights would be appreciated.

  My callback function:

  //Callback function to read a file from disk for upload to a remote site.
  //A buffer overrun crash occurs when leaving this function!!!
  size_t my_fread(void *ptr, size_t size, size_t nmemb, void *stream)
  {
          //The total size of the buffer we may write to.
          size_t total = size * nmemb;
          //If the size of stream (mlFileSize) is smaller than ptr then use mlFileSize
          if (total > mlFileSize)
                  total = mlFileSize;
          //If we have data to copy
          if (total > 0)
          {
                  //Copy bytes to the ptr buffer.
                  memcpy(ptr, stream, total);
                  //Move the stream to point in plus the remaining data. Not necesary if have finished.
                  if (mlFileSize > total)
                          memcpy(stream, ((char*)stream) + total, mlFileSize - total);
                  //Decrement the FileSize that is left to copy.
                  mlFileSize -= total;
          }
          return total;
  }

  Now the procedure that sets up the call to this function:

  // Put a file onto the FTP server
  // szRemoteFile goes to an ftp server, and has the username/pass as well as the remote
  // filename built in.
  void PutFile(char *szRemoteFile, LPCSTR szLocalFile)
  {
          int res;

          //Initialize variables that are used with file transfers.
          mlFileSize = 0;
          mFileDataBuf = NULL;
          mUploadFile = fopen(szLocalFile, "r"); // Open the local file

          if (NULL == mUploadFile)
                  throw "Unable to open local file";

          //Get the file size
          fseek(mUploadFile, 0, SEEK_END);
        long lFileSize = ftell(mUploadFile);
        fseek(mUploadFile, 0, SEEK_SET);

          //Store the contents of the file in a local buffer.
          mFileDataBuf = (char *)malloc(lFileSize);
        fread (mFileDataBuf, sizeof(char) ,lFileSize, mUploadFile);
          fclose(mUploadFile);

          //Hold on to the file size for use in the callback function.
          mlFileSize = lFileSize;

          curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, TRUE);
        curl_easy_setopt(m_pCurl, CURLOPT_READFUNCTION, my_fread); // Set a pointer to our struct to pass to the callback
        curl_easy_setopt(m_pCurl, CURLOPT_UPLOAD, TRUE) ;
          curl_easy_setopt(m_pCurl, CURLOPT_URL, szRemoteFile); // Set the URL to transmit to
        curl_easy_setopt(m_pCurl, CURLOPT_INFILESIZE, lFileSize);
        curl_easy_setopt(m_pCurl, CURLOPT_READDATA, mFileDataBuf); // Set a pointer to our struct to pass to the callback
          res = curl_easy_perform(m_pCurl);
          
          // always cleanup
          free(mFileDataBuf);

          if(CURLE_OK != res)
                  throw m_szErrMsgLast;
  }

  If it is useful, the procedure that initialized the m_pCurl object:

  initializeCURL(BOOL bPassive, BOOL bSSL)
  {
          if (bSSL)
                  curl_global_init(CURL_GLOBAL_SSL);
          else
                  curl_global_init(CURL_GLOBAL_ALL);

          m_pCurl = curl_easy_init();

          // set the errror buffer
          ZeroMemory(m_szErrMsgLast, cchErrMsgLastMax);
          curl_easy_setopt(m_pCurl, CURLOPT_ERRORBUFFER, m_szErrMsgLast);

          //Set the passive mode
          curl_easy_setopt(m_pCurl, CURLOPT_FTP_USE_EPSV, bPassive);
  }

  Cheers,
  joe

  Joe Tilley
  E-File Senior Engineer
  ATX II, LLC
  Phone: (207) 498-4289 ext. 40728
  Fax: (207) 498-6838
  E-Mail: joseph.tilley_at_atxinc.com
Received on 2004-11-21