From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp29.i.mail.ru (smtp29.i.mail.ru [94.100.177.89]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 35169445320 for ; Thu, 6 Aug 2020 16:20:18 +0300 (MSK) From: Yaroslav Dynnikov Date: Thu, 6 Aug 2020 16:19:55 +0300 Message-Id: <20200806131955.3400088-1-yaroslav.dynnikov@tarantool.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH] Ensure all curl symbols are exported List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: tarantool-patches@dev.tarantool.org Cc: Yaroslav Dynnikov , Vladislav Shpilevoy , Alexander Turenko 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