[Tarantool-patches] [PATCH] Ensure all curl symbols are exported
Yaroslav Dynnikov
yaroslav.dynnikov at tarantool.org
Thu Aug 6 16:19:55 MSK 2020
In the recent update of libcurl (2.5.0-278-g807c7fa58) its layout has
changed: private function `Curl_version_init()` which used to fill-in
info structure was eliminated. As a result, no symbols for
`libcurl_la-version.o` remained used, so it wasn't included in tarantool
binary. And `curl_version` and `curl_version_info` symbols went missing.
According to libcurl naming conventions all exported symbols are named
as `curl_*`. This patch lists them all explicitly in `exprots.h` and
adds the test.
Close #5223
Issue: https://github.com/tarantool/tarantool/issues/5223
Branch: https://github.com/tarantool/tarantool/tree/rosik/gh-5223-missing-curl-symbols
---
src/exports.h | 81 ++++++++++
test/box-tap/gh-5223-curl-exports.test.lua | 177 +++++++++++++++++++++
2 files changed, 258 insertions(+)
create mode 100755 test/box-tap/gh-5223-curl-exports.test.lua
diff --git a/src/exports.h b/src/exports.h
index 7cf283e5b..7f0601f4f 100644
--- a/src/exports.h
+++ b/src/exports.h
@@ -113,6 +113,87 @@ EXPORT(csv_feed)
EXPORT(csv_iterator_create)
EXPORT(csv_next)
EXPORT(csv_setopt)
+EXPORT(curl_easy_cleanup)
+EXPORT(curl_easy_duphandle)
+EXPORT(curl_easy_escape)
+EXPORT(curl_easy_getinfo)
+EXPORT(curl_easy_init)
+EXPORT(curl_easy_pause)
+EXPORT(curl_easy_perform)
+EXPORT(curl_easy_recv)
+EXPORT(curl_easy_reset)
+EXPORT(curl_easy_send)
+EXPORT(curl_easy_setopt)
+EXPORT(curl_easy_strerror)
+EXPORT(curl_easy_unescape)
+EXPORT(curl_easy_upkeep)
+EXPORT(curl_escape)
+EXPORT(curl_formadd)
+EXPORT(curl_formfree)
+EXPORT(curl_formget)
+EXPORT(curl_free)
+EXPORT(curl_getdate)
+EXPORT(curl_getenv)
+EXPORT(curl_global_cleanup)
+EXPORT(curl_global_init)
+EXPORT(curl_global_init_mem)
+EXPORT(curl_global_sslset)
+EXPORT(curl_maprintf)
+EXPORT(curl_mfprintf)
+EXPORT(curl_mime_addpart)
+EXPORT(curl_mime_data)
+EXPORT(curl_mime_data_cb)
+EXPORT(curl_mime_encoder)
+EXPORT(curl_mime_filedata)
+EXPORT(curl_mime_filename)
+EXPORT(curl_mime_free)
+EXPORT(curl_mime_headers)
+EXPORT(curl_mime_init)
+EXPORT(curl_mime_name)
+EXPORT(curl_mime_subparts)
+EXPORT(curl_mime_type)
+EXPORT(curl_mprintf)
+EXPORT(curl_msnprintf)
+EXPORT(curl_msprintf)
+EXPORT(curl_multi_add_handle)
+EXPORT(curl_multi_assign)
+EXPORT(curl_multi_cleanup)
+EXPORT(curl_multi_fdset)
+EXPORT(curl_multi_info_read)
+EXPORT(curl_multi_init)
+EXPORT(curl_multi_perform)
+EXPORT(curl_multi_poll)
+EXPORT(curl_multi_remove_handle)
+EXPORT(curl_multi_setopt)
+EXPORT(curl_multi_socket)
+EXPORT(curl_multi_socket_action)
+EXPORT(curl_multi_socket_all)
+EXPORT(curl_multi_strerror)
+EXPORT(curl_multi_timeout)
+EXPORT(curl_multi_wait)
+EXPORT(curl_mvaprintf)
+EXPORT(curl_mvfprintf)
+EXPORT(curl_mvprintf)
+EXPORT(curl_mvsnprintf)
+EXPORT(curl_mvsprintf)
+EXPORT(curl_pushheader_byname)
+EXPORT(curl_pushheader_bynum)
+EXPORT(curl_share_cleanup)
+EXPORT(curl_share_init)
+EXPORT(curl_share_setopt)
+EXPORT(curl_share_strerror)
+EXPORT(curl_slist_append)
+EXPORT(curl_slist_free_all)
+EXPORT(curl_strequal)
+EXPORT(curl_strnequal)
+EXPORT(curl_unescape)
+EXPORT(curl_url)
+EXPORT(curl_url_cleanup)
+EXPORT(curl_url_dup)
+EXPORT(curl_url_get)
+EXPORT(curl_url_set)
+EXPORT(curl_version)
+EXPORT(curl_version_info)
EXPORT(decimal_unpack)
EXPORT(error_ref)
EXPORT(error_set_prev)
diff --git a/test/box-tap/gh-5223-curl-exports.test.lua b/test/box-tap/gh-5223-curl-exports.test.lua
new file mode 100755
index 000000000..300d60b07
--- /dev/null
+++ b/test/box-tap/gh-5223-curl-exports.test.lua
@@ -0,0 +1,177 @@
+#!/usr/bin/env tarantool
+
+local tap = require('tap')
+local ffi = require('ffi')
+ffi.cdef([[
+ void *dlsym(void *handle, const char *symbol);
+ struct curl_version_info_data {
+ int age; /* see description below */
+ const char *version; /* human readable string */
+ unsigned int version_num; /* numeric representation */
+ const char *host; /* human readable string */
+ int features; /* bitmask, see below */
+ char *ssl_version; /* human readable string */
+ long ssl_version_num; /* not used, always zero */
+ const char *libz_version; /* human readable string */
+ const char * const *protocols; /* protocols */
+
+ /* when 'age' is CURLVERSION_SECOND or higher, the members below exist */
+ const char *ares; /* human readable string */
+ int ares_num; /* number */
+
+ /* when 'age' is CURLVERSION_THIRD or higher, the members below exist */
+ const char *libidn; /* human readable string */
+
+ /* when 'age' is CURLVERSION_FOURTH or higher (>= 7.16.1), the members
+ below exist */
+ int iconv_ver_num; /* '_libiconv_version' if iconv support enabled */
+
+ const char *libssh_version; /* human readable string */
+
+ /* when 'age' is CURLVERSION_FIFTH or higher (>= 7.57.0), the members
+ below exist */
+ unsigned int brotli_ver_num; /* Numeric Brotli version
+ (MAJOR << 24) | (MINOR << 12) | PATCH */
+ const char *brotli_version; /* human readable string. */
+
+ /* when 'age' is CURLVERSION_SIXTH or higher (>= 7.66.0), the members
+ below exist */
+ unsigned int nghttp2_ver_num; /* Numeric nghttp2 version
+ (MAJOR << 16) | (MINOR << 8) | PATCH */
+ const char *nghttp2_version; /* human readable string. */
+
+ const char *quic_version; /* human readable quic (+ HTTP/3) library +
+ version or NULL */
+
+ /* when 'age' is CURLVERSION_SEVENTH or higher (>= 7.70.0), the members
+ below exist */
+ const char *cainfo; /* the built-in default CURLOPT_CAINFO, might
+ be NULL */
+ const char *capath; /* the built-in default CURLOPT_CAPATH, might
+ be NULL */
+ };
+
+ struct curl_version_info_data *curl_version_info(int age);
+]])
+
+local info = ffi.C.curl_version_info(7)
+local test = tap.test('curl-features')
+test:plan(3)
+
+if test:ok(info.ssl_version ~= nil, 'Curl built with SSL support') then
+ test:diag('ssl_version: ' .. ffi.string(info.ssl_version))
+end
+if test:ok(info.libz_version ~= nil, 'Curl built with LIBZ') then
+ test:diag('libz_version: ' .. ffi.string(info.libz_version))
+end
+
+local RTLD_DEFAULT
+-- See `man 3 dlsym`:
+-- RTLD_DEFAULT
+-- Find the first occurrence of the desired symbol using the default
+-- shared object search order. The search will include global symbols
+-- in the executable and its dependencies, as well as symbols in shared
+-- objects that were dynamically loaded with the RTLD_GLOBAL flag.
+if jit.os == "OSX" then
+ RTLD_DEFAULT = ffi.cast("void *", -2LL)
+else
+ RTLD_DEFAULT = ffi.cast("void *", 0LL)
+end
+
+-- The following list was obtained by parsing libcurl.a static library:
+-- nm libcurl.a | grep -oP 'T \K(curl_.+)$' | sort
+local curl_symbols = {
+ 'curl_easy_cleanup',
+ 'curl_easy_duphandle',
+ 'curl_easy_escape',
+ 'curl_easy_getinfo',
+ 'curl_easy_init',
+ 'curl_easy_pause',
+ 'curl_easy_perform',
+ 'curl_easy_recv',
+ 'curl_easy_reset',
+ 'curl_easy_send',
+ 'curl_easy_setopt',
+ 'curl_easy_strerror',
+ 'curl_easy_unescape',
+ 'curl_easy_upkeep',
+ 'curl_escape',
+ 'curl_formadd',
+ 'curl_formfree',
+ 'curl_formget',
+ 'curl_free',
+ 'curl_getdate',
+ 'curl_getenv',
+ 'curl_global_cleanup',
+ 'curl_global_init',
+ 'curl_global_init_mem',
+ 'curl_global_sslset',
+ 'curl_maprintf',
+ 'curl_mfprintf',
+ 'curl_mime_addpart',
+ 'curl_mime_data',
+ 'curl_mime_data_cb',
+ 'curl_mime_encoder',
+ 'curl_mime_filedata',
+ 'curl_mime_filename',
+ 'curl_mime_free',
+ 'curl_mime_headers',
+ 'curl_mime_init',
+ 'curl_mime_name',
+ 'curl_mime_subparts',
+ 'curl_mime_type',
+ 'curl_mprintf',
+ 'curl_msnprintf',
+ 'curl_msprintf',
+ 'curl_multi_add_handle',
+ 'curl_multi_assign',
+ 'curl_multi_cleanup',
+ 'curl_multi_fdset',
+ 'curl_multi_info_read',
+ 'curl_multi_init',
+ 'curl_multi_perform',
+ 'curl_multi_poll',
+ 'curl_multi_remove_handle',
+ 'curl_multi_setopt',
+ 'curl_multi_socket',
+ 'curl_multi_socket_action',
+ 'curl_multi_socket_all',
+ 'curl_multi_strerror',
+ 'curl_multi_timeout',
+ 'curl_multi_wait',
+ 'curl_mvaprintf',
+ 'curl_mvfprintf',
+ 'curl_mvprintf',
+ 'curl_mvsnprintf',
+ 'curl_mvsprintf',
+ 'curl_pushheader_byname',
+ 'curl_pushheader_bynum',
+ 'curl_share_cleanup',
+ 'curl_share_init',
+ 'curl_share_setopt',
+ 'curl_share_strerror',
+ 'curl_slist_append',
+ 'curl_slist_free_all',
+ 'curl_strequal',
+ 'curl_strnequal',
+ 'curl_unescape',
+ 'curl_url',
+ 'curl_url_cleanup',
+ 'curl_url_dup',
+ 'curl_url_get',
+ 'curl_url_set',
+ 'curl_version',
+ 'curl_version_info',
+}
+
+test:test('curl_symbols', function(t)
+ t:plan(#curl_symbols)
+ for _, sym in ipairs(curl_symbols) do
+ t:ok(
+ ffi.C.dlsym(RTLD_DEFAULT, sym) ~= nil,
+ ('Symbol %q found'):format(sym)
+ )
+ end
+end)
+
+os.exit(test:check() and 0 or 1)
--
2.25.1
More information about the Tarantool-patches
mailing list