From: Stefan Eissing Date: Wed, 6 Mar 2024 08:52:43 +0000 (+0100) Subject: lib: add `void *ctx` to reader/writer instances X-Git-Tag: curl-8_7_0~74 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9978d40ddbd00abf219ec332f72b5b9e697e5941;p=thirdparty%2Fcurl.git 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 --- diff --git a/lib/cw-out.c b/lib/cw-out.c index b29b45665a..25a27a68cd 100644 --- a/lib/cw-out.c +++ b/lib/cw-out.c @@ -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; diff --git a/lib/ftp.c b/lib/ftp.c index 8881bd364a..2511bd4b61 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -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') diff --git a/lib/http_chunks.c b/lib/http_chunks.c index f9cb0741ea..cfbd40bc28 100644 --- a/lib/http_chunks.c +++ b/lib/http_chunks.c @@ -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; diff --git a/lib/mime.c b/lib/mime.c index cccf46f897..48a1ad87c7 100644 --- a/lib/mime.c +++ b/lib/mime.c @@ -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); diff --git a/lib/sendf.c b/lib/sendf.c index 81f2deabdc..ce9b2b0757 100644 --- a/lib/sendf.c +++ b/lib/sendf.c @@ -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; diff --git a/lib/sendf.h b/lib/sendf.h index 2c5bc36208..a62cfe8c68 100644 --- a/lib/sendf.h +++ b/lib/sendf.h @@ -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 */ }; diff --git a/lib/smtp.c b/lib/smtp.c index 2d85360083..b32ef36e4b 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -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; diff --git a/lib/ws.c b/lib/ws.c index 37108946d4..263299761f 100644 --- a/lib/ws.c +++ b/lib/ws.c @@ -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;