rubysl-digest 2.0.3 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -10
  3. data/MRI_LICENSE +56 -0
  4. data/ext/rubysl/digest/bubblebabble/bubblebabble.c +27 -28
  5. data/ext/rubysl/digest/defs.h +1 -1
  6. data/ext/rubysl/digest/digest.c +142 -58
  7. data/ext/rubysl/digest/digest.h +25 -5
  8. data/ext/rubysl/digest/digest_conf.rb +28 -0
  9. data/ext/rubysl/digest/extconf.rb +1 -1
  10. data/ext/rubysl/digest/md5/extconf.rb +3 -13
  11. data/ext/rubysl/digest/md5/md5.c +9 -7
  12. data/ext/rubysl/digest/md5/md5.h +3 -3
  13. data/ext/rubysl/digest/md5/md5cc.h +12 -0
  14. data/ext/rubysl/digest/md5/md5init.c +12 -5
  15. data/ext/rubysl/digest/md5/md5ossl.h +4 -2
  16. data/ext/rubysl/digest/rmd160/extconf.rb +3 -12
  17. data/ext/rubysl/digest/rmd160/rmd160.c +12 -6
  18. data/ext/rubysl/digest/rmd160/rmd160.h +3 -3
  19. data/ext/rubysl/digest/rmd160/rmd160init.c +10 -5
  20. data/ext/rubysl/digest/rmd160/rmd160ossl.h +3 -2
  21. data/ext/rubysl/digest/sha1/extconf.rb +3 -12
  22. data/ext/rubysl/digest/sha1/sha1.c +5 -3
  23. data/ext/rubysl/digest/sha1/sha1.h +3 -3
  24. data/ext/rubysl/digest/sha1/sha1cc.h +14 -0
  25. data/ext/rubysl/digest/sha1/sha1init.c +12 -5
  26. data/ext/rubysl/digest/sha1/sha1ossl.h +4 -2
  27. data/ext/rubysl/digest/sha2/extconf.rb +7 -8
  28. data/ext/rubysl/digest/sha2/sha2.c +235 -73
  29. data/ext/rubysl/digest/sha2/sha2.h +142 -26
  30. data/ext/rubysl/digest/sha2/sha2cc.h +31 -0
  31. data/ext/rubysl/digest/sha2/sha2init.c +12 -4
  32. data/ext/rubysl/digest/sha2/sha2ossl.h +27 -0
  33. data/ext/rubysl/openssl/deprecation.rb +21 -0
  34. data/lib/digest/sha2.rb +42 -9
  35. data/lib/rubysl/digest/digest.rb +27 -7
  36. data/lib/rubysl/digest/version.rb +1 -1
  37. data/spec/fixtures/dir/common.rb +171 -0
  38. data/spec/md5/file_spec.rb +1 -1
  39. data/spec/sha1/file_spec.rb +1 -1
  40. data/spec/sha256/file_spec.rb +1 -1
  41. data/spec/sha384/file_spec.rb +1 -1
  42. data/spec/sha512/file_spec.rb +1 -1
  43. data/spec/shared/file/read.rb +21 -0
  44. metadata +15 -5
  45. data/ext/rubysl/digest/bubblebabble/depend +0 -3
  46. data/ext/rubysl/digest/bubblebabble/extconf.h +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65359f4d44e5214c1792c18bd005f743429b0dff
4
- data.tar.gz: 50f9dbd5c3316dd98bd1fb3cd592e9a80a7b8a4a
3
+ metadata.gz: 3b2b09fcc999edcc21062d1bb6b315a648d2ec69
4
+ data.tar.gz: b6bb606c58f98c87e6f6aa54ee829df248818f79
5
5
  SHA512:
6
- metadata.gz: 527c4cb678c0158c8452ebacd7cc79592c849c172d5c38e7f57da02578d2de06599ee64d569d8077f8499b9d7148dbd526e6671d053e7659bd4a187df7a6d7de
7
- data.tar.gz: cf84d9af3b548d219abca59aec69aaada07740d7f0b0418db9cc446658b3aa401a8ca497e637ffaa9bf87756cf0545da36fa8b1e78ab278cfb747639a1c65362
6
+ metadata.gz: a3d383f9991ea080439f217e3e56bca326a7cf97afafe750c6ef976029d778c06cc239defaea84376f89d332a2560c2f51f4944294149a2722940130f51a495f
7
+ data.tar.gz: c38362f21f604d9e5a13279966588c4fc7b360c3ba4fcc8b60a0e2297888b48939f55fd8527bbbb960cb8ad94e82a5bdf7b108ee2b10846f642035171b7dc373
data/.travis.yml CHANGED
@@ -1,14 +1,12 @@
1
1
  language: ruby
2
2
  env:
3
- - RUBYLIB=lib
4
- - RUBYLIB=
3
+ - RUBYLIB=lib:.
5
4
  script: mspec spec
5
+ branches:
6
+ only:
7
+ - 1.0
8
+ - 2.0
6
9
  rvm:
7
- - 2.0.0
8
- - rbx-2.1.1
9
- matrix:
10
- exclude:
11
- - rvm: 2.0.0
12
- env: RUBYLIB=lib
13
- - rvm: rbx-2.1.1
14
- env: RUBYLIB=
10
+ - 2.1.0
11
+ - rbx-2
12
+
data/MRI_LICENSE ADDED
@@ -0,0 +1,56 @@
1
+ Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
2
+ You can redistribute it and/or modify it under either the terms of the
3
+ 2-clause BSDL (see the file BSDL), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) give non-standard binaries non-standard names, with
21
+ instructions on where to get the original software distribution.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or binary form,
26
+ provided that you do at least ONE of the following:
27
+
28
+ a) distribute the binaries and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c) give non-standard binaries non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under these terms.
43
+
44
+ For the list of those files and their copying conditions, see the
45
+ file LEGAL.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
@@ -2,16 +2,17 @@
2
2
 
3
3
  bubblebabble.c - BubbleBabble encoding support
4
4
 
5
- $Author: shyouhei $
5
+ $Author$
6
6
  created at: Fri Oct 13 18:31:42 JST 2006
7
7
 
8
8
  Copyright (C) 2006 Akinori MUSHA
9
9
 
10
- $Id: bubblebabble.c 11708 2007-02-12 23:01:19Z shyouhei $
10
+ $Id$
11
11
 
12
12
  ************************************************/
13
13
 
14
- #include "bubblebabble.h"
14
+ #include "ruby.h"
15
+ #include "digest.h"
15
16
 
16
17
  static ID id_digest;
17
18
 
@@ -22,9 +23,7 @@ bubblebabble_str_new(VALUE str_digest)
22
23
  size_t digest_len;
23
24
  VALUE str;
24
25
  char *p;
25
- char *buf;
26
- int buf_len;
27
- int i, j, seed = 1;
26
+ size_t i, j, seed = 1;
28
27
  static const char vowels[] = {
29
28
  'a', 'e', 'i', 'o', 'u', 'y'
30
29
  };
@@ -34,16 +33,15 @@ bubblebabble_str_new(VALUE str_digest)
34
33
  };
35
34
 
36
35
  StringValue(str_digest);
36
+ digest = RSTRING_PTR(str_digest);
37
37
  digest_len = RSTRING_LEN(str_digest);
38
38
 
39
39
  if ((LONG_MAX - 2) / 3 < (digest_len | 1)) {
40
- rb_raise(rb_eRuntimeError, "digest string too long");
40
+ rb_raise(rb_eRuntimeError, "digest string too long");
41
41
  }
42
42
 
43
- digest = rb_str_ptr_readonly(str_digest);
44
- buf_len = (digest_len | 1) * 3 + 2;
45
- buf = calloc(buf_len, sizeof(char));
46
- p = buf;
43
+ str = rb_str_new(0, (digest_len | 1) * 3 + 2);
44
+ p = RSTRING_PTR(str);
47
45
 
48
46
  i = j = 0;
49
47
  p[j++] = 'x';
@@ -77,13 +75,11 @@ bubblebabble_str_new(VALUE str_digest)
77
75
 
78
76
  p[j] = 'x';
79
77
 
80
- str = rb_str_new(buf, buf_len);
81
- free(buf);
82
-
83
78
  return str;
84
79
  }
85
80
 
86
- /*
81
+ /* Document-method: Digest::bubblebabble
82
+ *
87
83
  * call-seq:
88
84
  * Digest.bubblebabble(string) -> bubblebabble_string
89
85
  *
@@ -95,7 +91,8 @@ rb_digest_s_bubblebabble(VALUE klass, VALUE str)
95
91
  return bubblebabble_str_new(str);
96
92
  }
97
93
 
98
- /*
94
+ /* Document-method: Digest::Class::bubblebabble
95
+ *
99
96
  * call-seq:
100
97
  * Digest::Class.bubblebabble(string, ...) -> hash_string
101
98
  *
@@ -107,7 +104,8 @@ rb_digest_class_s_bubblebabble(int argc, VALUE *argv, VALUE klass)
107
104
  return bubblebabble_str_new(rb_funcall2(klass, id_digest, argc, argv));
108
105
  }
109
106
 
110
- /*
107
+ /* Document-method: Digest::Instance#bubblebabble
108
+ *
111
109
  * call-seq:
112
110
  * digest_obj.bubblebabble -> hash_string
113
111
  *
@@ -126,20 +124,21 @@ rb_digest_instance_bubblebabble(VALUE self)
126
124
  void
127
125
  Init_bubblebabble(void)
128
126
  {
129
- VALUE mDigest, mDigest_Instance, cDigest_Class;
130
-
131
- mDigest = rb_path2class("Digest");
132
- mDigest_Instance = rb_path2class("Digest::Instance");
133
- cDigest_Class = rb_path2class("Digest::Class");
127
+ VALUE rb_mDigest, rb_mDigest_Instance, rb_cDigest_Class;
134
128
 
135
- /* Digest::bubblebabble() */
136
- rb_define_module_function(mDigest, "bubblebabble", rb_digest_s_bubblebabble, 1);
129
+ rb_mDigest = rb_path2class("Digest");
130
+ rb_mDigest_Instance = rb_path2class("Digest::Instance");
131
+ rb_cDigest_Class = rb_path2class("Digest::Class");
137
132
 
138
- /* Digest::Class::bubblebabble() */
139
- rb_define_singleton_method(cDigest_Class, "bubblebabble", rb_digest_class_s_bubblebabble, -1);
133
+ #if 0
134
+ rb_mDigest = rb_define_module("Digest");
135
+ rb_mDigest_Instance = rb_define_module_under(rb_mDigest, "Instance");
136
+ rb_cDigest_Class = rb_define_class_under(rb_mDigest, "Class", rb_cObject);
137
+ #endif
140
138
 
141
- /* Digest::Instance#bubblebabble() */
142
- rb_define_method(mDigest_Instance, "bubblebabble", rb_digest_instance_bubblebabble, 0);
139
+ rb_define_module_function(rb_mDigest, "bubblebabble", rb_digest_s_bubblebabble, 1);
140
+ rb_define_singleton_method(rb_cDigest_Class, "bubblebabble", rb_digest_class_s_bubblebabble, -1);
141
+ rb_define_method(rb_mDigest_Instance, "bubblebabble", rb_digest_instance_bubblebabble, 0);
143
142
 
144
143
  id_digest = rb_intern("digest");
145
144
  }
@@ -1,5 +1,5 @@
1
1
  /* -*- C -*-
2
- * $Id: defs.h 15780 2008-03-14 08:04:45Z nobu $
2
+ * $Id$
3
3
  */
4
4
 
5
5
  #ifndef DEFS_H
@@ -2,22 +2,19 @@
2
2
 
3
3
  digest.c -
4
4
 
5
- $Author: shyouhei $
5
+ $Author$
6
6
  created at: Fri May 25 08:57:27 JST 2001
7
7
 
8
8
  Copyright (C) 1995-2001 Yukihiro Matsumoto
9
9
  Copyright (C) 2001-2006 Akinori MUSHA
10
10
 
11
11
  $RoughId: digest.c,v 1.16 2001/07/13 15:38:27 knu Exp $
12
- $Id: digest.c 17775 2008-07-01 10:36:22Z shyouhei $
12
+ $Id$
13
13
 
14
14
  ************************************************/
15
15
 
16
16
  #include "digest.h"
17
17
 
18
- #include <string.h>
19
- #include <stdlib.h>
20
-
21
18
  static VALUE rb_mDigest;
22
19
  static VALUE rb_mDigest_Instance;
23
20
  static VALUE rb_cDigest_Class;
@@ -32,6 +29,69 @@ RUBY_EXTERN void Init_digest_base(void);
32
29
  * Document-module: Digest
33
30
  *
34
31
  * This module provides a framework for message digest libraries.
32
+ *
33
+ * You may want to look at OpenSSL::Digest as it supports more algorithms.
34
+ *
35
+ * A cryptographic hash function is a procedure that takes data and returns a
36
+ * fixed bit string: the hash value, also known as _digest_. Hash functions
37
+ * are also called one-way functions, it is easy to compute a digest from
38
+ * a message, but it is infeasible to generate a message from a digest.
39
+ *
40
+ * == Examples
41
+ *
42
+ * require 'digest'
43
+ *
44
+ * # Compute a complete digest
45
+ * Digest::SHA256.digest 'message' #=> "\xABS\n\x13\xE4Y..."
46
+ *
47
+ * sha256 = Digest::SHA256.new
48
+ * sha256.digest 'message' #=> "\xABS\n\x13\xE4Y..."
49
+ *
50
+ * # Other encoding formats
51
+ * Digest::SHA256.hexdigest 'message' #=> "ab530a13e459..."
52
+ * Digest::SHA256.base64digest 'message' #=> "q1MKE+RZFJgr..."
53
+ *
54
+ * # Compute digest by chunks
55
+ * md5 = Digest::MD5.new
56
+ * md5.update 'message1'
57
+ * md5 << 'message2' # << is an alias for update
58
+ *
59
+ * md5.hexdigest #=> "94af09c09bb9..."
60
+ *
61
+ * # Compute digest for a file
62
+ * sha256 = Digest::SHA256.file 'testfile'
63
+ * sha256.hexdigest
64
+ *
65
+ * Additionally digests can be encoded in "bubble babble" format as a sequence
66
+ * of consonants and vowels which is more recognizable and comparable than a
67
+ * hexadecimal digest.
68
+ *
69
+ * require 'digest/bubblebabble'
70
+ *
71
+ * Digest::SHA256.bubblebabble 'message' #=> "xopoh-fedac-fenyh-..."
72
+ *
73
+ * See the bubble babble specification at
74
+ * http://web.mit.edu/kenta/www/one/bubblebabble/spec/jrtrjwzi/draft-huima-01.txt.
75
+ *
76
+ * == Digest algorithms
77
+ *
78
+ * Different digest algorithms (or hash functions) are available:
79
+ *
80
+ * HMAC::
81
+ * See FIPS PUB 198 The Keyed-Hash Message Authentication Code (HMAC).
82
+ * RIPEMD-160::
83
+ * As Digest::RMD160.
84
+ * See http://homes.esat.kuleuven.be/~bosselae/ripemd160.html.
85
+ * SHA1::
86
+ * See FIPS 180 Secure Hash Standard.
87
+ * SHA2 family::
88
+ * See FIPS 180 Secure Hash Standard which defines the following algorithms:
89
+ * * SHA512
90
+ * * SHA384
91
+ * * SHA256
92
+ *
93
+ * The latest versions of the FIPS publications can be found here:
94
+ * http://csrc.nist.gov/publications/PubsFIPS.html.
35
95
  */
36
96
 
37
97
  static VALUE
@@ -39,34 +99,31 @@ hexencode_str_new(VALUE str_digest)
39
99
  {
40
100
  char *digest;
41
101
  size_t digest_len;
42
- int i;
102
+ size_t i;
43
103
  VALUE str;
44
104
  char *p;
45
- char *buf;
46
105
  static const char hex[] = {
47
106
  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
48
107
  'a', 'b', 'c', 'd', 'e', 'f'
49
108
  };
50
109
 
51
110
  StringValue(str_digest);
111
+ digest = RSTRING_PTR(str_digest);
52
112
  digest_len = RSTRING_LEN(str_digest);
53
113
 
54
114
  if (LONG_MAX / 2 < digest_len) {
55
115
  rb_raise(rb_eRuntimeError, "digest string too long");
56
116
  }
57
117
 
58
- digest = rb_str_ptr_readonly(str_digest);
59
- buf = calloc(digest_len * 2, sizeof(char));
118
+ str = rb_usascii_str_new(0, digest_len * 2);
60
119
 
61
- for (i = 0, p = buf; i < digest_len; i++) {
120
+ for (i = 0, p = RSTRING_PTR(str); i < digest_len; i++) {
62
121
  unsigned char byte = digest[i];
63
122
 
64
123
  p[i + i] = hex[byte >> 4];
65
124
  p[i + i + 1] = hex[byte & 0x0f];
66
125
  }
67
126
 
68
- str = rb_str_new(buf, digest_len * 2);
69
- free(buf);
70
127
  return str;
71
128
  }
72
129
 
@@ -82,6 +139,8 @@ rb_digest_s_hexencode(VALUE klass, VALUE str)
82
139
  return hexencode_str_new(str);
83
140
  }
84
141
 
142
+ NORETURN(static void rb_digest_instance_method_unimpl(VALUE self, const char *method));
143
+
85
144
  /*
86
145
  * Document-module: Digest::Instance
87
146
  *
@@ -89,6 +148,13 @@ rb_digest_s_hexencode(VALUE klass, VALUE str)
89
148
  * object to calculate message digest values.
90
149
  */
91
150
 
151
+ static void
152
+ rb_digest_instance_method_unimpl(VALUE self, const char *method)
153
+ {
154
+ rb_raise(rb_eRuntimeError, "%s does not implement %s()",
155
+ rb_obj_classname(self), method);
156
+ }
157
+
92
158
  /*
93
159
  * call-seq:
94
160
  * digest_obj.update(string) -> digest_obj
@@ -103,9 +169,9 @@ rb_digest_s_hexencode(VALUE klass, VALUE str)
103
169
  static VALUE
104
170
  rb_digest_instance_update(VALUE self, VALUE str)
105
171
  {
106
- rb_raise(rb_eRuntimeError, "%s does not implement update()",
107
- rb_str_ptr_readonly(rb_inspect(self)));
108
- return Qnil; /* Keep compiler happy */
172
+ rb_digest_instance_method_unimpl(self, "update");
173
+
174
+ UNREACHABLE;
109
175
  }
110
176
 
111
177
  /*
@@ -123,9 +189,9 @@ rb_digest_instance_update(VALUE self, VALUE str)
123
189
  static VALUE
124
190
  rb_digest_instance_finish(VALUE self)
125
191
  {
126
- rb_raise(rb_eRuntimeError, "%s does not implement finish()",
127
- rb_str_ptr_readonly(rb_inspect(self)));
128
- return Qnil; /* Keep compiler happy */
192
+ rb_digest_instance_method_unimpl(self, "finish");
193
+
194
+ UNREACHABLE;
129
195
  }
130
196
 
131
197
  /*
@@ -139,9 +205,9 @@ rb_digest_instance_finish(VALUE self)
139
205
  static VALUE
140
206
  rb_digest_instance_reset(VALUE self)
141
207
  {
142
- rb_raise(rb_eRuntimeError, "%s does not implement reset()",
143
- rb_str_ptr_readonly(rb_inspect(self)));
144
- return Qnil; /* Keep compiler happy */
208
+ rb_digest_instance_method_unimpl(self, "reset");
209
+
210
+ UNREACHABLE;
145
211
  }
146
212
 
147
213
  /*
@@ -182,10 +248,7 @@ rb_digest_instance_digest(int argc, VALUE *argv, VALUE self)
182
248
  value = rb_funcall(self, id_finish, 0);
183
249
  rb_funcall(self, id_reset, 0);
184
250
  } else {
185
- VALUE clone = rb_obj_clone(self);
186
-
187
- value = rb_funcall(clone, id_finish, 0);
188
- rb_funcall(clone, id_reset, 0);
251
+ value = rb_funcall(rb_obj_clone(self), id_finish, 0);
189
252
  }
190
253
 
191
254
  return value;
@@ -230,10 +293,7 @@ rb_digest_instance_hexdigest(int argc, VALUE *argv, VALUE self)
230
293
  value = rb_funcall(self, id_finish, 0);
231
294
  rb_funcall(self, id_reset, 0);
232
295
  } else {
233
- VALUE clone = rb_obj_clone(self);
234
-
235
- value = rb_funcall(clone, id_finish, 0);
236
- rb_funcall(clone, id_reset, 0);
296
+ value = rb_funcall(rb_obj_clone(self), id_finish, 0);
237
297
  }
238
298
 
239
299
  return hexencode_str_new(value);
@@ -243,8 +303,8 @@ rb_digest_instance_hexdigest(int argc, VALUE *argv, VALUE self)
243
303
  * call-seq:
244
304
  * digest_obj.hexdigest! -> string
245
305
  *
246
- * Returns the resulting hash value and resets the digest to the
247
- * initial state.
306
+ * Returns the resulting hash value in a hex-encoded form and resets
307
+ * the digest to the initial state.
248
308
  */
249
309
  static VALUE
250
310
  rb_digest_instance_hexdigest_bang(VALUE self)
@@ -312,7 +372,8 @@ rb_digest_instance_equal(VALUE self, VALUE other)
312
372
  str2 = rb_digest_instance_digest(0, 0, other);
313
373
  } else {
314
374
  str1 = rb_digest_instance_to_s(self);
315
- str2 = other;
375
+ str2 = rb_check_string_type(other);
376
+ if (NIL_P(str2)) return Qfalse;
316
377
  }
317
378
 
318
379
  /* never blindly assume that subclass methods return strings */
@@ -320,8 +381,8 @@ rb_digest_instance_equal(VALUE self, VALUE other)
320
381
  StringValue(str2);
321
382
 
322
383
  if (RSTRING_LEN(str1) == RSTRING_LEN(str2) &&
323
- rb_str_cmp(str1, str2) == 0) {
324
- return Qtrue;
384
+ rb_str_cmp(str1, str2) == 0) {
385
+ return Qtrue;
325
386
  }
326
387
  return Qfalse;
327
388
  }
@@ -370,9 +431,9 @@ rb_digest_instance_length(VALUE self)
370
431
  static VALUE
371
432
  rb_digest_instance_block_length(VALUE self)
372
433
  {
373
- rb_raise(rb_eRuntimeError, "%s does not implement block_length()",
374
- rb_str_ptr_readonly(rb_inspect(self)));
375
- return Qnil; /* Keep compiler happy */
434
+ rb_digest_instance_method_unimpl(self, "block_length");
435
+
436
+ UNREACHABLE;
376
437
  }
377
438
 
378
439
  /*
@@ -426,6 +487,13 @@ rb_digest_class_s_hexdigest(int argc, VALUE *argv, VALUE klass)
426
487
  return hexencode_str_new(rb_funcall2(klass, id_digest, argc, argv));
427
488
  }
428
489
 
490
+ /* :nodoc: */
491
+ static VALUE
492
+ rb_digest_class_init(VALUE self)
493
+ {
494
+ return self;
495
+ }
496
+
429
497
  /*
430
498
  * Document-class: Digest::Base
431
499
  *
@@ -437,23 +505,25 @@ static rb_digest_metadata_t *
437
505
  get_digest_base_metadata(VALUE klass)
438
506
  {
439
507
  VALUE p;
440
- VALUE obj = 0;
508
+ VALUE obj;
441
509
  rb_digest_metadata_t *algo;
442
510
 
443
- for (p = klass; p; p = RCLASS_SUPER(p)) {
511
+ for (p = klass; !NIL_P(p); p = rb_class_superclass(p)) {
444
512
  if (rb_ivar_defined(p, id_metadata)) {
445
513
  obj = rb_ivar_get(p, id_metadata);
446
514
  break;
447
515
  }
448
516
  }
449
517
 
450
- if (!p)
518
+ if (NIL_P(p))
451
519
  rb_raise(rb_eRuntimeError, "Digest::Base cannot be directly inherited in Ruby");
452
520
 
521
+ #undef RUBY_UNTYPED_DATA_WARNING
522
+ #define RUBY_UNTYPED_DATA_WARNING 0
453
523
  Data_Get_Struct(obj, rb_digest_metadata_t, algo);
454
524
 
455
525
  switch (algo->api_version) {
456
- case 2:
526
+ case 3:
457
527
  break;
458
528
 
459
529
  /*
@@ -467,6 +537,21 @@ get_digest_base_metadata(VALUE klass)
467
537
  return algo;
468
538
  }
469
539
 
540
+ static const rb_data_type_t digest_type = {
541
+ "digest",
542
+ {0, RUBY_TYPED_DEFAULT_FREE, 0,},
543
+ 0, 0,
544
+ (RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED),
545
+ };
546
+
547
+ static inline void
548
+ algo_init(const rb_digest_metadata_t *algo, void *pctx)
549
+ {
550
+ if (algo->init_func(pctx) != 1) {
551
+ rb_raise(rb_eRuntimeError, "Digest initialization failed.");
552
+ }
553
+ }
554
+
470
555
  static VALUE
471
556
  rb_digest_base_alloc(VALUE klass)
472
557
  {
@@ -475,15 +560,15 @@ rb_digest_base_alloc(VALUE klass)
475
560
  void *pctx;
476
561
 
477
562
  if (klass == rb_cDigest_Base) {
478
- rb_raise(rb_eNotImpError, "Digest::Base is an abstract class");
563
+ rb_raise(rb_eNotImpError, "Digest::Base is an abstract class");
479
564
  }
480
565
 
481
566
  algo = get_digest_base_metadata(klass);
482
567
 
483
568
  pctx = xmalloc(algo->ctx_size);
484
- algo->init_func(pctx);
569
+ algo_init(algo, pctx);
485
570
 
486
- obj = Data_Wrap_Struct(klass, 0, xfree, pctx);
571
+ obj = TypedData_Wrap_Struct(klass, &digest_type, pctx);
487
572
 
488
573
  return obj;
489
574
  }
@@ -500,9 +585,11 @@ rb_digest_base_copy(VALUE copy, VALUE obj)
500
585
  rb_check_frozen(copy);
501
586
 
502
587
  algo = get_digest_base_metadata(rb_obj_class(copy));
588
+ if (algo != get_digest_base_metadata(rb_obj_class(obj)))
589
+ rb_raise(rb_eTypeError, "different algorithms");
503
590
 
504
- Data_Get_Struct(obj, void, pctx1);
505
- Data_Get_Struct(copy, void, pctx2);
591
+ TypedData_Get_Struct(obj, void, &digest_type, pctx1);
592
+ TypedData_Get_Struct(copy, void, &digest_type, pctx2);
506
593
  memcpy(pctx2, pctx1, algo->ctx_size);
507
594
 
508
595
  return copy;
@@ -517,9 +604,9 @@ rb_digest_base_reset(VALUE self)
517
604
 
518
605
  algo = get_digest_base_metadata(rb_obj_class(self));
519
606
 
520
- Data_Get_Struct(self, void, pctx);
607
+ TypedData_Get_Struct(self, void, &digest_type, pctx);
521
608
 
522
- algo->init_func(pctx);
609
+ algo_init(algo, pctx);
523
610
 
524
611
  return self;
525
612
  }
@@ -533,10 +620,10 @@ rb_digest_base_update(VALUE self, VALUE str)
533
620
 
534
621
  algo = get_digest_base_metadata(rb_obj_class(self));
535
622
 
536
- Data_Get_Struct(self, void, pctx);
623
+ TypedData_Get_Struct(self, void, &digest_type, pctx);
537
624
 
538
625
  StringValue(str);
539
- algo->update_func(pctx, (unsigned char *)rb_str_ptr_readonly(str), RSTRING_LEN(str));
626
+ algo->update_func(pctx, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str));
540
627
 
541
628
  return self;
542
629
  }
@@ -551,17 +638,13 @@ rb_digest_base_finish(VALUE self)
551
638
 
552
639
  algo = get_digest_base_metadata(rb_obj_class(self));
553
640
 
554
- Data_Get_Struct(self, void, pctx);
641
+ TypedData_Get_Struct(self, void, &digest_type, pctx);
555
642
 
556
- char* buf = calloc(algo->digest_len, sizeof(char));
557
-
558
- algo->finish_func(pctx, (unsigned char*)buf);
643
+ str = rb_str_new(0, algo->digest_len);
644
+ algo->finish_func(pctx, (unsigned char *)RSTRING_PTR(str));
559
645
 
560
646
  /* avoid potential coredump caused by use of a finished context */
561
- algo->init_func(pctx);
562
-
563
- str = rb_str_new(buf, algo->digest_len);
564
- free(buf);
647
+ algo_init(algo, pctx);
565
648
 
566
649
  return str;
567
650
  }
@@ -637,6 +720,7 @@ Init_digest(void)
637
720
  * class Digest::Class
638
721
  */
639
722
  rb_cDigest_Class = rb_define_class_under(rb_mDigest, "Class", rb_cObject);
723
+ rb_define_method(rb_cDigest_Class, "initialize", rb_digest_class_init, 0);
640
724
  rb_include_module(rb_cDigest_Class, rb_mDigest_Instance);
641
725
 
642
726
  /* class methods */