diff options
Diffstat (limited to 'ext/digest')
-rw-r--r-- | ext/digest/digest.c | 42 | ||||
-rw-r--r-- | ext/digest/digest.h | 19 | ||||
-rw-r--r-- | ext/digest/md5/md5cc.h | 12 |
3 files changed, 62 insertions, 11 deletions
diff --git a/ext/digest/digest.c b/ext/digest/digest.c index 68837a674c..bd8d3e815f 100644 --- a/ext/digest/digest.c +++ b/ext/digest/digest.c @@ -534,9 +534,39 @@ rb_digest_class_init(VALUE self) * * * rb_ivar_set(cDigest_SHA1, rb_intern("metadata"), - * Data_Wrap_Struct(0, 0, 0, (void *)&sha1)); + * rb_digest_make_metadata(&sha1)); */ +#ifdef DIGEST_USE_RB_EXT_RESOLVE_SYMBOL +static const rb_data_type_t metadata_type = { + "digest/metadata", + {0}, +}; + +RUBY_FUNC_EXPORTED VALUE +rb_digest_wrap_metadata(const rb_digest_metadata_t *meta) +{ + return rb_obj_freeze(TypedData_Wrap_Struct(0, &metadata_type, (void *)meta)); +} +#endif + +static rb_digest_metadata_t * +get_metadata_ptr(VALUE obj) +{ + rb_digest_metadata_t *algo; + +#ifdef DIGEST_USE_RB_EXT_RESOLVE_SYMBOL + if (!rb_typeddata_is_kind_of(obj, &metadata_type)) return 0; + algo = RTYPEDDATA_DATA(obj); +#else +# undef RUBY_UNTYPED_DATA_WARNING +# define RUBY_UNTYPED_DATA_WARNING 0 + Data_Get_Struct(obj, rb_digest_metadata_t, algo); +#endif + + return algo; +} + static rb_digest_metadata_t * get_digest_base_metadata(VALUE klass) { @@ -554,8 +584,8 @@ get_digest_base_metadata(VALUE klass) if (NIL_P(p)) rb_raise(rb_eRuntimeError, "Digest::Base cannot be directly inherited in Ruby"); - if (!RB_TYPE_P(obj, T_DATA) || RTYPEDDATA_P(obj)) { - wrong: + algo = get_metadata_ptr(obj); + if (!algo) { if (p == klass) rb_raise(rb_eTypeError, "%"PRIsVALUE"::metadata is not initialized properly", klass); @@ -564,12 +594,6 @@ get_digest_base_metadata(VALUE klass) klass, p); } -#undef RUBY_UNTYPED_DATA_WARNING -#define RUBY_UNTYPED_DATA_WARNING 0 - Data_Get_Struct(obj, rb_digest_metadata_t, algo); - - if (!algo) goto wrong; - switch (algo->api_version) { case 3: break; diff --git a/ext/digest/digest.h b/ext/digest/digest.h index 68a3da5dd2..4503929bab 100644 --- a/ext/digest/digest.h +++ b/ext/digest/digest.h @@ -64,10 +64,29 @@ rb_id_metadata(void) return rb_intern_const("metadata"); } +#if !defined(HAVE_RB_EXT_RESOLVE_SYMBOL) +#elif !defined(RUBY_UNTYPED_DATA_WARNING) +# error RUBY_UNTYPED_DATA_WARNING is not defined +#elif RUBY_UNTYPED_DATA_WARNING +/* rb_ext_resolve_symbol() has been defined since Ruby 3.3, but digest + * bundled with 3.3 didn't use it. */ +# define DIGEST_USE_RB_EXT_RESOLVE_SYMBOL 1 +#endif + static inline VALUE rb_digest_make_metadata(const rb_digest_metadata_t *meta) { +#ifdef DIGEST_USE_RB_EXT_RESOLVE_SYMBOL + typedef VALUE (*wrapper_func_type)(const rb_digest_metadata_t *meta); + static wrapper_func_type wrapper; + if (!wrapper) { + wrapper = (wrapper_func_type)rb_ext_resolve_symbol("digest.so", "rb_digest_wrap_metadata"); + if (!wrapper) rb_raise(rb_eLoadError, "rb_digest_wrap_metadata not found"); + } + return wrapper(meta); +#else #undef RUBY_UNTYPED_DATA_WARNING #define RUBY_UNTYPED_DATA_WARNING 0 return rb_obj_freeze(Data_Wrap_Struct(0, 0, 0, (void *)meta)); +#endif } diff --git a/ext/digest/md5/md5cc.h b/ext/digest/md5/md5cc.h index e34d7d5c11..0e7a58d2e0 100644 --- a/ext/digest/md5/md5cc.h +++ b/ext/digest/md5/md5cc.h @@ -1,8 +1,16 @@ #define COMMON_DIGEST_FOR_OPENSSL 1 #include <CommonCrypto/CommonDigest.h> -#ifdef __clang__ -# pragma clang diagnostic ignored "-Wdeprecated-declarations" +#ifdef __GNUC__ +# define RB_DIGEST_DIAGNOSTIC(compiler, op, flag) _Pragma(STRINGIZE(compiler diagnostic op flag)) +# ifdef RBIMPL_WARNING_IGNORED +# define RB_DIGEST_WARNING_IGNORED(flag) RBIMPL_WARNING_IGNORED(flag) +# elif defined(__clang__) +# define RB_DIGEST_WARNING_IGNORED(flag) RB_DIGEST_DIAGNOSTIC(clang, ignored, #flag) +# else /* __GNUC__ */ +# define RB_DIGEST_WARNING_IGNORED(flag) RB_DIGEST_DIAGNOSTIC(GCC, ignored, #flag) +# endif +RB_DIGEST_WARNING_IGNORED(-Wdeprecated-declarations) /* Suppress deprecation warnings of MD5 from Xcode 11.1 */ /* Although we know MD5 is deprecated too, provide just for backward * compatibility, as well as Apple does. */ |