From 1f9494979268b62ed4b4588fb7d9e790c0e12100 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Mon, 26 Oct 2026 22:32:52 +0100 Subject: replace all calls to sprintf with a format helper that advances a cursor. Also convert the meta-formatter (i.e. results printer) to this scheme --- ot_http.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'ot_http.c') diff --git a/ot_http.c b/ot_http.c index e1798dc..36819c7 100644 --- a/ot_http.c +++ b/ot_http.c @@ -24,6 +24,7 @@ #include "ot_scan.h" #include "ot_event.h" #include "ot_fdstate.h" +#include "ot_fmt.h" #include "ot_stats.h" #include "ot_urlencoded.h" #include "trackerlogic.h" @@ -257,6 +258,7 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c {"txtp", TASK_FULLSCRAPE_TPB_ASCII_PLUS}, {NULL, -3}}; struct http_data *cookie = fdstate_cookie(sock); + char *reply; int mode = TASK_STATS_PEERS, scanon = 1, format = 0; /* A socket without one is a dead socket, which is what http_sendiovecdata @@ -333,7 +335,9 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c } /* Simple stats can be answerred immediately */ - return ws->reply_size = return_stats_for_tracker(ws->reply, mode, 0); + reply = ws->reply; + return_stats_for_tracker(&reply, ws->outbuf + G_OUTBUF_SIZE, mode, 0); + return ws->reply_size = reply - ws->reply; } #ifdef WANT_MODEST_FULLSCRAPES @@ -417,9 +421,10 @@ static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct * static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) { static const ot_keywords keywords_scrape[] = {{"info_hash", 1}, {NULL, -3}}; - ot_hash *multiscrape_buf = (ot_hash *)ws->request; - int scanon = 1; - size_t numwant = 0; + ot_hash *multiscrape_buf = (ot_hash *)ws->request; + char *reply = ws->reply; + int scanon = 1; + size_t numwant = 0; /* This is to hack around stupid clients that send "scrape ?info_hash" */ if (read_ptr[-1] != '?') { @@ -457,7 +462,8 @@ static ssize_t http_handle_scrape(const int64_t sock, struct ot_workstruct *ws, numwant = OT_MAXMULTISCRAPE_COUNT; /* Enough for http header + whole scrape string */ - ws->reply_size = return_tcp_scrape_for_torrent((const ot_hash *)multiscrape_buf, numwant, ws->reply); + return_tcp_scrape_for_torrent((const ot_hash *)multiscrape_buf, numwant, &reply, ws->outbuf + G_OUTBUF_SIZE); + ws->reply_size = reply - ws->reply; stats_issue_event(EVENT_SCRAPE, FLAG_TCP, ws->reply_size); return ws->reply_size; } @@ -493,6 +499,16 @@ static ot_keywords keywords_announce[] = {{"port", 1}, {"left", 2}, {"event", #endif {"peer_id", 9}, {NULL, -3}}; static ot_keywords keywords_announce_event[] = {{"completed", 1}, {"stopped", 2}, {NULL, -3}}; + +/* For the replies that are one fixed string and nothing else, where the only + thing the caller wants back is how long it turned out */ +static ssize_t reply_literal(struct ot_workstruct *ws, const char *text) { + char *reply = ws->reply; + + fmt_bytes(&reply, ws->outbuf + G_OUTBUF_SIZE, text, strlen(text)); + return reply - ws->reply; +} + static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct *ws, char *read_ptr) { size_t numwant; int64_t tmp; @@ -621,7 +637,7 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct HTTPERROR_400_PARAM; if (*tmp_buf == '-') { loglist_reset(); - return ws->reply_size = sprintf(ws->reply, "Successfully removed.\n"); + return ws->reply_size = reply_literal(ws, "Successfully removed.\n"); } parsed = ip_parse(tmp_buf, net.address); if (!parsed) @@ -638,7 +654,7 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct } net.bits = bits; loglist_add_network(&net); - return ws->reply_size = sprintf(ws->reply, "Successfully added.\n"); + return ws->reply_size = reply_literal(ws, "Successfully added.\n"); //} } break; #endif @@ -661,7 +677,7 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct /* Scanned whole query string */ if (!ws->hash) - return ws->reply_size = sprintf(ws->reply, "d14:failure reason80:Your client forgot to send your torrent's info_hash. Please upgrade your client.e"); + return ws->reply_size = reply_literal(ws, "d14:failure reason80:Your client forgot to send your torrent's info_hash. Please upgrade your client.e"); if (OT_PEERFLAG(&ws->peer) & PEER_FLAG_STOPPED) ws->reply_size = remove_peer_from_torrent(FLAG_TCP, ws); @@ -772,9 +788,11 @@ ssize_t http_handle_request(const int64_t sock, struct ot_workstruct *ws) { reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf(ws->outbuf, 0, "%zd", ws->reply_size); ws->reply = ws->outbuf + reply_off; - /* 2. Now we sprintf our header so that sprintf writes its terminating '\0' exactly one byte before content starts. Complete - packet size is increased by size of header plus one byte '\n', we will copy over '\0' in next step */ - ws->reply_size += 1 + sprintf(ws->reply, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", ws->reply_size); + /* 2. Now we write the header so that its terminating '\0' lands exactly one byte before the content starts. The bound is the + space step 1 reserved, so the '\0' falls where step 3 expects it. Complete packet size is increased by size of header plus + one byte '\n', we will copy over '\0' in next step */ + ws->reply_size += 1 + snprintf(ws->reply, (size_t)(SUCCESS_HTTP_HEADER_LENGTH - reply_off), + "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", ws->reply_size); /* 3. Finally we join both blocks neatly */ ws->outbuf[SUCCESS_HTTP_HEADER_LENGTH - 1] = '\n'; -- cgit v1.3