lib: add void *ctx to reader/writer instances

- `struct Curl_cwriter` and `struct Curl_creader` now carry a
  `void *ctx` member that points to the instance as allocated.
- using `r->ctx` and `w->ctx` as pointer to the instance specific
  struct that has been allocated

Reported-by: Rudi Heitbaum
Fixes #13035
Closes #13059
This commit is contained in:
Stefan Eissing 2024-03-06 09:52:43 +01:00 committed by Daniel Stenberg
parent 2ca530d2fa
commit 9978d40ddb
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
8 changed files with 68 additions and 50 deletions

View file

@ -123,7 +123,7 @@ struct Curl_cwtype Curl_cwt_out = {
static CURLcode cw_out_init(struct Curl_easy *data,
struct Curl_cwriter *writer)
{
struct cw_out_ctx *ctx = (struct cw_out_ctx *)writer;
struct cw_out_ctx *ctx = writer->ctx;
(void)data;
ctx->buf = NULL;
return CURLE_OK;
@ -151,7 +151,7 @@ static size_t cw_out_bufs_len(struct cw_out_ctx *ctx)
static void cw_out_close(struct Curl_easy *data, struct Curl_cwriter *writer)
{
struct cw_out_ctx *ctx = (struct cw_out_ctx *)writer;
struct cw_out_ctx *ctx = writer->ctx;
(void)data;
cw_out_bufs_free(ctx);
@ -378,7 +378,7 @@ static CURLcode cw_out_write(struct Curl_easy *data,
struct Curl_cwriter *writer, int type,
const char *buf, size_t blen)
{
struct cw_out_ctx *ctx = (struct cw_out_ctx *)writer;
struct cw_out_ctx *ctx = writer->ctx;
CURLcode result;
bool flush_all;

View file

@ -273,7 +273,7 @@ static CURLcode ftp_cw_lc_write(struct Curl_easy *data,
const char *buf, size_t blen)
{
static const char nl = '\n';
struct ftp_cw_lc_ctx *ctx = (struct ftp_cw_lc_ctx *)writer;
struct ftp_cw_lc_ctx *ctx = writer->ctx;
if(!(type & CLIENTWRITE_BODY) ||
data->conn->proto.ftpc.transfertype != 'A')

View file

@ -394,7 +394,7 @@ struct chunked_writer {
static CURLcode cw_chunked_init(struct Curl_easy *data,
struct Curl_cwriter *writer)
{
struct chunked_writer *ctx = (struct chunked_writer *)writer;
struct chunked_writer *ctx = writer->ctx;
data->req.chunk = TRUE; /* chunks coming our way. */
Curl_httpchunk_init(data, &ctx->ch, FALSE);
@ -404,7 +404,7 @@ static CURLcode cw_chunked_init(struct Curl_easy *data,
static void cw_chunked_close(struct Curl_easy *data,
struct Curl_cwriter *writer)
{
struct chunked_writer *ctx = (struct chunked_writer *)writer;
struct chunked_writer *ctx = writer->ctx;
Curl_httpchunk_free(data, &ctx->ch);
}
@ -412,7 +412,7 @@ static CURLcode cw_chunked_write(struct Curl_easy *data,
struct Curl_cwriter *writer, int type,
const char *buf, size_t blen)
{
struct chunked_writer *ctx = (struct chunked_writer *)writer;
struct chunked_writer *ctx = writer->ctx;
CURLcode result;
size_t consumed;
@ -474,7 +474,7 @@ struct chunked_reader {
static CURLcode cr_chunked_init(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct chunked_reader *ctx = (struct chunked_reader *)reader;
struct chunked_reader *ctx = reader->ctx;
(void)data;
Curl_bufq_init2(&ctx->chunkbuf, CURL_CHUNKED_MAXLEN, 2, BUFQ_OPT_SOFT_LIMIT);
return CURLE_OK;
@ -483,7 +483,7 @@ static CURLcode cr_chunked_init(struct Curl_easy *data,
static void cr_chunked_close(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct chunked_reader *ctx = (struct chunked_reader *)reader;
struct chunked_reader *ctx = reader->ctx;
(void)data;
Curl_bufq_free(&ctx->chunkbuf);
}
@ -491,7 +491,7 @@ static void cr_chunked_close(struct Curl_easy *data,
static CURLcode add_last_chunk(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct chunked_reader *ctx = (struct chunked_reader *)reader;
struct chunked_reader *ctx = reader->ctx;
struct curl_slist *trailers = NULL, *tr;
CURLcode result;
size_t n;
@ -542,7 +542,7 @@ static CURLcode add_chunk(struct Curl_easy *data,
struct Curl_creader *reader,
char *buf, size_t blen)
{
struct chunked_reader *ctx = (struct chunked_reader *)reader;
struct chunked_reader *ctx = reader->ctx;
CURLcode result;
char tmp[CURL_CHUNKED_MINLEN];
size_t nread;
@ -595,7 +595,7 @@ static CURLcode cr_chunked_read(struct Curl_easy *data,
char *buf, size_t blen,
size_t *pnread, bool *peos)
{
struct chunked_reader *ctx = (struct chunked_reader *)reader;
struct chunked_reader *ctx = reader->ctx;
CURLcode result = CURLE_READ_ERROR;
*pnread = 0;

View file

@ -1928,7 +1928,7 @@ struct cr_mime_ctx {
static CURLcode cr_mime_init(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct cr_mime_ctx *ctx = (struct cr_mime_ctx *)reader;
struct cr_mime_ctx *ctx = reader->ctx;
(void)data;
ctx->total_len = -1;
ctx->read_len = 0;
@ -1941,7 +1941,7 @@ static CURLcode cr_mime_read(struct Curl_easy *data,
char *buf, size_t blen,
size_t *pnread, bool *peos)
{
struct cr_mime_ctx *ctx = (struct cr_mime_ctx *)reader;
struct cr_mime_ctx *ctx = reader->ctx;
size_t nread;
/* Once we have errored, we will return the same error forever */
@ -2022,7 +2022,7 @@ static CURLcode cr_mime_read(struct Curl_easy *data,
static bool cr_mime_needs_rewind(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct cr_mime_ctx *ctx = (struct cr_mime_ctx *)reader;
struct cr_mime_ctx *ctx = reader->ctx;
(void)data;
return ctx->read_len > 0;
}
@ -2030,7 +2030,7 @@ static bool cr_mime_needs_rewind(struct Curl_easy *data,
static curl_off_t cr_mime_total_length(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct cr_mime_ctx *ctx = (struct cr_mime_ctx *)reader;
struct cr_mime_ctx *ctx = reader->ctx;
(void)data;
return ctx->total_len;
}
@ -2039,7 +2039,7 @@ static CURLcode cr_mime_resume_from(struct Curl_easy *data,
struct Curl_creader *reader,
curl_off_t offset)
{
struct cr_mime_ctx *ctx = (struct cr_mime_ctx *)reader;
struct cr_mime_ctx *ctx = reader->ctx;
if(offset > 0) {
curl_off_t passed = 0;
@ -2080,7 +2080,7 @@ static CURLcode cr_mime_resume_from(struct Curl_easy *data,
static CURLcode cr_mime_rewind(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct cr_mime_ctx *ctx = (struct cr_mime_ctx *)reader;
struct cr_mime_ctx *ctx = reader->ctx;
CURLcode result = mime_rewind(ctx->part);
if(result)
failf(data, "Cannot rewind mime/post data");
@ -2090,7 +2090,7 @@ static CURLcode cr_mime_rewind(struct Curl_easy *data,
static CURLcode cr_mime_unpause(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct cr_mime_ctx *ctx = (struct cr_mime_ctx *)reader;
struct cr_mime_ctx *ctx = reader->ctx;
(void)data;
mime_unpause(ctx->part);
return CURLE_OK;
@ -2118,7 +2118,7 @@ CURLcode Curl_creader_set_mime(struct Curl_easy *data, curl_mimepart *part)
result = Curl_creader_create(&r, data, &cr_mime, CURL_CR_CLIENT);
if(result)
return result;
ctx = (struct cr_mime_ctx *)r;
ctx = r->ctx;
ctx->part = part;
/* Make sure we will read the entire mime structure. */
result = mime_rewind(ctx->part);

View file

@ -236,7 +236,7 @@ static CURLcode cw_download_write(struct Curl_easy *data,
struct Curl_cwriter *writer, int type,
const char *buf, size_t nbytes)
{
struct cw_download_ctx *ctx = (struct cw_download_ctx *)writer;
struct cw_download_ctx *ctx = writer->ctx;
CURLcode result;
size_t nwrite, excess_len = 0;
bool is_connect = !!(type & CLIENTWRITE_CONNECT);
@ -368,15 +368,18 @@ CURLcode Curl_cwriter_create(struct Curl_cwriter **pwriter,
const struct Curl_cwtype *cwt,
Curl_cwriter_phase phase)
{
struct Curl_cwriter *writer;
struct Curl_cwriter *writer = NULL;
CURLcode result = CURLE_OUT_OF_MEMORY;
void *p;
DEBUGASSERT(cwt->cwriter_size >= sizeof(struct Curl_cwriter));
writer = (struct Curl_cwriter *) calloc(1, cwt->cwriter_size);
if(!writer)
p = calloc(1, cwt->cwriter_size);
if(!p)
goto out;
writer = (struct Curl_cwriter *)p;
writer->cwt = cwt;
writer->ctx = p;
writer->phase = phase;
result = cwt->do_init(data, writer);
@ -575,7 +578,7 @@ struct cr_in_ctx {
static CURLcode cr_in_init(struct Curl_easy *data, struct Curl_creader *reader)
{
struct cr_in_ctx *ctx = (struct cr_in_ctx *)reader;
struct cr_in_ctx *ctx = reader->ctx;
(void)data;
ctx->read_cb = data->state.fread_func;
ctx->cb_user_data = data->state.in;
@ -590,7 +593,7 @@ static CURLcode cr_in_read(struct Curl_easy *data,
char *buf, size_t blen,
size_t *pnread, bool *peos)
{
struct cr_in_ctx *ctx = (struct cr_in_ctx *)reader;
struct cr_in_ctx *ctx = reader->ctx;
size_t nread;
/* Once we have errored, we will return the same error forever */
@ -681,7 +684,7 @@ static CURLcode cr_in_read(struct Curl_easy *data,
static bool cr_in_needs_rewind(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct cr_in_ctx *ctx = (struct cr_in_ctx *)reader;
struct cr_in_ctx *ctx = reader->ctx;
(void)data;
return ctx->has_used_cb;
}
@ -689,7 +692,7 @@ static bool cr_in_needs_rewind(struct Curl_easy *data,
static curl_off_t cr_in_total_length(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct cr_in_ctx *ctx = (struct cr_in_ctx *)reader;
struct cr_in_ctx *ctx = reader->ctx;
(void)data;
return ctx->total_len;
}
@ -698,7 +701,7 @@ static CURLcode cr_in_resume_from(struct Curl_easy *data,
struct Curl_creader *reader,
curl_off_t offset)
{
struct cr_in_ctx *ctx = (struct cr_in_ctx *)reader;
struct cr_in_ctx *ctx = reader->ctx;
int seekerr = CURL_SEEKFUNC_CANTSEEK;
DEBUGASSERT(data->conn);
@ -760,7 +763,7 @@ static CURLcode cr_in_resume_from(struct Curl_easy *data,
static CURLcode cr_in_rewind(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct cr_in_ctx *ctx = (struct cr_in_ctx *)reader;
struct cr_in_ctx *ctx = reader->ctx;
/* If we never invoked the callback, there is noting to rewind */
if(!ctx->has_used_cb)
@ -830,15 +833,18 @@ CURLcode Curl_creader_create(struct Curl_creader **preader,
const struct Curl_crtype *crt,
Curl_creader_phase phase)
{
struct Curl_creader *reader;
struct Curl_creader *reader = NULL;
CURLcode result = CURLE_OUT_OF_MEMORY;
void *p;
DEBUGASSERT(crt->creader_size >= sizeof(struct Curl_creader));
reader = (struct Curl_creader *) calloc(1, crt->creader_size);
if(!reader)
p = calloc(1, crt->creader_size);
if(!p)
goto out;
reader = (struct Curl_creader *)p;
reader->crt = crt;
reader->ctx = p;
reader->phase = phase;
result = crt->do_init(data, reader);
@ -866,7 +872,7 @@ struct cr_lc_ctx {
static CURLcode cr_lc_init(struct Curl_easy *data, struct Curl_creader *reader)
{
struct cr_lc_ctx *ctx = (struct cr_lc_ctx *)reader;
struct cr_lc_ctx *ctx = reader->ctx;
(void)data;
Curl_bufq_init2(&ctx->buf, (16 * 1024), 1, BUFQ_OPT_SOFT_LIMIT);
return CURLE_OK;
@ -874,7 +880,7 @@ static CURLcode cr_lc_init(struct Curl_easy *data, struct Curl_creader *reader)
static void cr_lc_close(struct Curl_easy *data, struct Curl_creader *reader)
{
struct cr_lc_ctx *ctx = (struct cr_lc_ctx *)reader;
struct cr_lc_ctx *ctx = reader->ctx;
(void)data;
Curl_bufq_free(&ctx->buf);
}
@ -885,7 +891,7 @@ static CURLcode cr_lc_read(struct Curl_easy *data,
char *buf, size_t blen,
size_t *pnread, bool *peos)
{
struct cr_lc_ctx *ctx = (struct cr_lc_ctx *)reader;
struct cr_lc_ctx *ctx = reader->ctx;
CURLcode result;
size_t nread, i, start, n;
bool eos;
@ -1024,7 +1030,7 @@ CURLcode Curl_creader_set_fread(struct Curl_easy *data, curl_off_t len)
result = Curl_creader_create(&r, data, &cr_in, CURL_CR_CLIENT);
if(result)
return result;
ctx = (struct cr_in_ctx *)r;
ctx = r->ctx;
ctx->total_len = len;
cl_reset_reader(data);
@ -1161,7 +1167,7 @@ static CURLcode cr_buf_read(struct Curl_easy *data,
char *buf, size_t blen,
size_t *pnread, bool *peos)
{
struct cr_buf_ctx *ctx = (struct cr_buf_ctx *)reader;
struct cr_buf_ctx *ctx = reader->ctx;
size_t nread = ctx->blen - ctx->index;
(void)data;
@ -1183,7 +1189,7 @@ static CURLcode cr_buf_read(struct Curl_easy *data,
static bool cr_buf_needs_rewind(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct cr_buf_ctx *ctx = (struct cr_buf_ctx *)reader;
struct cr_buf_ctx *ctx = reader->ctx;
(void)data;
return ctx->index > 0;
}
@ -1191,7 +1197,7 @@ static bool cr_buf_needs_rewind(struct Curl_easy *data,
static curl_off_t cr_buf_total_length(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct cr_buf_ctx *ctx = (struct cr_buf_ctx *)reader;
struct cr_buf_ctx *ctx = reader->ctx;
(void)data;
return (curl_off_t)ctx->blen;
}
@ -1200,7 +1206,7 @@ static CURLcode cr_buf_resume_from(struct Curl_easy *data,
struct Curl_creader *reader,
curl_off_t offset)
{
struct cr_buf_ctx *ctx = (struct cr_buf_ctx *)reader;
struct cr_buf_ctx *ctx = reader->ctx;
size_t boffset;
(void)data;
@ -1242,7 +1248,7 @@ CURLcode Curl_creader_set_buf(struct Curl_easy *data,
result = Curl_creader_create(&r, data, &cr_buf, CURL_CR_CLIENT);
if(result)
return result;
ctx = (struct cr_buf_ctx *)r;
ctx = r->ctx;
ctx->buf = buf;
ctx->blen = blen;
ctx->index = 0;

View file

@ -117,10 +117,16 @@ struct Curl_cwtype {
size_t cwriter_size; /* sizeof() allocated struct Curl_cwriter */
};
/* Client writer instance */
/* Client writer instance, allocated on creation.
* `void *ctx` is the pointer from the allocation of
* the `struct Curl_cwriter` itself. This is suitable for "downcasting"
* by the writers implementation. See https://github.com/curl/curl/pull/13054
* for the alignment problems that arise otherwise.
*/
struct Curl_cwriter {
const struct Curl_cwtype *cwt; /* type implementation */
struct Curl_cwriter *next; /* Downstream writer. */
void *ctx; /* allocated instance pointer */
Curl_cwriter_phase phase; /* phase at which it operates */
};
@ -214,10 +220,16 @@ typedef enum {
CURL_CR_CLIENT /* data read from client */
} Curl_creader_phase;
/* Client reader instance */
/* Client reader instance, allocated on creation.
* `void *ctx` is the pointer from the allocation of
* the `struct Curl_cwriter` itself. This is suitable for "downcasting"
* by the writers implementation. See https://github.com/curl/curl/pull/13054
* for the alignment problems that arise otherwise.
*/
struct Curl_creader {
const struct Curl_crtype *crt; /* type implementation */
struct Curl_creader *next; /* Downstream reader. */
void *ctx;
Curl_creader_phase phase; /* phase at which it operates */
};

View file

@ -1786,7 +1786,7 @@ struct cr_eob_ctx {
static CURLcode cr_eob_init(struct Curl_easy *data,
struct Curl_creader *reader)
{
struct cr_eob_ctx *ctx = (struct cr_eob_ctx *)reader;
struct cr_eob_ctx *ctx = reader->ctx;
(void)data;
/* The first char we read is the first on a line, as if we had
* read CRLF just before */
@ -1797,7 +1797,7 @@ static CURLcode cr_eob_init(struct Curl_easy *data,
static void cr_eob_close(struct Curl_easy *data, struct Curl_creader *reader)
{
struct cr_eob_ctx *ctx = (struct cr_eob_ctx *)reader;
struct cr_eob_ctx *ctx = reader->ctx;
(void)data;
Curl_bufq_free(&ctx->buf);
}
@ -1812,7 +1812,7 @@ static CURLcode cr_eob_read(struct Curl_easy *data,
char *buf, size_t blen,
size_t *pnread, bool *peos)
{
struct cr_eob_ctx *ctx = (struct cr_eob_ctx *)reader;
struct cr_eob_ctx *ctx = reader->ctx;
CURLcode result = CURLE_OK;
size_t nread, i, start, n;
bool eos;

View file

@ -363,7 +363,7 @@ struct ws_cw_ctx {
static CURLcode ws_cw_init(struct Curl_easy *data,
struct Curl_cwriter *writer)
{
struct ws_cw_ctx *ctx = (struct ws_cw_ctx *)writer;
struct ws_cw_ctx *ctx = writer->ctx;
(void)data;
Curl_bufq_init2(&ctx->buf, WS_CHUNK_SIZE, 1, BUFQ_OPT_SOFT_LIMIT);
return CURLE_OK;
@ -371,7 +371,7 @@ static CURLcode ws_cw_init(struct Curl_easy *data,
static void ws_cw_close(struct Curl_easy *data, struct Curl_cwriter *writer)
{
struct ws_cw_ctx *ctx = (struct ws_cw_ctx *)writer;
struct ws_cw_ctx *ctx = writer->ctx;
(void) data;
Curl_bufq_free(&ctx->buf);
}
@ -423,7 +423,7 @@ static CURLcode ws_cw_write(struct Curl_easy *data,
struct Curl_cwriter *writer, int type,
const char *buf, size_t nbytes)
{
struct ws_cw_ctx *ctx = (struct ws_cw_ctx *)writer;
struct ws_cw_ctx *ctx = writer->ctx;
struct websocket *ws;
CURLcode result;