From 358b609e9dfd503cc25985d197a92610cbbe9f3d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 6 Feb 2018 10:34:41 -0500 Subject: [PATCH] Enable (safe) use of zstd static-only APIs We'll only use these when the compile-time version and the run-time version of the zstd library match. Part of ticket 25162. --- changes/ticket25162 | 6 ++++++ src/common/compress_zstd.c | 36 ++++++++++++++++++++++++++++++++++++ src/common/compress_zstd.h | 6 ++++++ 3 files changed, 48 insertions(+) create mode 100644 changes/ticket25162 diff --git a/changes/ticket25162 b/changes/ticket25162 new file mode 100644 index 0000000000..37019a7f8f --- /dev/null +++ b/changes/ticket25162 @@ -0,0 +1,6 @@ + o Minor features (compression, zstd): + - When running with zstd, Tor now considers using advanced functions that + the zstd maintainers have labeled as potentially unstable. To + prevent breakage, Tor will only use this functionality when + the runtime version of the zstd library matches the version + with which it were compiled. Closes ticket 25162. diff --git a/src/common/compress_zstd.c b/src/common/compress_zstd.c index 0db87d61b7..7994487446 100644 --- a/src/common/compress_zstd.c +++ b/src/common/compress_zstd.c @@ -18,6 +18,13 @@ #include "compress.h" #include "compress_zstd.h" +/* This is a lie, but we make sure it doesn't get us in trouble by wrapping + * all invocations of zstd's static-only functions in a check to make sure + * that the compile-time version matches the run-time version. + * + * Note: Make sure that this file still builds with this macro disabled. */ +#define ZSTD_STATIC_LINKING_ONLY + #ifdef HAVE_ZSTD #include #endif @@ -85,6 +92,26 @@ tor_zstd_get_header_version_str(void) #endif } +#ifdef TOR_UNIT_TESTS +static int static_apis_disable_for_testing = 0; +#endif + +/** Return true iff we can use the "static-only" APIs. */ +int +tor_zstd_can_use_static_apis(void) +{ +#if defined(ZSTD_STATIC_LINKING_ONLY) && defined(HAVE_ZSTD) +#ifdef TOR_UNIT_TESTS + if (static_apis_disable_for_testing) { + return 0; + } +#endif + return (ZSTD_VERSION_NUMBER == ZSTD_versionNumber()); +#else + return 0; +#endif +} + /** Internal Zstandard state for incremental compression/decompression. * The body of this struct is not exposed. */ struct tor_zstd_compress_state_t { @@ -440,3 +467,12 @@ tor_zstd_init(void) atomic_counter_init(&total_zstd_allocation); } +#ifdef TOR_UNIT_TESTS +/** Testing only: disable usage of static-only APIs, so we can make sure that + * we still work without them. */ +void +tor_zstd_set_static_apis_disabled_for_testing(int disabled) +{ + static_apis_disable_for_testing = disabled; +} +#endif diff --git a/src/common/compress_zstd.h b/src/common/compress_zstd.h index 9bca24ded7..8882617c9f 100644 --- a/src/common/compress_zstd.h +++ b/src/common/compress_zstd.h @@ -17,6 +17,8 @@ const char *tor_zstd_get_version_str(void); const char *tor_zstd_get_header_version_str(void); +int tor_zstd_can_use_static_apis(void); + /** Internal state for an incremental Zstandard compression/decompression. */ typedef struct tor_zstd_compress_state_t tor_zstd_compress_state_t; @@ -42,5 +44,9 @@ size_t tor_zstd_get_total_allocation(void); void tor_zstd_init(void); +#ifdef TOR_UNIT_TESTS +void tor_zstd_set_static_apis_disabled_for_testing(int disabled); +#endif + #endif /* !defined(TOR_COMPRESS_ZSTD_H) */