rubysl-digest 2.0.3 → 2.0.7

Sign up to get free protection for your applications and to get access to all the features.
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 */