]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
urldata: use a curl_prot_t type for storing protocol bits
authorDaniel Stenberg <daniel@haxx.se>
Mon, 12 Sep 2022 07:57:01 +0000 (09:57 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 13 Sep 2022 09:26:49 +0000 (11:26 +0200)
This internal-use-only storage type can be bumped to a curl_off_t once
we need to use bit 32 as the previous 'unsigned int' can no longer hold
them all then.

The websocket protocols take bit 30 and 31 so they are the last ones
that fit within 32 bits - but cannot properly be exported through APIs
since those use *signed* 32 bit types (long) in places.

Closes #9481

lib/connect.c
lib/setopt.c
lib/url.c
lib/urldata.h

index be9f72117cbeaa967f6fc7fe6e2b1035681e2f21..d2c3ef267413301d327d0d87a3dc3fbdc85eeb02 100644 (file)
@@ -625,7 +625,8 @@ void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn,
   else
     data->info.conn_local_ip[0] = 0;
   data->info.conn_scheme = conn->handler->scheme;
-  data->info.conn_protocol = conn->handler->protocol;
+  /* conn_protocol can only provide "old" protocols */
+  data->info.conn_protocol = (conn->handler->protocol) & CURLPROTO_MASK;
   data->info.conn_primary_port = conn->port;
   data->info.conn_remote_port = conn->remote_port;
   data->info.conn_local_port = local_port;
index a84ae4fa47ea2be4bec6f1ec2f5d6afaa0541ffd..8639225ebb987a6f81c61aa7e47506a8ac49af2a 100644 (file)
@@ -148,12 +148,12 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
 #define C_SSLVERSION_VALUE(x) (x & 0xffff)
 #define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000)
 
-static CURLcode protocol2num(char *str, curl_off_t *val)
+static CURLcode protocol2num(char *str, curl_prot_t *val)
 {
   bool found_comma = FALSE;
   static struct scheme {
     const char *name;
-    curl_off_t bit;
+    curl_prot_t bit;
   } const protos[] = {
     { "dict", CURLPROTO_DICT },
     { "file", CURLPROTO_FILE },
@@ -2649,31 +2649,35 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
        transfer, which thus helps the app which takes URLs from users or other
        external inputs and want to restrict what protocol(s) to deal
        with. Defaults to CURLPROTO_ALL. */
-    data->set.allowed_protocols = (curl_off_t)va_arg(param, long);
+    data->set.allowed_protocols = (curl_prot_t)va_arg(param, long);
     break;
 
   case CURLOPT_REDIR_PROTOCOLS:
     /* set the bitmask for the protocols that libcurl is allowed to follow to,
        as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
        to be set in both bitmasks to be allowed to get redirected to. */
-    data->set.redir_protocols = (curl_off_t)va_arg(param, long);
+    data->set.redir_protocols = (curl_prot_t)va_arg(param, long);
     break;
 
-  case CURLOPT_PROTOCOLS_STR:
+  case CURLOPT_PROTOCOLS_STR: {
+    curl_prot_t prot;
     argptr = va_arg(param, char *);
-    result = protocol2num(argptr, &bigsize);
+    result = protocol2num(argptr, &prot);
     if(result)
       return result;
-    data->set.allowed_protocols = bigsize;
+    data->set.allowed_protocols = prot;
     break;
+  }
 
-  case CURLOPT_REDIR_PROTOCOLS_STR:
+  case CURLOPT_REDIR_PROTOCOLS_STR: {
+    curl_prot_t prot;
     argptr = va_arg(param, char *);
-    result = protocol2num(argptr, &bigsize);
+    result = protocol2num(argptr, &prot);
     if(result)
       return result;
-    data->set.redir_protocols = bigsize;
+    data->set.redir_protocols = prot;
     break;
+  }
 
   case CURLOPT_DEFAULT_PROTOCOL:
     /* Set the protocol to use when the URL doesn't include any protocol */
index 23d8caa10199a8088eebf87b1c3e66d74bd6a13f..3d65925236db9aa3c0383e29286bbda03f82f1d9 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -167,7 +167,7 @@ static void conn_free(struct connectdata *conn);
 *
 * Returns the family as a single bit protocol identifier.
 */
-static unsigned int get_protocol_family(const struct Curl_handler *h)
+static curl_prot_t get_protocol_family(const struct Curl_handler *h)
 {
   DEBUGASSERT(h);
   DEBUGASSERT(h->family);
index f6a644e67d386da2f44d1199cc34b15be61f71b9..13f75438b2a39247bc44aa49727edcb071b44027 100644 (file)
 #define PORT_MQTT 1883
 
 #ifdef USE_WEBSOCKETS
+/* CURLPROTO_GOPHERS (29) is the highest publicly used protocol bit number,
+ * the rest are internal information. If we use higher bits we only do this on
+ * platforms that have a >= 64 bit type and then we use such a type for the
+ * protocol fields in the protocol handler.
+ */
 #define CURLPROTO_WS     (1<<30)
 #define CURLPROTO_WSS    (1LL<<31)
+
+/* This type should be bumped to a curl_off_t once we need bit 32 or higher */
+typedef unsigned int curl_prot_t;
 #else
 #define CURLPROTO_WS 0
 #define CURLPROTO_WSS 0
+typedef unsigned int curl_prot_t;
 #endif
 
+/* This mask is for all the old protocols that are provided and defined in the
+   public header and shall exclude protocols added since which are not exposed
+   in the API */
+#define CURLPROTO_MASK   (0x3ffffff)
+
 #define DICT_MATCH "/MATCH:"
 #define DICT_MATCH2 "/M:"
 #define DICT_MATCH3 "/FIND:"
@@ -787,10 +801,10 @@ struct Curl_handler {
   void (*attach)(struct Curl_easy *data, struct connectdata *conn);
 
   int defport;            /* Default port. */
-  unsigned int protocol;  /* See CURLPROTO_* - this needs to be the single
-                             specific protocol bit */
-  unsigned int family;    /* single bit for protocol family; basically the
-                             non-TLS name of the protocol this is */
+  curl_prot_t protocol;  /* See CURLPROTO_* - this needs to be the single
+                            specific protocol bit */
+  curl_prot_t family;    /* single bit for protocol family; basically the
+                            non-TLS name of the protocol this is */
   unsigned int flags;     /* Extra particular characteristics, see PROTOPT_* */
 
 };
@@ -1345,7 +1359,7 @@ struct UrlState {
      This is strdup()ed data. */
   char *first_host;
   int first_remote_port;
-  unsigned int first_remote_protocol;
+  curl_prot_t first_remote_protocol;
 
   int retrycount; /* number of retries on a new connection */
   struct Curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
@@ -1776,8 +1790,8 @@ struct UserDefined {
 #ifdef ENABLE_IPV6
   unsigned int scope_id;  /* Scope id for IPv6 */
 #endif
-  curl_off_t allowed_protocols;
-  curl_off_t redir_protocols;
+  curl_prot_t allowed_protocols;
+  curl_prot_t redir_protocols;
   unsigned int mime_options;      /* Mime option flags. */
 
 #ifndef CURL_DISABLE_RTSP