]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
typecheck-gcc: add type checks for curl_multi_setopt()
authorDaniel Stenberg <daniel@haxx.se>
Fri, 22 Aug 2025 13:54:10 +0000 (15:54 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 22 Aug 2025 15:12:58 +0000 (17:12 +0200)
Test 745 verifies that all options are tested.

Closes #18357

include/curl/typecheck-gcc.h
tests/test745.pl

index d053332032d46fa1da6bfd26057039d5b56991cc..a0b41aeb2473918c31502bea4cad6413e3fcdcd6 100644 (file)
       curl_easy_getinfo(handle, info, arg);                             \
     })
 
+#define curl_multi_setopt(handle, option, value)                        \
+  __extension__({                                                       \
+      if(__builtin_constant_p(option)) {                                \
+        if(curlcheck_long_option(option))                               \
+          if(!curlcheck_long(value))                                    \
+            _curl_multi_setopt_err_long();                              \
+        if(curlcheck_off_t_option(option))                              \
+          if(!curlcheck_off_t(value))                                   \
+            _curl_multi_setopt_err_curl_off_t();                        \
+        if(curlcheck_multicb_data_option(option))                       \
+          if(!curlcheck_cb_data(value))                                 \
+            _curl_multi_setopt_err_cb_data();                           \
+        if(curlcheck_charpp_option(option))                             \
+          if(!curlcheck_ptrptr(value, char))                            \
+            _curl_multi_setopt_err_charpp();                            \
+        if((option) == CURLMOPT_PUSHFUNCTION)                           \
+          if(!curlcheck_multipush_cb(value))                            \
+            _curl_multi_setopt_err_pushcb();                            \
+        if((option) == CURLMOPT_SOCKETFUNCTION)                         \
+          if(!curlcheck_multisocket_cb(value))                          \
+            _curl_multi_setopt_err_socketcb();                          \
+        if((option) == CURLMOPT_TIMERFUNCTION)                          \
+          if(!curlcheck_multitimer_cb(value))                           \
+            _curl_multi_setopt_err_timercb();                           \
+      }                                                                 \
+      curl_multi_setopt(handle, option, value);                         \
+    })
+
+/* evaluates to true if the option takes a data argument to pass to a
+   callback */
+#define curlcheck_multicb_data_option(option)                           \
+  ((option) == CURLMOPT_PUSHDATA ||                                     \
+   (option) == CURLMOPT_SOCKETDATA ||                                   \
+   (option) == CURLMOPT_TIMERDATA ||                                    \
+   0)
+
+/* evaluates to true if the option takes a char ** argument */
+#define curlcheck_charpp_option(option)                                 \
+  ((option) == CURLMOPT_PIPELINING_SERVER_BL ||                         \
+   (option) == CURLMOPT_PIPELINING_SITE_BL ||                           \
+   0)
+
+/* evaluates to true if expr is of type curl_multi_timer_callback */
+#define curlcheck_multitimer_cb(expr)                                   \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_multi_timer_callback))
+
+/* evaluates to true if expr is of type curl_socket_callback */
+#define curlcheck_multisocket_cb(expr)                                  \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_socket_callback))
+
+/* evaluates to true if expr is of type curl_push_callback */
+#define curlcheck_multipush_cb(expr)                                  \
+  (curlcheck_NULL(expr) ||                                            \
+   curlcheck_cb_compatible((expr), curl_push_callback))
+
 /*
  * For now, just make sure that the functions are called with three arguments
  */
 #define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
-#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+
 
 /* the actual warnings, triggered by calling the _curl_easy_setopt_err*
  * functions */
   __attribute__((__unused__)) __attribute__((__noinline__))             \
   id(void) { __asm__(""); }
 
+CURLWARNING(_curl_multi_setopt_err_long,
+            "curl_multi_setopt expects a long argument")
+CURLWARNING(_curl_multi_setopt_err_curl_off_t,
+            "curl_multi_setopt expects a curl_off_t argument")
+CURLWARNING(_curl_multi_setopt_err_cb_data,
+            "curl_multi_setopt expects a 'void *' argument")
+CURLWARNING(_curl_multi_setopt_err_charpp,
+            "curl_multi_setopt expects a 'char **' argument")
+CURLWARNING(_curl_multi_setopt_err_pushcb,
+            "curl_multi_setopt expects a curl_push_callback argument")
+CURLWARNING(_curl_multi_setopt_err_socketcb,
+            "curl_multi_setopt expects a curl_socket_callback argument")
+CURLWARNING(_curl_multi_setopt_err_timercb,
+            "curl_multi_setopt expects a curl_multi_timer_callback argument")
+
 CURLWARNING(_curl_easy_setopt_err_long,
             "curl_easy_setopt expects a long argument")
 CURLWARNING(_curl_easy_setopt_err_curl_off_t,
@@ -534,6 +606,14 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
    __builtin_types_compatible_p(__typeof__(expr), type *) ||            \
    __builtin_types_compatible_p(__typeof__(expr), const type *))
 
+/* evaluates to true if expr is type**, const type** or NULL */
+#define curlcheck_ptrptr(expr, type)                                    \
+  (curlcheck_NULL(expr) ||                                              \
+   __builtin_types_compatible_p(__typeof__(expr), type **) ||           \
+   __builtin_types_compatible_p(__typeof__(expr), type *[]) ||          \
+   __builtin_types_compatible_p(__typeof__(expr), const type *[]) ||    \
+   __builtin_types_compatible_p(__typeof__(expr), const type **))
+
 /* evaluates to true if expr is one of type[], type*, NULL or const type* */
 #define curlcheck_arr(expr, type)                                       \
   (curlcheck_ptr((expr), type) ||                                       \
index 02ed3be5c3f8e37d141b089425152a903a1fa671..faddda429f396bdc9adf350f2c617f541a3bf8d8 100755 (executable)
@@ -60,6 +60,18 @@ sub getinclude {
     $enum{"CURLOPT_CONV_FROM_UTF8_FUNCTION"}++;
     $enum{"CURLOPT_CONV_TO_NETWORK_FUNCTION"}++;
     close($f);
+
+    open(my $f, "<", "$root/include/curl/multi.h")
+        || die "no curl.h";
+    while(<$f>) {
+        if($_ =~ /\((CURLMOPT[^,]*), (CURLOPTTYPE_[^,]*)/) {
+            my ($opt, $type) = ($1, $2);
+            if($type !~ /LONG|OFF_T/) {
+                $enum{$opt}++;
+            }
+        }
+    }
+    close($f);
 }
 
 gettypecheck();