cURL / Mailing Lists / curl-library / Single Mail

curl-library

RE: getinmemory.c sample crashes with TCHAR

From: Itamar Syn-Hershko <itamar_at_divrei-tora.com>
Date: Mon, 13 Nov 2006 01:12:43 +0200

 
> -----Original Message-----
> From: curl-library-bounces_at_cool.haxx.se
> [mailto:curl-library-bounces_at_cool.haxx.se] On Behalf Of
> Daniel Stenberg
> Sent: Monday, November 13, 2006 12:21 AM
> To: libcurl development
> Subject: Re: getinmemory.c sample crashes with TCHAR
>
> On Sun, 12 Nov 2006, Itamar Syn-Hershko wrote:
>
> > 4. After compiled, it crashes with AV at this line:
> > mem->memory[mem->size] = 0;. I'm 100% it will crash at your end if
> > you'll compile the same code with wchar_t*.
>
> You ask for help.
>
> I offer to view your code or possibly test it.
>
> You don't show any code.
>
> I can't test or review it.
>

There it is. As I said, it is 99% identical to what you have in your sample.
It contains 2 changes only - TCHAR instead of char, and the use of CString
in the end of the process (the crash occurs before than anyway).

struct MemoryStruct {
    TCHAR *memory;
    size_t size;
};

void *myrealloc(void *ptr, size_t size)
{
    /* There might be a realloc() out there that doesn't like reallocing
    NULL pointers, so we take care of it here */
    if(ptr)
        return realloc(ptr, size);
    else
        return malloc(size);
}

size_t
    WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
    size_t realsize = size * nmemb;
    struct MemoryStruct *mem = (struct MemoryStruct *)data;

    mem->memory = (TCHAR*)myrealloc(mem->memory, mem->size + realsize + 1);
    if (mem->memory) {
        memcpy(&(mem->memory[mem->size]), ptr, realsize);
        mem->size += realsize;
        mem->memory[mem->size] = 0; // Crashes with AV here
    }
    return realsize;
}

bool DownloadToString(LPCTSTR szURL, CString& szData)
{
    CURL *curl_handle;

    USES_CONVERSION;

    struct MemoryStruct chunk;
    chunk.memory=NULL; /* we expect realloc(NULL, size) to work */
    chunk.size = 0; /* no data at this point */

    curl_global_init(CURL_GLOBAL_ALL);

    /* init the curl session */
    curl_handle = curl_easy_init();

    /* specify URL to get */
    curl_easy_setopt(curl_handle, CURLOPT_URL, T2A(szURL));

    /* fail on 404 errors */
    curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1);

    /* send all data to this function */
    curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION,
WriteMemoryCallback);

    /* we pass our 'chunk' struct to the callback function */
    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);

    /* some servers don't like requests that are made without a user-agent
    field, so we provide one */
    curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");

    /* get it! */
    curl_easy_perform(curl_handle);

    /* cleanup curl stuff */
    curl_easy_cleanup(curl_handle);

    if(chunk.memory) {
        try {
            szData.Format(_T("%S"), chunk.memory);
        } catch (CFileException* e) {
            // Something went wrong.
            e->ReportError ();
            e->Delete ();
            free(chunk.memory);
            return false;
        }
        free(chunk.memory);
        return true;
    } else {
        AfxMessageBox(_T("Error downloading")); // error code?
        return false;
    }
}

Itamar.
Received on 2006-11-13