cURL
Haxx ad
libcurl
Automatically get a mirror near you





COMPARE PRICES:
Digital cameras, MP3 Players, Camcorders, Mobile phones, PDA, Computers, Electronics LCD monitors, Printers, Notebook, DVD Players, Motherboards, TV, ipod, Processors. See all...

Shopping cart software
Online collaboration software

SourceForge.net Logo

cURL > Mailing List > Monthly Index > Single Mail

curl-library Archives

rfc: curl_easy_setopt() typechecker

From: Michal Marek <mmarek_at_suse.cz>
Date: Mon, 25 Feb 2008 15:11:01 +0100

Hi,

I played a bit with various extensions available in gcc and hacked
together a set of macros that allow for compile-time checking of
parameters passed to curl_easy_setopt(). The result is attached to this
mail as a patch, but needs probably a bit of explanation :) Also, the
patch isn't meant to be checked in as it is now.

How it works:
- curl_easy_setopt() is wrapped into a macro with a fixed number of
  three arguments. Passing less or more results in an error (see below).
- First, __builtin_constant_p() [1] determines, whether the number of
  the option is known at compile time. If it isn't, no checks are done
  and curl_easy_setopt() is called.
- If we know what option the user wants to set, the type of the argument
  is checked with __builtin_types_compatible_p() [1]. If the type
  matches, everything is OK.
- if the type doesn't match, a custom warning is issued using gcc 4.3's
  __attribute__((warning (...))) feature [3]. curl_easy_setopt() is
  called nevertheless

Example (error-checking omitted for sake of brevity):
$ nl -b a test.c
     1 #include <curl/curl.h>
     2
     3 int main()
     4 {
     5 CURL *h = curl_easy_init();
     6 curl_easy_setopt(h, CURLOPT_HTTPPROXYTUNNEL,
"http://proxy");
     7 curl_easy_setopt(h, CURLOPT_URL, "http://example.com/");
     8 curl_easy_perform(h);
     9 return 0;
    10 }
$ gcc -Wall -O2 -I ./include/ -l curl test.c
test.c: In function ‘main’:
test.c:6: warning: call to ‘_curl_easy_setopt_err_long’ declared with
attribute warning: curl_easy_setopt expects a long argument for this option

Above sounds pretty simple, but of course there are a few gotchas:
- The CURLOPT_SSLENGINE_DEFAULT option doesn't take any argument. This
  means that completely valid code using CURLOPT_SSLENGINE_DEFAULT can
  break due to the three-arg macro. OTOH it shouldn't be too hard to
  pass a dummy option argument. Also, googling for code possibly
  affected by this [3], I only found one project (among open source
  code, that is).
- __builtin_types_compatible_p() only works in C, not C++, so for C++
  there's no typechecking. Although it might be doable using rtti.
- It only works with the not-yet-released gcc 4.3.
- The macros are a bit messy, yeah :). But it's not fatal if the
  typecheck-gcc.h file gets out of sync with curl.h, it just won't check
  newly added options.
- It might not work (read: it might not issue warnings) with -O0
- While it's easy to recognize a char* pointer, checking the various
  function pointers prove rather hard. E.g. it's OK to write
    size_t my_write(void *, size_t, size_t, struct my_buf*);
                                            ^^^^^^^^^^^^^^
    curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, my_write);
  but the typechecker will treat it as a different type than the
  required one :-/

Anyway, except for the issue with CURLOPT_SSLENGINE_DEFAULT, it
shouldn't change API or ABI. I tried a build-test of a bunch of packages
that use libcurl in the openSUSE build service [4] and the only failures
were xmlrpc-c due to CURLOPT_SSLENGINE_DEFAULT and
libopensync-plugin-opie which uses -Werror (it gets what it asks for
;)). I didn't analyze the resulting warnings for false positives yet.
The most common warning is "curl_easy_setopt expects a long argument for
this option" (447 occurences), probably because nobody cares about int
vs. long.

Now the question: are you interested in this? I can offer maintaining
the typecheck-gcc.h file and/or documenting exactly how to maintain it.
Also, it's easy to extend this to cover other libcurl functions
(curl_easy_getinfo() is probably even more interesting than
curl_easy_setopt() due to the pointers involved) if there's interest.

Michal

[1] http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
[2] http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
[3]
http://www.google.com/codesearch?q=curl_easy_setopt.*CURLOPT_SSLENGINE_DEFAULT%5C%29
[4]
https://build.opensuse.org/project/show?project=home%3Amichal-m%3Acurl-typecheck
 (requires a registration, but access is otherwise unrestricted)

Received on 2008-02-25

These mail archives are generated by hypermail.

donate! Page updated October 19, 2006.
web site info