summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/digest/digest.c21
-rwxr-xr-xtest/digest/test_digest.rb12
2 files changed, 27 insertions, 6 deletions
diff --git a/ext/digest/digest.c b/ext/digest/digest.c
index 2231452..c5e1ca5 100644
--- a/ext/digest/digest.c
+++ b/ext/digest/digest.c
@@ -535,6 +535,13 @@ get_digest_base_metadata(VALUE klass)
return algo;
}
+static const rb_data_type_t digest_type = {
+ "digest",
+ {0, RUBY_TYPED_DEFAULT_FREE, 0,},
+ NULL, NULL,
+ (RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED),
+};
+
static inline void
algo_init(const rb_digest_metadata_t *algo, void *pctx)
{
@@ -559,7 +566,7 @@ rb_digest_base_alloc(VALUE klass)
pctx = xmalloc(algo->ctx_size);
algo_init(algo, pctx);
- obj = Data_Wrap_Struct(klass, 0, xfree, pctx);
+ obj = TypedData_Wrap_Struct(klass, &digest_type, pctx);
return obj;
}
@@ -576,9 +583,11 @@ rb_digest_base_copy(VALUE copy, VALUE obj)
rb_check_frozen(copy);
algo = get_digest_base_metadata(rb_obj_class(copy));
+ if (algo != get_digest_base_metadata(rb_obj_class(obj)))
+ rb_raise(rb_eTypeError, "different algorithms");
- Data_Get_Struct(obj, void, pctx1);
- Data_Get_Struct(copy, void, pctx2);
+ TypedData_Get_Struct(obj, void, &digest_type, pctx1);
+ TypedData_Get_Struct(copy, void, &digest_type, pctx2);
memcpy(pctx2, pctx1, algo->ctx_size);
return copy;
@@ -593,7 +602,7 @@ rb_digest_base_reset(VALUE self)
algo = get_digest_base_metadata(rb_obj_class(self));
- Data_Get_Struct(self, void, pctx);
+ TypedData_Get_Struct(self, void, &digest_type, pctx);
algo_init(algo, pctx);
@@ -609,7 +618,7 @@ rb_digest_base_update(VALUE self, VALUE str)
algo = get_digest_base_metadata(rb_obj_class(self));
- Data_Get_Struct(self, void, pctx);
+ TypedData_Get_Struct(self, void, &digest_type, pctx);
StringValue(str);
algo->update_func(pctx, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str));
@@ -627,7 +636,7 @@ rb_digest_base_finish(VALUE self)
algo = get_digest_base_metadata(rb_obj_class(self));
- Data_Get_Struct(self, void, pctx);
+ TypedData_Get_Struct(self, void, &digest_type, pctx);
str = rb_str_new(0, algo->digest_len);
algo->finish_func(pctx, (unsigned char *)RSTRING_PTR(str));
diff --git a/test/digest/test_digest.rb b/test/digest/test_digest.rb
index cf541a4..6c0da46 100755
--- a/test/digest/test_digest.rb
+++ b/test/digest/test_digest.rb
@@ -198,4 +198,16 @@ module TestDigest
assert_raise(NotImplementedError, bug3810) {Digest::Base.new}
end
end
+
+ class TestInitCopy < Test::Unit::TestCase
+ if defined?(Digest::MD5) and defined?(Digest::RMD160)
+ def test_initialize_copy_md5_rmd160
+ assert_separately(%w[-rdigest], <<-'end;')
+ md5 = Digest::MD5.allocate
+ rmd160 = Digest::RMD160.allocate
+ assert_raise(TypeError) {md5.__send__(:initialize_copy, rmd160)}
+ end;
+ end
+ end
+ end
end