curl/tests/libtest/lib2302.c
Viktor Szakats 7e282e18a5
lib2302: fix crash due to stack overflow on MSVC and clang Windows
It fixes test 2302, 2303, 2307 with MSVC and clang on Windows.
GCC Windows builds were not affected.

Failure was caused by stack overflow due to a 1MB+ sized test struct on
stack. Replace it with dynamic allocation.

Also unignore affected tests in GHA/windows.

As seen under WINE with llvm-mingw:
```
$ wine64 libtests.exe lib2302 ws://127.0.0.1:59964/2302 > stdout2302 2> stderr2302
Test: lib2302
URL: ws://127.0.0.1:59964/2302
wine: Unhandled stack overflow at address 000000014007486A (thread 0024), starting debugger...
Unhandled exception: stack overflow in 64-bit code (0x000000014007486a).
```

Ref: #16629 (discovery)
Ref: 1bd5ac998b #16570

Closes #16630
2025-03-09 11:53:12 +01:00

132 lines
3.3 KiB
C

/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "test.h"
#ifndef CURL_DISABLE_WEBSOCKETS
struct ws_data {
CURL *easy;
char *buf;
size_t blen;
size_t nwrites;
int has_meta;
int meta_flags;
};
#define LIB2302_BUFSIZE (1024 * 1024)
static void flush_data(struct ws_data *wd)
{
size_t i;
if(!wd->nwrites)
return;
for(i = 0; i < wd->blen; ++i)
printf("%02x ", (unsigned char)wd->buf[i]);
printf("\n");
if(wd->has_meta)
printf("RECFLAGS: %x\n", wd->meta_flags);
else
fprintf(stderr, "RECFLAGS: NULL\n");
wd->blen = 0;
wd->nwrites = 0;
}
static size_t add_data(struct ws_data *wd, const char *buf, size_t blen,
const struct curl_ws_frame *meta)
{
if((wd->nwrites == 0) ||
(!!meta != !!wd->has_meta) ||
(meta && meta->flags != wd->meta_flags)) {
if(wd->nwrites > 0)
flush_data(wd);
wd->has_meta = (meta != NULL);
wd->meta_flags = meta ? meta->flags : 0;
}
if(wd->blen + blen > LIB2302_BUFSIZE) {
return 0;
}
memcpy(wd->buf + wd->blen, buf, blen);
wd->blen += blen;
wd->nwrites++;
return blen;
}
static size_t writecb(char *buffer, size_t size, size_t nitems, void *p)
{
struct ws_data *ws_data = p;
size_t incoming = nitems;
const struct curl_ws_frame *meta;
(void)size;
meta = curl_ws_meta(ws_data->easy);
incoming = add_data(ws_data, buffer, incoming, meta);
if(nitems != incoming)
fprintf(stderr, "returns error from callback\n");
return nitems;
}
CURLcode test(char *URL)
{
CURL *curl;
CURLcode res = CURLE_OK;
struct ws_data ws_data;
memset(&ws_data, 0, sizeof(ws_data));
ws_data.buf = (char *)calloc(LIB2302_BUFSIZE, 1);
if(!ws_data.buf)
return res;
global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
ws_data.easy = curl;
curl_easy_setopt(curl, CURLOPT_URL, URL);
/* use the callback style */
curl_easy_setopt(curl, CURLOPT_USERAGENT, "webbie-sox/3");
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ws_data);
res = curl_easy_perform(curl);
fprintf(stderr, "curl_easy_perform() returned %d\n", res);
/* always cleanup */
curl_easy_cleanup(curl);
flush_data(&ws_data);
}
curl_global_cleanup();
free(ws_data.buf);
return res;
}
#else
NO_SUPPORT_BUILT_IN
#endif