Ver código fonte

Fix the warnings left in the 32-bit, BoringSSL and MSVC builds

time_t is 32 bits wide on 32-bit builds, so the millisecond counts in
set_max_timeout() and the streams' duration() narrowed into it
implicitly. Cast them as duration_to_sec_and_usec() already does. In
the tests, six content receivers took a uint64_t length where
ContentReceiver passes size_t, the Expect: 100-continue test kept
10 GiB in a size_t, and the Range checks compared ssize_t fields with
unsigned literals, so they now compare whole Ranges.
DoesNotReserveTheClaimedLength shifted a size_t by 41. It now claims
std::string().max_size(), the most the client accepts, and still
fails if the reserve cap is removed.

BoringSSL counts stacks in size_t, and takes the protocol version as
uint16_t and the error code as uint32_t. Walk the certificate stacks
with the decltype(count) loop used elsewhere, pass the version as
uint16_t, and cast the error code to what ERR_get_error() returns.

MSVC takes the send() length as int, so the raw send() calls left in
the tests go through detail::send_socket().
yhirose 2 dias atrás
pai
commit
7234944098
2 arquivos alterados com 69 adições e 78 exclusões
  1. 25 18
      httplib.h
  2. 44 60
      test/test.cc

+ 25 - 18
httplib.h

@@ -3645,7 +3645,7 @@ inline void ClientImpl::set_max_timeout(
     const std::chrono::duration<Rep, Period> &duration) {
   auto msec =
       std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
-  set_max_timeout(msec);
+  set_max_timeout(static_cast<time_t>(msec));
 }
 
 template <class Rep, class Period>
@@ -12685,9 +12685,10 @@ inline void SocketStream::get_local_ip_and_port(std::string &ip,
 inline socket_t SocketStream::socket() const { return sock_; }
 
 inline time_t SocketStream::duration() const {
-  return std::chrono::duration_cast<std::chrono::milliseconds>(
-             std::chrono::steady_clock::now() - start_time_)
-      .count();
+  return static_cast<time_t>(
+      std::chrono::duration_cast<std::chrono::milliseconds>(
+          std::chrono::steady_clock::now() - start_time_)
+          .count());
 }
 
 inline void SocketStream::set_read_timeout(time_t sec, time_t usec) {
@@ -13229,9 +13230,10 @@ inline void SSLSocketStream::get_local_ip_and_port(std::string &ip,
 inline socket_t SSLSocketStream::socket() const { return sock_; }
 
 inline time_t SSLSocketStream::duration() const {
-  return std::chrono::duration_cast<std::chrono::milliseconds>(
-             std::chrono::steady_clock::now() - start_time_)
-      .count();
+  return static_cast<time_t>(
+      std::chrono::duration_cast<std::chrono::milliseconds>(
+          std::chrono::steady_clock::now() - start_time_)
+          .count());
 }
 
 inline void SSLSocketStream::set_read_timeout(time_t sec, time_t usec) {
@@ -13362,9 +13364,10 @@ inline void WebSocketSSLStream::get_local_ip_and_port(std::string &ip,
 inline socket_t WebSocketSSLStream::socket() const { return sock_; }
 
 inline time_t WebSocketSSLStream::duration() const {
-  return std::chrono::duration_cast<std::chrono::milliseconds>(
-             std::chrono::steady_clock::now() - start_time_)
-      .count();
+  return static_cast<time_t>(
+      std::chrono::duration_cast<std::chrono::milliseconds>(
+          std::chrono::steady_clock::now() - start_time_)
+          .count());
 }
 
 inline void WebSocketSSLStream::set_read_timeout(time_t sec, time_t usec) {
@@ -19750,7 +19753,7 @@ inline void free_context(ctx_t ctx) {
 inline bool set_min_version(ctx_t ctx, Version version) {
   if (!ctx) return false;
   return SSL_CTX_set_min_proto_version(static_cast<SSL_CTX *>(ctx),
-                                       static_cast<int>(version)) == 1;
+                                       static_cast<uint16_t>(version)) == 1;
 }
 
 inline bool load_ca_pem(ctx_t ctx, const char *pem, size_t len) {
@@ -20203,11 +20206,13 @@ inline size_t get_peer_certs(const_session_t session,
   if (SSL_is_server(ssl)) {
     if (auto leaf = get_peer_cert(session)) { certs.push_back(leaf); }
   }
-  auto sk = SSL_get_peer_cert_chain(ssl);
-  for (int i = 0; sk && i < sk_X509_num(sk); i++) {
-    auto x509 = sk_X509_value(sk, i);
-    X509_up_ref(x509);
-    certs.push_back(static_cast<cert_t>(x509));
+  if (auto sk = SSL_get_peer_cert_chain(ssl)) {
+    auto count = sk_X509_num(sk);
+    for (decltype(count) i = 0; i < count; i++) {
+      auto x509 = sk_X509_value(sk, i);
+      X509_up_ref(x509);
+      certs.push_back(static_cast<cert_t>(x509));
+    }
   }
   return certs.size();
 }
@@ -20409,7 +20414,8 @@ inline uint64_t get_error() { return ERR_get_error(); }
 
 inline std::string error_string(uint64_t code) {
   char buf[256];
-  ERR_error_string_n(static_cast<unsigned long>(code), buf, sizeof(buf));
+  ERR_error_string_n(static_cast<decltype(ERR_get_error())>(code), buf,
+                     sizeof(buf));
   return std::string(buf);
 }
 
@@ -20423,7 +20429,8 @@ inline ca_store_t create_ca_store(const char *pem, size_t len) {
 
   auto store = X509_STORE_new();
   if (store) {
-    for (auto i = 0; i < static_cast<int>(sk_X509_INFO_num(inf)); i++) {
+    auto count = sk_X509_INFO_num(inf);
+    for (decltype(count) i = 0; i < count; i++) {
       auto itmp = sk_X509_INFO_value(inf, i);
       if (!itmp) { continue; }
       if (itmp->x509) { X509_STORE_add_cert(store, itmp->x509); }

+ 44 - 60
test/test.cc

@@ -2283,27 +2283,21 @@ TEST(ParseHeaderValueTest, Range) {
     Ranges ranges;
     auto ret = detail::parse_range_header("bytes=1-", ranges);
     EXPECT_TRUE(ret);
-    EXPECT_EQ(1u, ranges.size());
-    EXPECT_EQ(1u, ranges[0].first);
-    EXPECT_EQ(-1, ranges[0].second);
+    EXPECT_EQ((Ranges{{1, -1}}), ranges);
   }
 
   {
     Ranges ranges;
     auto ret = detail::parse_range_header("bytes=-1", ranges);
     EXPECT_TRUE(ret);
-    EXPECT_EQ(1u, ranges.size());
-    EXPECT_EQ(-1, ranges[0].first);
-    EXPECT_EQ(1u, ranges[0].second);
+    EXPECT_EQ((Ranges{{-1, 1}}), ranges);
   }
 
   {
     Ranges ranges;
     auto ret = detail::parse_range_header("bytes=1-10", ranges);
     EXPECT_TRUE(ret);
-    EXPECT_EQ(1u, ranges.size());
-    EXPECT_EQ(1u, ranges[0].first);
-    EXPECT_EQ(10u, ranges[0].second);
+    EXPECT_EQ((Ranges{{1, 10}}), ranges);
   }
 
   {
@@ -2316,11 +2310,7 @@ TEST(ParseHeaderValueTest, Range) {
     Ranges ranges;
     auto ret = detail::parse_range_header("bytes=1-10, 100-", ranges);
     EXPECT_TRUE(ret);
-    EXPECT_EQ(2u, ranges.size());
-    EXPECT_EQ(1u, ranges[0].first);
-    EXPECT_EQ(10u, ranges[0].second);
-    EXPECT_EQ(100u, ranges[1].first);
-    EXPECT_EQ(-1, ranges[1].second);
+    EXPECT_EQ((Ranges{{1, 10}, {100, -1}}), ranges);
   }
 
   {
@@ -2328,13 +2318,7 @@ TEST(ParseHeaderValueTest, Range) {
     auto ret =
         detail::parse_range_header("bytes=1-10, 100-200, 300-400", ranges);
     EXPECT_TRUE(ret);
-    EXPECT_EQ(3u, ranges.size());
-    EXPECT_EQ(1u, ranges[0].first);
-    EXPECT_EQ(10u, ranges[0].second);
-    EXPECT_EQ(100u, ranges[1].first);
-    EXPECT_EQ(200u, ranges[1].second);
-    EXPECT_EQ(300u, ranges[2].first);
-    EXPECT_EQ(400u, ranges[2].second);
+    EXPECT_EQ((Ranges{{1, 10}, {100, 200}, {300, 400}}), ranges);
   }
 
   {
@@ -9900,12 +9884,12 @@ TEST_F(ServerTest, GzipWithContentReceiver) {
   Headers headers;
   headers.emplace("Accept-Encoding", "gzip, deflate");
   std::string body;
-  auto res = cli_.Get("/compress", headers,
-                      [&](const char *data, uint64_t data_length) {
-                        EXPECT_EQ(100U, data_length);
-                        body.append(data, data_length);
-                        return true;
-                      });
+  auto res =
+      cli_.Get("/compress", headers, [&](const char *data, size_t data_length) {
+        EXPECT_EQ(100U, data_length);
+        body.append(data, data_length);
+        return true;
+      });
 
   ASSERT_TRUE(res) << "Error: " << to_string(res.error());
   EXPECT_EQ("gzip", res->get_header_value("Content-Encoding"));
@@ -9937,12 +9921,12 @@ TEST_F(ServerTest, GzipWithContentReceiverWithoutAcceptEncoding) {
   headers.emplace("Accept-Encoding", "");
 
   std::string body;
-  auto res = cli_.Get("/compress", headers,
-                      [&](const char *data, uint64_t data_length) {
-                        EXPECT_EQ(100U, data_length);
-                        body.append(data, data_length);
-                        return true;
-                      });
+  auto res =
+      cli_.Get("/compress", headers, [&](const char *data, size_t data_length) {
+        EXPECT_EQ(100U, data_length);
+        body.append(data, data_length);
+        return true;
+      });
 
   ASSERT_TRUE(res) << "Error: " << to_string(res.error());
   EXPECT_TRUE(res->get_header_value("Content-Encoding").empty());
@@ -9974,7 +9958,7 @@ TEST_F(ServerTest, NoGzipWithContentReceiver) {
   headers.emplace("Accept-Encoding", "gzip, deflate");
   std::string body;
   auto res = cli_.Get("/nocompress", headers,
-                      [&](const char *data, uint64_t data_length) {
+                      [&](const char *data, size_t data_length) {
                         EXPECT_EQ(100U, data_length);
                         body.append(data, data_length);
                         return true;
@@ -10430,12 +10414,12 @@ TEST_F(ServerTest, ZstdWithContentReceiver) {
   Headers headers;
   headers.emplace("Accept-Encoding", "zstd");
   std::string body;
-  auto res = cli_.Get("/compress", headers,
-                      [&](const char *data, uint64_t data_length) {
-                        EXPECT_EQ(100U, data_length);
-                        body.append(data, data_length);
-                        return true;
-                      });
+  auto res =
+      cli_.Get("/compress", headers, [&](const char *data, size_t data_length) {
+        EXPECT_EQ(100U, data_length);
+        body.append(data, data_length);
+        return true;
+      });
 
   ASSERT_TRUE(res) << "Error: " << to_string(res.error());
   EXPECT_EQ("zstd", res->get_header_value("Content-Encoding"));
@@ -10474,12 +10458,12 @@ TEST_F(ServerTest, ZstdWithContentReceiverWithoutAcceptEncoding) {
   headers.emplace("Accept-Encoding", "");
 
   std::string body;
-  auto res = cli_.Get("/compress", headers,
-                      [&](const char *data, uint64_t data_length) {
-                        EXPECT_EQ(100U, data_length);
-                        body.append(data, data_length);
-                        return true;
-                      });
+  auto res =
+      cli_.Get("/compress", headers, [&](const char *data, size_t data_length) {
+        EXPECT_EQ(100U, data_length);
+        body.append(data, data_length);
+        return true;
+      });
 
   ASSERT_TRUE(res) << "Error: " << to_string(res.error());
   EXPECT_TRUE(res->get_header_value("Content-Encoding").empty());
@@ -10511,7 +10495,7 @@ TEST_F(ServerTest, NoZstdWithContentReceiver) {
   headers.emplace("Accept-Encoding", "zstd");
   std::string body;
   auto res = cli_.Get("/nocompress", headers,
-                      [&](const char *data, uint64_t data_length) {
+                      [&](const char *data, size_t data_length) {
                         EXPECT_EQ(100U, data_length);
                         body.append(data, data_length);
                         return true;
@@ -14383,8 +14367,9 @@ TEST_F(LargePayloadMaxLengthTest, NoContentLengthExceeds10MB) {
 TEST(ClientPayloadTest, DoesNotReserveTheClaimedLength) {
   Server svr;
   svr.Get("/", [](const Request &, Response &res) {
-    // Claims far more than it sends, then drops the connection.
-    res.set_content_provider(size_t(1) << 41, "text/plain",
+    // Claims the most the client accepts, far more than it sends, then drops
+    // the connection.
+    res.set_content_provider(std::string().max_size(), "text/plain",
                              [](size_t, size_t, DataSink &sink) {
                                sink.write("abc", 3);
                                return false;
@@ -21164,7 +21149,7 @@ TEST(Expect100ContinueHandlerTest, ExpectationFailedIsFinalResponse) {
 TEST(Expect100ContinueTest, ServerClosesConnection) {
   static constexpr char reject[] = "Unauthorized";
   static constexpr char accept[] = "Upload accepted";
-  constexpr size_t total_size = 10 * 1024 * 1024 * 1024ULL;
+  constexpr uint64_t total_size = 10 * 1024 * 1024 * 1024ULL;
 
   Server svr;
 
@@ -21202,8 +21187,8 @@ TEST(Expect100ContinueTest, ServerClosesConnection) {
     curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, list.get());
 
     struct read_data {
-      size_t read_size;
-      size_t total_size;
+      uint64_t read_size;
+      uint64_t total_size;
     } data = {0, total_size};
     using read_callback_t =
         size_t (*)(char *ptr, size_t size, size_t nmemb, void *userdata);
@@ -25986,8 +25971,7 @@ TEST(SSLClientServerTest, UpdateCertsSetsClientCAList) {
   ASSERT_TRUE(ssl_ctx != nullptr);
 
   STACK_OF(X509_NAME) *ca_list_before = SSL_CTX_get_client_CA_list(ssl_ctx);
-  int count_before = ca_list_before ? sk_X509_NAME_num(ca_list_before) : 0;
-  EXPECT_EQ(0, count_before);
+  EXPECT_TRUE(!ca_list_before || sk_X509_NAME_num(ca_list_before) == 0);
 
   // Now update with client CA (PEM string)
   std::string cert_pem, key_pem, ca_pem;
@@ -26002,7 +25986,7 @@ TEST(SSLClientServerTest, UpdateCertsSetsClientCAList) {
   // Now client CA list should be set
   STACK_OF(X509_NAME) *ca_list_after = SSL_CTX_get_client_CA_list(ssl_ctx);
   ASSERT_TRUE(ca_list_after != nullptr);
-  EXPECT_GT(sk_X509_NAME_num(ca_list_after), 0);
+  EXPECT_TRUE(sk_X509_NAME_num(ca_list_after) > 0);
 }
 
 TEST(SSLClientServerTest, FilePathConstructorSetsClientCAList) {
@@ -26016,7 +26000,7 @@ TEST(SSLClientServerTest, FilePathConstructorSetsClientCAList) {
 
   STACK_OF(X509_NAME) *ca_list = SSL_CTX_get_client_CA_list(ssl_ctx);
   ASSERT_TRUE(ca_list != nullptr);
-  EXPECT_GT(sk_X509_NAME_num(ca_list), 0);
+  EXPECT_TRUE(sk_X509_NAME_num(ca_list) > 0);
 }
 
 #endif
@@ -28644,7 +28628,7 @@ static int count_smuggled_requests(const std::string &outer_head,
   }
 
   // Step 1: Send only the outer request headers (no body yet)
-  auto sent = send(sock, head.data(), head.size(), 0);
+  auto sent = detail::send_socket(sock, head.data(), head.size(), 0);
   EXPECT_EQ(static_cast<ssize_t>(head.size()), sent);
 
   // Step 2: Read the first response
@@ -28673,7 +28657,7 @@ static int count_smuggled_requests(const std::string &outer_head,
   // Step 3: Now send the body, which looks like a new HTTP request. On a
   // vulnerable server the keep-alive loop reads this as a second request. The
   // server may already have closed the connection, so the result is ignored.
-  send(sock, smuggled.data(), smuggled.size(), 0);
+  detail::send_socket(sock, smuggled.data(), smuggled.size(), 0);
 
   // Half-close so that a server which drained the body sees EOF and closes,
   // instead of the read below waiting for the read timeout.
@@ -28990,7 +28974,7 @@ TEST(KeepAliveTest, DeleteWithoutContentLengthDoesNotEatNextRequest) {
 
   auto send_request_and_read_response = [&](const std::string &req,
                                             std::string &out) -> bool {
-    auto sent = send(sock, req.data(), req.size(), 0);
+    auto sent = detail::send_socket(sock, req.data(), req.size(), 0);
     if (sent != static_cast<ssize_t>(req.size())) { return false; }
     char buf[4096];
     for (;;) {
@@ -29052,7 +29036,7 @@ TEST(KeepAliveTest, UnconsumedChunkedBodyIsNotDrainedWhenResponseCloses) {
                         "\r\n"
                         "4\r\n"
                         "data\r\n";
-  auto sent = send(sock, request.data(), request.size(), 0);
+  auto sent = detail::send_socket(sock, request.data(), request.size(), 0);
   ASSERT_EQ(static_cast<ssize_t>(request.size()), sent);
 
   std::string response;