diff options
Diffstat (limited to 'ext/digest/digest.h')
-rw-r--r-- | ext/digest/digest.h | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/ext/digest/digest.h b/ext/digest/digest.h index 0d4f0e7cc2..4503929bab 100644 --- a/ext/digest/digest.h +++ b/ext/digest/digest.h @@ -38,9 +38,10 @@ rb_digest_##name##_update(void *ctx, unsigned char *ptr, size_t size) \ const unsigned int stride = 16384; \ \ for (; size > stride; size -= stride, ptr += stride) { \ - name##_Update(ctx, ptr, stride); \ + name##_Update(ctx, ptr, stride); \ } \ - if (size > 0) name##_Update(ctx, ptr, size); \ + /* Since size <= stride, size should fit into an unsigned int */ \ + if (size > 0) name##_Update(ctx, ptr, (unsigned int)size); \ } #define DEFINE_FINISH_FUNC_FROM_FINAL(name) \ @@ -63,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 } |