You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bc...@apache.org on 2022/11/28 19:10:45 UTC

[trafficserver] branch master updated: Removed most sprintf and ignore sprintf warnings in bind code (#9189)

This is an automated email from the ASF dual-hosted git repository.

bcall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new b72943227 Removed most sprintf and ignore sprintf warnings in bind code (#9189)
b72943227 is described below

commit b7294322739f1705aae5a62b1bc96768605dc492
Author: Bryan Call <bc...@apache.org>
AuthorDate: Mon Nov 28 11:10:37 2022 -0800

    Removed most sprintf and ignore sprintf warnings in bind code (#9189)
---
 iocore/cache/CachePagesInternal.cc                 |   2 +-
 mgmt/WebMgmtUtils.cc                               |  62 ++---
 mgmt/WebMgmtUtils.h                                |   8 +-
 mgmt/utils/MgmtUtils.cc                            |  10 +-
 plugins/certifier/certifier.cc                     |   2 +-
 plugins/compress/misc.cc                           |   7 +-
 plugins/experimental/access_control/plugin.cc      |   5 +-
 plugins/experimental/access_control/utils.cc       |   4 +-
 plugins/experimental/icap/icap_plugin.cc           |  12 +-
 .../ja3_fingerprint/ja3_fingerprint.cc             |   4 +-
 plugins/experimental/mp4/mp4.cc                    |   2 +-
 .../experimental/traffic_dump/transaction_data.cc  |  14 +-
 plugins/prefetch/plugin.cc                         |   5 +-
 proxy/http/HttpBodyFactory.cc                      |   4 +-
 proxy/http/HttpSM.cc                               |   2 +-
 .../http/remap/unit-tests/plugin_testing_common.cc |   2 +-
 proxy/logging/Log.cc                               |   2 +-
 src/traffic_top/stats.h                            |   2 +-
 src/tscore/ink_res_mkquery.cc                      |   3 +
 tools/jtest/jtest.cc                               | 301 +++++++++++----------
 20 files changed, 227 insertions(+), 226 deletions(-)

diff --git a/iocore/cache/CachePagesInternal.cc b/iocore/cache/CachePagesInternal.cc
index 531797cd9..f4c8cb19f 100644
--- a/iocore/cache/CachePagesInternal.cc
+++ b/iocore/cache/CachePagesInternal.cc
@@ -205,7 +205,7 @@ ShowCacheInternal::showVolEvacuations(int event, Event *e)
   for (int i = 0; i < last; i++) {
     for (b = p->evacuate[i].head; b; b = b->link.next) {
       char offset[60];
-      sprintf(offset, "%" PRIu64 "", static_cast<uint64_t>(p->vol_offset(&b->dir)));
+      snprintf(offset, sizeof(offset), "%" PRIu64 "", static_cast<uint64_t>(p->vol_offset(&b->dir)));
       CHECK_SHOW(show("<tr>"
                       "<td>%s</td>" // offset
                       "<td>%d</td>" // estimated size
diff --git a/mgmt/WebMgmtUtils.cc b/mgmt/WebMgmtUtils.cc
index da3458c65..481544600 100644
--- a/mgmt/WebMgmtUtils.cc
+++ b/mgmt/WebMgmtUtils.cc
@@ -443,41 +443,31 @@ varIntFromName(const char *varName, RecInt *value)
 // void percentStrFromFloat(MgmtFloat, char* bufVal)
 //
 //  Converts a float to a percent string
-//
-//     bufVal must point to adequate space a la sprintf
-//
 void
-percentStrFromFloat(RecFloat val, char *bufVal)
+percentStrFromFloat(RecFloat val, char *bufVal, int bufLen)
 {
-  int percent;
-
-  percent = static_cast<int>((val * 100.0) + 0.5);
-  snprintf(bufVal, 4, "%d%%", percent);
+  int percent = static_cast<int>((val * 100.0) + 0.5);
+  snprintf(bufVal, bufLen, "%d%%", percent);
 }
 
 // void commaStrFromInt(RecInt bytes, char* bufVal)
 //   Converts an Int to string with commas in it
-//
-//     bufVal must point to adequate space a la sprintf
-//
 void
-commaStrFromInt(RecInt bytes, char *bufVal)
+commaStrFromInt(RecInt bytes, char *bufVal, int bufLen)
 {
-  int len;
-  int numCommas;
   char *curPtr;
 
-  sprintf(bufVal, "%" PRId64 "", bytes);
-  len = strlen(bufVal);
+  int len = snprintf(bufVal, bufLen, "%" PRId64 "", bytes);
 
   // The string is too short to need commas
   if (len < 4) {
     return;
   }
 
-  numCommas = (len - 1) / 3;
-  curPtr    = bufVal + (len + numCommas);
-  *curPtr   = '\0';
+  int numCommas = (len - 1) / 3;
+  ink_release_assert(bufLen > numCommas + len);
+  curPtr  = bufVal + (len + numCommas);
+  *curPtr = '\0';
   curPtr--;
 
   for (int i = 0; i < len; i++) {
@@ -494,17 +484,13 @@ commaStrFromInt(RecInt bytes, char *bufVal)
 }
 
 // void MbytesFromInt(RecInt bytes, char* bufVal)
-//     Converts into a string in units of megabytes
-//      No unit specification is added
-//
-//     bufVal must point to adequate space a la sprintf
-//
+//     Converts into a string in units of megabytes No unit specification is added
 void
-MbytesFromInt(RecInt bytes, char *bufVal)
+MbytesFromInt(RecInt bytes, char *bufVal, int bufLen)
 {
   RecInt mBytes = bytes / 1048576;
 
-  sprintf(bufVal, "%" PRId64 "", mBytes);
+  snprintf(bufVal, bufLen, "%" PRId64 "", mBytes);
 }
 
 // void bytesFromInt(RecInt bytes, char* bufVal)
@@ -514,7 +500,7 @@ MbytesFromInt(RecInt bytes, char *bufVal)
 //
 //     bufVal must point to adequate space a la sprintf
 void
-bytesFromInt(RecInt bytes, char *bufVal)
+bytesFromInt(RecInt bytes, char *bufVal, int bufLen)
 {
   const int64_t gb  = 1073741824;
   const long int mb = 1048576;
@@ -523,7 +509,7 @@ bytesFromInt(RecInt bytes, char *bufVal)
 
   if (bytes >= gb) {
     unitBytes = bytes / static_cast<double>(gb);
-    snprintf(bufVal, 15, "%.1f GB", unitBytes);
+    snprintf(bufVal, bufLen, "%.1f GB", unitBytes);
   } else {
     // Reduce the precision of the bytes parameter
     //   because we know that it less than 1GB which
@@ -533,12 +519,12 @@ bytesFromInt(RecInt bytes, char *bufVal)
     int bytesP = static_cast<int>(bytes);
     if (bytesP >= mb) {
       unitBytes = bytes / static_cast<double>(mb);
-      snprintf(bufVal, 15, "%.1f MB", unitBytes);
+      snprintf(bufVal, bufLen, "%.1f MB", unitBytes);
     } else if (bytesP >= kb) {
       unitBytes = bytes / static_cast<double>(kb);
-      snprintf(bufVal, 15, "%.1f KB", unitBytes);
+      snprintf(bufVal, bufLen, "%.1f KB", unitBytes);
     } else {
-      snprintf(bufVal, 15, "%d", bytesP);
+      snprintf(bufVal, bufLen, "%d", bytesP);
     }
   }
 }
@@ -603,11 +589,11 @@ varStrFromName(const char *varNameConst, char *bufVal, int bufLen)
   case RECD_INT:
     RecGetRecordInt(varName, &data.rec_int);
     if (formatOption == 'b') {
-      bytesFromInt(data.rec_int, bufVal);
+      bytesFromInt(data.rec_int, bufVal, bufLen);
     } else if (formatOption == 'm') {
-      MbytesFromInt(data.rec_int, bufVal);
+      MbytesFromInt(data.rec_int, bufVal, bufLen);
     } else if (formatOption == 'c') {
-      commaStrFromInt(data.rec_int, bufVal);
+      commaStrFromInt(data.rec_int, bufVal, bufLen);
     } else {
       snprintf(bufVal, bufLen, "%" PRId64 "", data.rec_int);
     }
@@ -616,11 +602,11 @@ varStrFromName(const char *varNameConst, char *bufVal, int bufLen)
   case RECD_COUNTER:
     RecGetRecordCounter(varName, &data.rec_counter);
     if (formatOption == 'b') {
-      bytesFromInt(static_cast<MgmtInt>(data.rec_counter), bufVal);
+      bytesFromInt(static_cast<MgmtInt>(data.rec_counter), bufVal, bufLen);
     } else if (formatOption == 'm') {
-      MbytesFromInt(static_cast<MgmtInt>(data.rec_counter), bufVal);
+      MbytesFromInt(static_cast<MgmtInt>(data.rec_counter), bufVal, bufLen);
     } else if (formatOption == 'c') {
-      commaStrFromInt(data.rec_counter, bufVal);
+      commaStrFromInt(data.rec_counter, bufVal, bufLen);
     } else {
       snprintf(bufVal, bufLen, "%" PRId64 "", data.rec_counter);
     }
@@ -628,7 +614,7 @@ varStrFromName(const char *varNameConst, char *bufVal, int bufLen)
   case RECD_FLOAT:
     RecGetRecordFloat(varName, &data.rec_float);
     if (formatOption == 'p') {
-      percentStrFromFloat(data.rec_float, bufVal);
+      percentStrFromFloat(data.rec_float, bufVal, bufLen);
     } else {
       snprintf(bufVal, bufLen, "%.2f", data.rec_float);
     }
diff --git a/mgmt/WebMgmtUtils.h b/mgmt/WebMgmtUtils.h
index 26cb01d91..6522cf143 100644
--- a/mgmt/WebMgmtUtils.h
+++ b/mgmt/WebMgmtUtils.h
@@ -41,16 +41,16 @@ public:
 };
 
 // Convert to byte units (GB, MB, KB)
-void bytesFromInt(RecInt bytes, char *bufVal);
+void bytesFromInt(RecInt bytes, char *bufVal, int bufLen);
 
 // Convert to MB
-void MbytesFromInt(RecInt bytes, char *bufVal);
+void MbytesFromInt(RecInt bytes, char *bufVal, int bufLen);
 
 // Create comma string from int
-void commaStrFromInt(RecInt bytes, char *bufVal);
+void commaStrFromInt(RecInt bytes, char *bufVal, int bufLen);
 
 // Create percent string from float
-void percentStrFromFloat(RecFloat val, char *bufVal);
+void percentStrFromFloat(RecFloat val, char *bufVal, int bufLen);
 
 // All types converted to/from strings where appropriate
 bool varStrFromName(const char *varName, char *bufVal, int bufLen);
diff --git a/mgmt/utils/MgmtUtils.cc b/mgmt/utils/MgmtUtils.cc
index c7eb7b572..5cae4bc0f 100644
--- a/mgmt/utils/MgmtUtils.cc
+++ b/mgmt/utils/MgmtUtils.cc
@@ -233,11 +233,11 @@ mgmt_log(const char *message_format, ...)
   } else {
     if (use_syslog) {
       snprintf(extended_format, sizeof(extended_format), "log ==> %s", message_format);
-      vsprintf(message, extended_format, ap);
+      vsnprintf(message, sizeof(message), extended_format, ap);
       syslog(LOG_WARNING, "%s", message);
     } else {
       snprintf(extended_format, sizeof(extended_format), "[E. Mgmt] log ==> %s", message_format);
-      vsprintf(message, extended_format, ap);
+      vsnprintf(message, sizeof(message), extended_format, ap);
       ink_assert(fwrite(message, strlen(message), 1, stderr) == 1);
     }
   }
@@ -262,14 +262,14 @@ mgmt_elog(const int lerrno, const char *message_format, ...)
   } else {
     if (use_syslog) {
       snprintf(extended_format, sizeof(extended_format), "ERROR ==> %s", message_format);
-      vsprintf(message, extended_format, ap);
+      vsnprintf(message, sizeof(message), extended_format, ap);
       syslog(LOG_ERR, "%s", message);
       if (lerrno != 0) {
         syslog(LOG_ERR, " (last system error %d: %s)", lerrno, strerror(lerrno));
       }
     } else {
       snprintf(extended_format, sizeof(extended_format), "Manager ERROR: %s", message_format);
-      vsprintf(message, extended_format, ap);
+      vsnprintf(message, sizeof(message), extended_format, ap);
       ink_assert(fwrite(message, strlen(message), 1, stderr) == 1);
       if (lerrno != 0) {
         snprintf(message, sizeof(message), "(last system error %d: %s)", lerrno, strerror(lerrno));
@@ -297,7 +297,7 @@ mgmt_fatal(const int lerrno, const char *message_format, ...)
   } else {
     char extended_format[4096], message[4096];
     snprintf(extended_format, sizeof(extended_format), "FATAL ==> %s", message_format);
-    vsprintf(message, extended_format, ap);
+    vsnprintf(message, sizeof(message), extended_format, ap);
 
     ink_assert(fwrite(message, strlen(message), 1, stderr) == 1);
 
diff --git a/plugins/certifier/certifier.cc b/plugins/certifier/certifier.cc
index 8f8817a42..0916d10f3 100644
--- a/plugins/certifier/certifier.cc
+++ b/plugins/certifier/certifier.cc
@@ -423,7 +423,7 @@ shadow_cert_generator(TSCont contp, TSEvent event, void *edata)
   unsigned char digest[MD5_DIGEST_LENGTH];
   MD5(reinterpret_cast<unsigned char const *>(commonName.data()), commonName.length(), digest);
   char md5String[5];
-  sprintf(md5String, "%02hhx%02hhx", digest[0], digest[1]);
+  snprintf(md5String, sizeof(md5String), "%02hhx%02hhx", digest[0], digest[1]);
   std::string path          = store_path + "/" + std::string(md5String, 3);
   std::string cert_filename = path + '/' + commonName + ".crt";
 
diff --git a/plugins/compress/misc.cc b/plugins/compress/misc.cc
index 56c3fa9a2..bdad5bb33 100644
--- a/plugins/compress/misc.cc
+++ b/plugins/compress/misc.cc
@@ -168,10 +168,9 @@ init_hidden_header_name()
   if (TSMgmtStringGet(var_name, &result) != TS_SUCCESS) {
     fatal("failed to get server name");
   } else {
-    int hidden_header_name_len                 = strlen("x-accept-encoding-") + strlen(result);
-    hidden_header_name                         = static_cast<char *>(TSmalloc(hidden_header_name_len + 1));
-    hidden_header_name[hidden_header_name_len] = 0;
-    sprintf(hidden_header_name, "x-accept-encoding-%s", result);
+    size_t hidden_header_name_size = strlen("x-accept-encoding-") + strlen(result) + 1; // add one for null
+    hidden_header_name             = static_cast<char *>(TSmalloc(hidden_header_name_size));
+    snprintf(hidden_header_name, hidden_header_name_size, "x-accept-encoding-%s", result);
     TSfree(result);
   }
   return hidden_header_name;
diff --git a/plugins/experimental/access_control/plugin.cc b/plugins/experimental/access_control/plugin.cc
index 38d062102..3b2ad4e27 100644
--- a/plugins/experimental/access_control/plugin.cc
+++ b/plugins/experimental/access_control/plugin.cc
@@ -399,8 +399,9 @@ contHandleAccessControl(const TSCont contp, TSEvent event, void *edata)
               /* Don't set any cookie, fail the request here returning appropriate status code and body.*/
               TSHttpTxnStatusSet(txnp, config->_invalidOriginResponse);
               static const char *body = "Unexpected Response From the Origin Server\n";
-              char *buf               = static_cast<char *>(TSmalloc(strlen(body) + 1));
-              sprintf(buf, "%s", body);
+              size_t bufsize          = strlen(body) + 1;
+              char *buf               = static_cast<char *>(TSmalloc(bufsize));
+              snprintf(buf, bufsize, "%s", body);
               TSHttpTxnErrorBodySet(txnp, buf, strlen(buf), nullptr);
 
               resultEvent = TS_EVENT_HTTP_ERROR;
diff --git a/plugins/experimental/access_control/utils.cc b/plugins/experimental/access_control/utils.cc
index 211716da5..5c7af1e26 100644
--- a/plugins/experimental/access_control/utils.cc
+++ b/plugins/experimental/access_control/utils.cc
@@ -51,7 +51,7 @@ hexEncode(const char *in, size_t inLen, char *out, size_t outLen)
   char *dst          = out;
   char *dstEnd       = out + outLen;
 
-  while (src < srcEnd && dst < dstEnd && 2 == sprintf(dst, "%02x", static_cast<unsigned char>(*src))) {
+  while (src < srcEnd && dst < dstEnd && 2 == snprintf(dst, outLen, "%02x", static_cast<unsigned char>(*src))) {
     dst += 2;
     src++;
   }
@@ -124,7 +124,7 @@ urlEncode(const char *in, size_t inLen, char *out, size_t outLen)
       *dst++ = '+';
     } else {
       *dst++ = '%';
-      sprintf(dst, "%02x", static_cast<unsigned char>(*src));
+      snprintf(dst, out + outLen - dst, "%02x", static_cast<unsigned char>(*src));
       dst += 2;
     }
     src++;
diff --git a/plugins/experimental/icap/icap_plugin.cc b/plugins/experimental/icap/icap_plugin.cc
index a44812509..092f257ab 100644
--- a/plugins/experimental/icap/icap_plugin.cc
+++ b/plugins/experimental/icap/icap_plugin.cc
@@ -554,12 +554,12 @@ handle_write_header(TSCont contp, TransformData *data)
   /* formulate the ICAP request header */
   char res_buf[1000];
   memset(res_buf, 0, 1000);
-  sprintf(res_buf,
-          "RESPMOD %s ICAP/%s\r\n"
-          "Host: %s\r\n"
-          "Connection: close\r\n" // "Connection: close" is used since each scan creates a new connection
-          "Encapsulated: req-hdr=0, res-hdr=%" PRIu64 ", res-body=%" PRIu64 "\r\n\r\n",
-          ICAP_SERVICE_URL, ICAP_VERSION, server_ip.c_str(), client_req_size, server_resp_size + client_req_size);
+  snprintf(res_buf, sizeof(res_buf),
+           "RESPMOD %s ICAP/%s\r\n"
+           "Host: %s\r\n"
+           "Connection: close\r\n" // "Connection: close" is used since each scan creates a new connection
+           "Encapsulated: req-hdr=0, res-hdr=%" PRIu64 ", res-body=%" PRIu64 "\r\n\r\n",
+           ICAP_SERVICE_URL, ICAP_VERSION, server_ip.c_str(), client_req_size, server_resp_size + client_req_size);
 
   TSIOBufferWrite(data->input_buf, (const char *)res_buf, strlen(res_buf));
   TSHttpHdrPrint(bufp_c, req_loc, data->input_buf);
diff --git a/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc b/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc
index fe3a33e87..3229e6b08 100644
--- a/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc
+++ b/plugins/experimental/ja3_fingerprint/ja3_fingerprint.cc
@@ -318,8 +318,10 @@ client_hello_ja3_handler(TSCont contp, TSEvent event, void *edata)
     unsigned char digest[MD5_DIGEST_LENGTH];
     MD5((unsigned char *)data->ja3_string.c_str(), data->ja3_string.length(), digest);
 
+    // Validate that the buffer is the same size as we will be writing into (compile time)
+    static_assert((16 * 2 + 1) == sizeof(data->md5_string));
     for (int i = 0; i < 16; i++) {
-      sprintf(&(data->md5_string[i * 2]), "%02x", static_cast<unsigned int>(digest[i]));
+      snprintf(&(data->md5_string[i * 2]), sizeof(data->md5_string) - (i * 2), "%02x", static_cast<unsigned int>(digest[i]));
     }
     TSDebug(PLUGIN_NAME, "Fingerprint: %s", data->md5_string);
     break;
diff --git a/plugins/experimental/mp4/mp4.cc b/plugins/experimental/mp4/mp4.cc
index 06988ad75..0791d5d7c 100644
--- a/plugins/experimental/mp4/mp4.cc
+++ b/plugins/experimental/mp4/mp4.cc
@@ -122,7 +122,7 @@ TSRemapDoRemap(void * /* ih ATS_UNUSED */, TSHttpTxn rh, TSRemapRequestInfo *rri
     right--;
   }
 
-  buf_len = sprintf(buf, "%.*s%.*s", left, query, right, query + query_len - right);
+  buf_len = snprintf(buf, sizeof(buf), "%.*s%.*s", left, query, right, query + query_len - right);
   TSUrlHttpQuerySet(rri->requestBufp, rri->requestUrl, buf, buf_len);
 
   // remove Accept-Encoding
diff --git a/plugins/experimental/traffic_dump/transaction_data.cc b/plugins/experimental/traffic_dump/transaction_data.cc
index 4c6f3482d..5c4cbf5e4 100644
--- a/plugins/experimental/traffic_dump/transaction_data.cc
+++ b/plugins/experimental/traffic_dump/transaction_data.cc
@@ -22,6 +22,7 @@
  */
 
 #include <sstream>
+#include <iomanip>
 
 #include "transaction_data.h"
 #include "global_variables.h"
@@ -106,16 +107,13 @@ TransactionData::response_buffer_handler(TSCont contp, TSEvent event, void *edat
 void
 TransactionData::initialize_default_sensitive_field()
 {
-  // 128 KB is the maximum size supported for all headers, so this size should
-  // be plenty large for our needs.
+  std::ostringstream ss;
+  // 128 KB is the maximum size supported for all headers, so this size should be plenty large for our needs.
   constexpr size_t default_field_size = 128 * 1024;
-  default_sensitive_field_value.resize(default_field_size);
-
-  char *field_buffer = default_sensitive_field_value.data();
-  for (auto i = 0u; i < default_field_size; i += 8) {
-    sprintf(field_buffer, "%07x ", i / 8);
-    field_buffer += 8;
+  for (uint32_t i = 0; i < default_field_size; i += 8) {
+    ss << std::hex << std::setw(7) << std::setfill('0') << i / 8 << " ";
   }
+  default_sensitive_field_value = ss.str();
 }
 
 /// The set of fields, default and user-specified, that are sensitive and whose
diff --git a/plugins/prefetch/plugin.cc b/plugins/prefetch/plugin.cc
index f4fedef68..ef1d2991d 100644
--- a/plugins/prefetch/plugin.cc
+++ b/plugins/prefetch/plugin.cc
@@ -584,8 +584,9 @@ contHandleFetch(const TSCont contp, TSEvent event, void *edata)
         TSHttpHdrReasonSet(bufp, hdrLoc, reason, reasonLen);
         PrefetchDebug("set response: %d %.*s '%s'", data->_status, reasonLen, reason, data->_body.c_str());
 
-        char *buf = static_cast<char *>(TSmalloc(data->_body.length() + 1));
-        sprintf(buf, "%s", data->_body.c_str());
+        size_t bufsize = data->_body.length() + 1;
+        char *buf      = static_cast<char *>(TSmalloc(bufsize));
+        memcpy(buf, data->_body.c_str(), bufsize);
         TSHttpTxnErrorBodySet(txnp, buf, strlen(buf), nullptr);
 
         setHeader(bufp, hdrLoc, TS_MIME_FIELD_CACHE_CONTROL, TS_MIME_LEN_CACHE_CONTROL, TS_HTTP_VALUE_NO_STORE,
diff --git a/proxy/http/HttpBodyFactory.cc b/proxy/http/HttpBodyFactory.cc
index c60680cc4..1f3e01ce5 100644
--- a/proxy/http/HttpBodyFactory.cc
+++ b/proxy/http/HttpBodyFactory.cc
@@ -410,11 +410,11 @@ HttpBodyFactory::fabricate(StrList *acpt_language_list, StrList *acpt_charset_li
   HttpBodyTemplate *t   = nullptr;
   HttpBodySet *body_set = nullptr;
   if (pType != nullptr && 0 != *pType && 0 != strncmp(pType, "NONE", 4)) {
-    sprintf(template_base, "%s_%s", pType, type);
+    snprintf(template_base, sizeof(template_base), "%s_%s", pType, type);
     t = find_template(set, template_base, &body_set);
     // Check for default alternate.
     if (t == nullptr) {
-      sprintf(template_base, "%s_default", pType);
+      snprintf(template_base, sizeof(template_base), "%s_default", pType);
       t = find_template(set, template_base, &body_set);
     }
   }
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 2138aa1d4..9797af453 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -4215,7 +4215,7 @@ HttpSM::do_hostdb_lookup()
     char d[MAXDNAME];
 
     // Look at the next_hop_scheme to determine what scheme to put in the SRV lookup
-    unsigned int scheme_len = sprintf(d, "_%s._tcp.", hdrtoken_index_to_wks(t_state.next_hop_scheme));
+    unsigned int scheme_len = snprintf(d, sizeof(d), "_%s._tcp.", hdrtoken_index_to_wks(t_state.next_hop_scheme));
     ink_strlcpy(d + scheme_len, t_state.server_info.name, sizeof(d) - scheme_len);
 
     SMDebug("dns_srv", "Beginning lookup of SRV records for origin %s", d);
diff --git a/proxy/http/remap/unit-tests/plugin_testing_common.cc b/proxy/http/remap/unit-tests/plugin_testing_common.cc
index 07a44e15f..6231d70c3 100644
--- a/proxy/http/remap/unit-tests/plugin_testing_common.cc
+++ b/proxy/http/remap/unit-tests/plugin_testing_common.cc
@@ -46,7 +46,7 @@ getTemporaryDir()
   tmpDir /= "sandbox_XXXXXX";
 
   char dirNameTemplate[tmpDir.string().length() + 1];
-  sprintf(dirNameTemplate, "%s", tmpDir.c_str());
+  memcpy(dirNameTemplate, tmpDir.c_str(), sizeof(dirNameTemplate));
 
   return fs::path(mkdtemp(dirNameTemplate));
 }
diff --git a/proxy/logging/Log.cc b/proxy/logging/Log.cc
index 636d171e0..c781950d9 100644
--- a/proxy/logging/Log.cc
+++ b/proxy/logging/Log.cc
@@ -1111,7 +1111,7 @@ Log::create_threads()
   // on the event system.
   for (int i = 0; i < preproc_threads; i++) {
     Continuation *preproc_cont = new LoggingPreprocContinuation(i);
-    sprintf(desc, "[LOG_PREPROC %d]", i);
+    snprintf(desc, sizeof(desc), "[LOG_PREPROC %d]", i);
     eventProcessor.spawn_thread(preproc_cont, desc, stacksize);
   }
 
diff --git a/src/traffic_top/stats.h b/src/traffic_top/stats.h
index ae0b7afb7..70965db88 100644
--- a/src/traffic_top/stats.h
+++ b/src/traffic_top/stats.h
@@ -306,7 +306,7 @@ public:
             }
             string key = item.name;
             char buffer[32];
-            sprintf(buffer, "%" PRId64, value);
+            snprintf(buffer, sizeof(buffer), "%" PRId64, value);
             string foo     = buffer;
             (*_stats)[key] = foo;
           }
diff --git a/src/tscore/ink_res_mkquery.cc b/src/tscore/ink_res_mkquery.cc
index 51fae21b3..80442b3ab 100644
--- a/src/tscore/ink_res_mkquery.cc
+++ b/src/tscore/ink_res_mkquery.cc
@@ -223,6 +223,8 @@ labellen(const u_char *lp)
   return (l);
 }
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 static int
 decode_bitstring(const unsigned char **cpp, char *dn, const char *eom)
 {
@@ -276,6 +278,7 @@ decode_bitstring(const unsigned char **cpp, char *dn, const char *eom)
   *cpp = cp;
   return (dn - beg);
 }
+#pragma GCC diagnostic pop
 
 /*%
  *	Thinking in noninternationalized USASCII (per the DNS spec),
diff --git a/tools/jtest/jtest.cc b/tools/jtest/jtest.cc
index 85bd06e50..46f5f4c39 100644
--- a/tools/jtest/jtest.cc
+++ b/tools/jtest/jtest.cc
@@ -332,10 +332,11 @@ struct FD {
 
   int state;   // request parsing state
   int req_pos; // request read position
-  char *base_url        = nullptr;
-  char *req_header      = nullptr;
-  char *response        = nullptr;
-  char *response_header = nullptr;
+  char *base_url          = nullptr;
+  char *req_header        = nullptr;
+  char *response          = nullptr;
+  char *response_header   = nullptr;
+  int max_req_header_size = 0;
   int length;
   int response_length;
   int response_remaining;
@@ -592,7 +593,8 @@ static void
 poll_init(int sock)
 {
   if (!fd[sock].req_header) {
-    fd[sock].req_header = (char *)malloc(HEADER_SIZE * pipeline + MAX_REQUEST_BODY_LENGTH);
+    fd[sock].max_req_header_size = HEADER_SIZE * pipeline + MAX_REQUEST_BODY_LENGTH;
+    fd[sock].req_header          = (char *)malloc(fd[sock].max_req_header_size);
   }
   if (!fd[sock].response_header) {
     fd[sock].response_header = (char *)malloc(HEADER_SIZE);
@@ -761,7 +763,8 @@ make_response_header(int sock, char *url_start, char *url_end, int *url_len, cha
                            no_cache ? "Pragma: no-cache\r\nCache-Control: no-cache\r\n" : "", url_start ? url_start : "");
     }
   } else {
-    *url_len = print_len = sprintf(header, "ftp://%s:%d/%12.10f/%d", local_host, server_port, fd[sock].doc, fd[sock].length);
+    *url_len = print_len =
+      snprintf(header, header_limit, "ftp://%s:%d/%12.10f/%d", local_host, server_port, fd[sock].doc, fd[sock].length);
   }
 
   if (show_headers) {
@@ -966,7 +969,7 @@ static void
 make_response(int sock, int code)
 {
   fd[sock].response        = fd[sock].req_header;
-  fd[sock].length          = sprintf(fd[sock].req_header, "%d\r\n", code);
+  fd[sock].length          = snprintf(fd[sock].req_header, fd[sock].max_req_header_size, "%d\r\n", code);
   fd[sock].req_pos         = 0;
   fd[sock].response_length = strlen(fd[sock].req_header);
   poll_set(sock, nullptr, write_ftp_response);
@@ -1452,7 +1455,7 @@ read_ftp_request(int sock)
       make_response(sock, res);
       return 0;
     } else if (STREQ(buffer, "SIZE")) {
-      fd[sock].length = sprintf(fd[sock].req_header, "213 %d\r\n", atoi(buffer + 5));
+      fd[sock].length = snprintf(fd[sock].req_header, fd[sock].max_req_header_size, "213 %d\r\n", atoi(buffer + 5));
       make_long_response(sock);
       return 0;
     } else if (STREQ(buffer, "MDTM")) {
@@ -1461,10 +1464,10 @@ read_ftp_request(int sock)
         err_rand = ts::Random::drandom();
       }
       if (err_rand < ftp_mdtm_err_rate) {
-        fd[sock].length = sprintf(fd[sock].req_header, "550 mdtm file not found\r\n");
+        fd[sock].length = snprintf(fd[sock].req_header, fd[sock].max_req_header_size, "550 mdtm file not found\r\n");
       } else {
         if (ftp_mdtm_rate == 0) {
-          fd[sock].length = sprintf(fd[sock].req_header, "213 19900615100045\r\n");
+          fd[sock].length = snprintf(fd[sock].req_header, fd[sock].max_req_header_size, "213 19900615100045\r\n");
         } else {
           time_t mdtm_now;
           time(&mdtm_now);
@@ -1472,10 +1475,10 @@ read_ftp_request(int sock)
             struct tm *mdtm_tm;
             ftp_mdtm_last_update = mdtm_now;
             mdtm_tm              = localtime(&ftp_mdtm_last_update);
-            sprintf(ftp_mdtm_str, "213 %.4d%.2d%.2d%.2d%.2d%.2d", mdtm_tm->tm_year + 1900, mdtm_tm->tm_mon + 1, mdtm_tm->tm_mday,
-                    mdtm_tm->tm_hour, mdtm_tm->tm_min, mdtm_tm->tm_sec);
+            snprintf(ftp_mdtm_str, sizeof(ftp_mdtm_str), "213 %.4d%.2d%.2d%.2d%.2d%.2d", mdtm_tm->tm_year + 1900,
+                     mdtm_tm->tm_mon + 1, mdtm_tm->tm_mday, mdtm_tm->tm_hour, mdtm_tm->tm_min, mdtm_tm->tm_sec);
           }
-          fd[sock].length = sprintf(fd[sock].req_header, "%s\r\n", ftp_mdtm_str);
+          fd[sock].length = snprintf(fd[sock].req_header, fd[sock].max_req_header_size, "%s\r\n", ftp_mdtm_str);
         }
       }
       make_long_response(sock);
@@ -1493,9 +1496,10 @@ read_ftp_request(int sock)
         printf("ftp PASV %d <-> %d\n", sock, fd[sock].ftp_data_fd);
       }
       unsigned short p = fd[fd[sock].ftp_data_fd].name.sin_port;
-      fd[sock].length  = sprintf(fd[sock].req_header, "227 (%u,%u,%u,%u,%u,%u)\r\n", ((unsigned char *)&local_addr)[0],
-                                ((unsigned char *)&local_addr)[1], ((unsigned char *)&local_addr)[2],
-                                ((unsigned char *)&local_addr)[3], ((unsigned char *)&p)[0], ((unsigned char *)&p)[1]);
+      fd[sock].length =
+        snprintf(fd[sock].req_header, fd[sock].max_req_header_size, "227 (%u,%u,%u,%u,%u,%u)\r\n",
+                 ((unsigned char *)&local_addr)[0], ((unsigned char *)&local_addr)[1], ((unsigned char *)&local_addr)[2],
+                 ((unsigned char *)&local_addr)[3], ((unsigned char *)&p)[0], ((unsigned char *)&p)[1]);
       if (verbose) {
         puts(fd[sock].req_header);
       }
@@ -1520,7 +1524,7 @@ read_ftp_request(int sock)
       ((unsigned char *)&(fd[sock].ftp_peer_port))[0] = strtol(start, &stop, 10);
       start                                           = ++stop;
       ((unsigned char *)&(fd[sock].ftp_peer_port))[1] = strtol(start, nullptr, 10);
-      fd[sock].length                                 = sprintf(fd[sock].req_header, "200 Okay\r\n");
+      fd[sock].length                                 = snprintf(fd[sock].req_header, fd[sock].max_req_header_size, "200 Okay\r\n");
       if (verbose) {
         puts(fd[sock].req_header);
       }
@@ -1568,8 +1572,9 @@ read_ftp_request(int sock)
         }
         return 1;
       }
-      fd[sock].response        = fd[sock].req_header;
-      fd[sock].length          = sprintf(fd[sock].req_header, "150 %d bytes\r\n", fd[fd[sock].ftp_data_fd].length);
+      fd[sock].response = fd[sock].req_header;
+      fd[sock].length =
+        snprintf(fd[sock].req_header, fd[sock].max_req_header_size, "150 %d bytes\r\n", fd[fd[sock].ftp_data_fd].length);
       fd[sock].req_pos         = 0;
       fd[sock].response_length = strlen(fd[sock].req_header);
       poll_set(sock, nullptr, write_ftp_response);
@@ -2929,64 +2934,64 @@ make_nohost_request(int sock, double dr, const char *evo_str, const char *extens
   switch (post_support) {
   case 0:
     if (range_mode) {
-      sprintf(fd[sock].req_header,
-              "GET http://%s:%d/%12.10f/%d%s%s HTTP/1.1\r\n"
-              "%s"
-              "%s"
-              "%s"
-              "%s"
-              "%s"
-              "%s"
-              "\r\n",
-              local_host, server_port, dr, fd[sock].response_length, evo_str, extension,
-              fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "Connection: close\r\n",
-              reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, "Host: localhost\r\n", rbuf, cookie);
+      snprintf(fd[sock].req_header, fd[sock].max_req_header_size,
+               "GET http://%s:%d/%12.10f/%d%s%s HTTP/1.1\r\n"
+               "%s"
+               "%s"
+               "%s"
+               "%s"
+               "%s"
+               "%s"
+               "\r\n",
+               local_host, server_port, dr, fd[sock].response_length, evo_str, extension,
+               fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "Connection: close\r\n",
+               reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, "Host: localhost\r\n", rbuf, cookie);
     } else {
-      sprintf(fd[sock].req_header,
-              ftp ? "GET ftp://%s:%d/%12.10f/%d%s%s HTTP/1.0\r\n"
-                    "%s"
-                    "%s"
-                    "%s"
-                    "%s"
-                    "\r\n" :
-                    "GET http://%s:%d/%12.10f/%d%s%s HTTP/1.0\r\n"
-                    "%s"
-                    "%s"
-                    "%s"
-                    "%s"
-                    "\r\n",
-              local_host, server_port, dr, fd[sock].response_length, evo_str, extension,
-              fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "",
-              reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, cookie);
+      snprintf(fd[sock].req_header, fd[sock].max_req_header_size,
+               ftp ? "GET ftp://%s:%d/%12.10f/%d%s%s HTTP/1.0\r\n"
+                     "%s"
+                     "%s"
+                     "%s"
+                     "%s"
+                     "\r\n" :
+                     "GET http://%s:%d/%12.10f/%d%s%s HTTP/1.0\r\n"
+                     "%s"
+                     "%s"
+                     "%s"
+                     "%s"
+                     "\r\n",
+               local_host, server_port, dr, fd[sock].response_length, evo_str, extension,
+               fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "",
+               reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, cookie);
     }
     break;
   case 1:
     if (range_mode) {
-      sprintf(fd[sock].req_header,
-              "POST http://%s:%d/%12.10f/%d%s%s HTTP/1.1\r\n"
-              "Content-Length: %d\r\n"
-              "%s"
-              "%s"
-              "%s"
-              "%s"
-              "%s"
-              "%s"
-              "\r\n",
-              local_host, server_port, dr, fd[sock].response_length, evo_str, extension, fd[sock].response_length,
-              fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "Connection: close\r\n",
-              reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, "Host: localhost\r\n", rbuf, cookie);
+      snprintf(fd[sock].req_header, fd[sock].max_req_header_size,
+               "POST http://%s:%d/%12.10f/%d%s%s HTTP/1.1\r\n"
+               "Content-Length: %d\r\n"
+               "%s"
+               "%s"
+               "%s"
+               "%s"
+               "%s"
+               "%s"
+               "\r\n",
+               local_host, server_port, dr, fd[sock].response_length, evo_str, extension, fd[sock].response_length,
+               fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "Connection: close\r\n",
+               reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, "Host: localhost\r\n", rbuf, cookie);
     } else {
-      sprintf(fd[sock].req_header,
-              "POST http://%s:%d/%12.10f/%d%s%s HTTP/1.0\r\n"
-              "Content-Length: %d\r\n"
-              "%s"
-              "%s"
-              "%s"
-              "%s"
-              "\r\n",
-              local_host, server_port, dr, fd[sock].response_length, evo_str, extension, fd[sock].response_length,
-              fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "",
-              reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, cookie);
+      snprintf(fd[sock].req_header, fd[sock].max_req_header_size,
+               "POST http://%s:%d/%12.10f/%d%s%s HTTP/1.0\r\n"
+               "Content-Length: %d\r\n"
+               "%s"
+               "%s"
+               "%s"
+               "%s"
+               "\r\n",
+               local_host, server_port, dr, fd[sock].response_length, evo_str, extension, fd[sock].response_length,
+               fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "",
+               reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, cookie);
     }
     post_length = fd[sock].response_length;
     break;
@@ -2995,31 +3000,31 @@ make_nohost_request(int sock, double dr, const char *evo_str, const char *extens
       ink_assert(!"post_size should never be zero!");
 
     if (range_mode) {
-      sprintf(fd[sock].req_header,
-              "POST http://%s:%d/%12.10f/%d%s%s HTTP/1.1\r\n"
-              "Content-Length: %d\r\n"
-              "%s"
-              "%s"
-              "%s"
-              "%s"
-              "%s"
-              "%s"
-              "\r\n",
-              local_host, server_port, dr, fd[sock].response_length, evo_str, extension, post_size,
-              fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "Connection: close\r\n",
-              reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, "Host: localhost\r\n", rbuf, cookie);
+      snprintf(fd[sock].req_header, fd[sock].max_req_header_size,
+               "POST http://%s:%d/%12.10f/%d%s%s HTTP/1.1\r\n"
+               "Content-Length: %d\r\n"
+               "%s"
+               "%s"
+               "%s"
+               "%s"
+               "%s"
+               "%s"
+               "\r\n",
+               local_host, server_port, dr, fd[sock].response_length, evo_str, extension, post_size,
+               fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "Connection: close\r\n",
+               reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, "Host: localhost\r\n", rbuf, cookie);
     } else {
-      sprintf(fd[sock].req_header,
-              "POST http://%s:%d/%12.10f/%d%s%s HTTP/1.0\r\n"
-              "Content-Length: %d\r\n"
-              "%s"
-              "%s"
-              "%s"
-              "%s"
-              "\r\n",
-              local_host, server_port, dr, fd[sock].response_length, evo_str, extension, post_size,
-              fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "",
-              reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, cookie);
+      snprintf(fd[sock].req_header, fd[sock].max_req_header_size,
+               "POST http://%s:%d/%12.10f/%d%s%s HTTP/1.0\r\n"
+               "Content-Length: %d\r\n"
+               "%s"
+               "%s"
+               "%s"
+               "%s"
+               "\r\n",
+               local_host, server_port, dr, fd[sock].response_length, evo_str, extension, post_size,
+               fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "",
+               reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, cookie);
     }
     post_length = post_size;
     break;
@@ -3031,17 +3036,17 @@ make_nohost_request(int sock, double dr, const char *evo_str, const char *extens
 static int
 make_host1_request(int sock, double dr, const char *evo_str, const char *extension, const char *eheaders, const char *cookie)
 {
-  sprintf(fd[sock].req_header,
-          "GET /%12.10f/%d%s%s HTTP/1.0\r\n"
-          "Host: %s:%d\r\n"
-          "%s"
-          "%s"
-          "%s"
-          "%s"
-          "\r\n",
-          dr, fd[sock].response_length, evo_str, extension, local_host, server_port,
-          fd[sock].keepalive ? "Connection: Keep-Alive\r\n" : "", reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "",
-          eheaders, cookie);
+  snprintf(fd[sock].req_header, fd[sock].max_req_header_size,
+           "GET /%12.10f/%d%s%s HTTP/1.0\r\n"
+           "Host: %s:%d\r\n"
+           "%s"
+           "%s"
+           "%s"
+           "%s"
+           "\r\n",
+           dr, fd[sock].response_length, evo_str, extension, local_host, server_port,
+           fd[sock].keepalive ? "Connection: Keep-Alive\r\n" : "",
+           reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, cookie);
   return 0;
 }
 
@@ -3049,15 +3054,15 @@ static int
 make_host2_request(int sock, double dr, const char *evo_str, const char *extension, const char *eheaders, const char *cookie)
 {
   /* Send a non-proxy client request i.e. for Transparency testing */
-  sprintf(fd[sock].req_header,
-          "GET /%12.10f/%d%s%s HTTP/1.0\r\n"
-          "%s"
-          "%s"
-          "%s"
-          "%s"
-          "\r\n",
-          dr, fd[sock].response_length, evo_str, extension, fd[sock].keepalive ? "Connection: Keep-Alive\r\n" : "",
-          reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, cookie);
+  snprintf(fd[sock].req_header, fd[sock].max_req_header_size,
+           "GET /%12.10f/%d%s%s HTTP/1.0\r\n"
+           "%s"
+           "%s"
+           "%s"
+           "%s"
+           "\r\n",
+           dr, fd[sock].response_length, evo_str, extension, fd[sock].keepalive ? "Connection: Keep-Alive\r\n" : "",
+           reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "", eheaders, cookie);
   return 0;
 }
 
@@ -3081,16 +3086,21 @@ build_request(int sock)
   *eheaders    = 0;
   int nheaders = extra_headers;
   if (nheaders > 0) {
-    char *eh = eheaders;
+    char *eh           = eheaders;
+    char *eheaders_end = eheaders + sizeof(eheaders);
     if (!vary_user_agent) {
-      eh += sprintf(eh, "User-Agent: Mozilla/4.04 [en] (X11; I; Linux 2.0.31 i586)\r\n");
+      eh += snprintf(eh, sizeof(eheaders) - (eh - eheaders), "User-Agent: Mozilla/4.04 [en] (X11; I; Linux 2.0.31 i586)\r\n");
+      ink_release_assert(eh < eheaders_end); // valdate that eh doesn't point past eheaders (buffer overflow)
       nheaders--;
     }
     if (nheaders > 0) {
-      eh += sprintf(eh, "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\n");
+      eh += snprintf(eh, sizeof(eheaders) - (eh - eheaders),
+                     "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\n");
+      ink_release_assert(eh < eheaders_end); // valdate that eh doesn't point past eheaders (buffer overflow)
     }
     while (--nheaders > 0) {
-      eh += sprintf(eh, "Extra-Header%d: a lot of junk for header %d\r\n", nheaders, nheaders);
+      eh += snprintf(eh, sizeof(eheaders) - (eh - eheaders), "Extra-Header%d: a lot of junk for header %d\r\n", nheaders, nheaders);
+      ink_release_assert(eh < eheaders_end); // valdate that eh doesn't point past eheaders (buffer overflow)
     }
   }
   char cookie[256];
@@ -3098,9 +3108,9 @@ build_request(int sock)
   fd[sock].nalternate = (int)(alternates * ts::Random::drandom());
   if (alternates) {
     if (!vary_user_agent) {
-      sprintf(cookie, "Cookie: jtest-cookie-%d\r\n", fd[sock].nalternate);
+      snprintf(cookie, sizeof(cookie), "Cookie: jtest-cookie-%d\r\n", fd[sock].nalternate);
     } else {
-      sprintf(cookie, "User-Agent: jtest-browser-%d\r\n", fd[sock].nalternate);
+      snprintf(cookie, sizeof(cookie), "User-Agent: jtest-browser-%d\r\n", fd[sock].nalternate);
     }
   }
   const char *extension;
@@ -3122,7 +3132,7 @@ build_request(int sock)
   evo_str[0] = '\0';
   if (evo_rate != 0.0) {
     double evo_index = dr + (((double)now) / HRTIME_HOUR) * evo_rate;
-    sprintf(evo_str, ".%u", ((unsigned int)evo_index));
+    snprintf(evo_str, sizeof(evo_str), ".%u", ((unsigned int)evo_index));
   }
 
   int post_body = 0;
@@ -3536,38 +3546,39 @@ make_url_client(const char *url, const char *base_url, bool seen, bool unthrottl
   if (nheaders > 0) {
     char *eh = eheaders;
     if (!vary_user_agent) {
-      eh += sprintf(eh, "User-Agent: Mozilla/4.04 [en] (X11; I; Linux 2.0.31 i586)\r\n");
+      eh += snprintf(eh, sizeof(eheaders) - (eh - eheaders), "User-Agent: Mozilla/4.04 [en] (X11; I; Linux 2.0.31 i586)\r\n");
       nheaders--;
     }
     if (nheaders > 0) {
-      eh += sprintf(eh, "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\n");
+      eh += snprintf(eh, sizeof(eheaders) - (eh - eheaders),
+                     "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\n");
     }
     while (--nheaders > 0) {
-      eh += sprintf(eh, "Extra-Header%d: a lot of junk for header %d\r\n", nheaders, nheaders);
+      eh += snprintf(eh, sizeof(eheaders) - (eh - eheaders), "Extra-Header%d: a lot of junk for header %d\r\n", nheaders, nheaders);
     }
   }
   if (proxy_port) {
-    sprintf(fd[sock].req_header,
-            "GET %s HTTP/1.0\r\n"
-            "%s"
-            "%s"
-            "Accept: */*\r\n"
-            "%s"
-            "\r\n",
-            curl, reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "",
-            fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "", eheaders);
+    snprintf(fd[sock].req_header, fd[sock].max_req_header_size,
+             "GET %s HTTP/1.0\r\n"
+             "%s"
+             "%s"
+             "Accept: */*\r\n"
+             "%s"
+             "\r\n",
+             curl, reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "",
+             fd[sock].keepalive ? "Proxy-Connection: Keep-Alive\r\n" : "", eheaders);
   } else {
-    sprintf(fd[sock].req_header,
-            "GET /%s%s%s%s%s HTTP/1.0\r\n"
-            "Host: %s\r\n"
-            "%s"
-            "%s"
-            "Accept: */*\r\n"
-            "%s"
-            "\r\n",
-            path, xquer ? "?" : "", quer, xpar ? ";" : "", para, host,
-            reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "",
-            fd[sock].keepalive ? "Connection: Keep-Alive\r\n" : "", eheaders);
+    snprintf(fd[sock].req_header, fd[sock].max_req_header_size,
+             "GET /%s%s%s%s%s HTTP/1.0\r\n"
+             "Host: %s\r\n"
+             "%s"
+             "%s"
+             "Accept: */*\r\n"
+             "%s"
+             "\r\n",
+             path, xquer ? "?" : "", quer, xpar ? ";" : "", para, host,
+             reload_rate > ts::Random::drandom() ? "Pragma: no-cache\r\n" : "",
+             fd[sock].keepalive ? "Connection: Keep-Alive\r\n" : "", eheaders);
   }
 
   if (verbose) {