Ruby  2.5.0dev(2017-10-22revision60238)
digest.c
Go to the documentation of this file.
1 /************************************************
2 
3  digest.c -
4 
5  $Author$
6  created at: Fri May 25 08:57:27 JST 2001
7 
8  Copyright (C) 1995-2001 Yukihiro Matsumoto
9  Copyright (C) 2001-2006 Akinori MUSHA
10 
11  $RoughId: digest.c,v 1.16 2001/07/13 15:38:27 knu Exp $
12  $Id$
13 
14 ************************************************/
15 
16 #include "digest.h"
17 
18 static VALUE rb_mDigest;
19 static VALUE rb_mDigest_Instance;
20 static VALUE rb_cDigest_Class;
21 static VALUE rb_cDigest_Base;
22 
23 static ID id_reset, id_update, id_finish, id_digest, id_hexdigest, id_digest_length;
24 static ID id_metadata;
25 
26 RUBY_EXTERN void Init_digest_base(void);
27 
28 /*
29  * Document-module: Digest
30  *
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  * MD5::
81  * See RFC 1321 The MD5 Message-Digest Algorithm
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.
95  */
96 
97 static VALUE
98 hexencode_str_new(VALUE str_digest)
99 {
100  char *digest;
101  size_t digest_len;
102  size_t i;
103  VALUE str;
104  char *p;
105  static const char hex[] = {
106  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
107  'a', 'b', 'c', 'd', 'e', 'f'
108  };
109 
110  StringValue(str_digest);
111  digest = RSTRING_PTR(str_digest);
112  digest_len = RSTRING_LEN(str_digest);
113 
114  if (LONG_MAX / 2 < digest_len) {
115  rb_raise(rb_eRuntimeError, "digest string too long");
116  }
117 
118  str = rb_usascii_str_new(0, digest_len * 2);
119 
120  for (i = 0, p = RSTRING_PTR(str); i < digest_len; i++) {
121  unsigned char byte = digest[i];
122 
123  p[i + i] = hex[byte >> 4];
124  p[i + i + 1] = hex[byte & 0x0f];
125  }
126 
127  RB_GC_GUARD(str_digest);
128 
129  return str;
130 }
131 
132 /*
133  * call-seq:
134  * Digest.hexencode(string) -> hexencoded_string
135  *
136  * Generates a hex-encoded version of a given _string_.
137  */
138 static VALUE
139 rb_digest_s_hexencode(VALUE klass, VALUE str)
140 {
141  return hexencode_str_new(str);
142 }
143 
144 NORETURN(static void rb_digest_instance_method_unimpl(VALUE self, const char *method));
145 
146 /*
147  * Document-module: Digest::Instance
148  *
149  * This module provides instance methods for a digest implementation
150  * object to calculate message digest values.
151  */
152 
153 static void
154 rb_digest_instance_method_unimpl(VALUE self, const char *method)
155 {
156  rb_raise(rb_eRuntimeError, "%s does not implement %s()",
157  rb_obj_classname(self), method);
158 }
159 
160 /*
161  * call-seq:
162  * digest_obj.update(string) -> digest_obj
163  * digest_obj << string -> digest_obj
164  *
165  * Updates the digest using a given _string_ and returns self.
166  *
167  * The update() method and the left-shift operator are overridden by
168  * each implementation subclass. (One should be an alias for the
169  * other)
170  */
171 static VALUE
172 rb_digest_instance_update(VALUE self, VALUE str)
173 {
174  rb_digest_instance_method_unimpl(self, "update");
175 
176  UNREACHABLE;
177 }
178 
179 /*
180  * call-seq:
181  * digest_obj.instance_eval { finish } -> digest_obj
182  *
183  * Finishes the digest and returns the resulting hash value.
184  *
185  * This method is overridden by each implementation subclass and often
186  * made private, because some of those subclasses may leave internal
187  * data uninitialized. Do not call this method from outside. Use
188  * #digest!() instead, which ensures that internal data be reset for
189  * security reasons.
190  */
191 static VALUE
192 rb_digest_instance_finish(VALUE self)
193 {
194  rb_digest_instance_method_unimpl(self, "finish");
195 
196  UNREACHABLE;
197 }
198 
199 /*
200  * call-seq:
201  * digest_obj.reset -> digest_obj
202  *
203  * Resets the digest to the initial state and returns self.
204  *
205  * This method is overridden by each implementation subclass.
206  */
207 static VALUE
208 rb_digest_instance_reset(VALUE self)
209 {
210  rb_digest_instance_method_unimpl(self, "reset");
211 
212  UNREACHABLE;
213 }
214 
215 /*
216  * call-seq:
217  * digest_obj.new -> another_digest_obj
218  *
219  * Returns a new, initialized copy of the digest object. Equivalent
220  * to digest_obj.clone().reset().
221  */
222 static VALUE
223 rb_digest_instance_new(VALUE self)
224 {
225  VALUE clone = rb_obj_clone(self);
226  rb_funcall(clone, id_reset, 0);
227  return clone;
228 }
229 
230 /*
231  * call-seq:
232  * digest_obj.digest -> string
233  * digest_obj.digest(string) -> string
234  *
235  * If none is given, returns the resulting hash value of the digest,
236  * keeping the digest's state.
237  *
238  * If a _string_ is given, returns the hash value for the given
239  * _string_, resetting the digest to the initial state before and
240  * after the process.
241  */
242 static VALUE
243 rb_digest_instance_digest(int argc, VALUE *argv, VALUE self)
244 {
245  VALUE str, value;
246 
247  if (rb_scan_args(argc, argv, "01", &str) > 0) {
248  rb_funcall(self, id_reset, 0);
249  rb_funcall(self, id_update, 1, str);
250  value = rb_funcall(self, id_finish, 0);
251  rb_funcall(self, id_reset, 0);
252  } else {
253  value = rb_funcall(rb_obj_clone(self), id_finish, 0);
254  }
255 
256  return value;
257 }
258 
259 /*
260  * call-seq:
261  * digest_obj.digest! -> string
262  *
263  * Returns the resulting hash value and resets the digest to the
264  * initial state.
265  */
266 static VALUE
267 rb_digest_instance_digest_bang(VALUE self)
268 {
269  VALUE value = rb_funcall(self, id_finish, 0);
270  rb_funcall(self, id_reset, 0);
271 
272  return value;
273 }
274 
275 /*
276  * call-seq:
277  * digest_obj.hexdigest -> string
278  * digest_obj.hexdigest(string) -> string
279  *
280  * If none is given, returns the resulting hash value of the digest in
281  * a hex-encoded form, keeping the digest's state.
282  *
283  * If a _string_ is given, returns the hash value for the given
284  * _string_ in a hex-encoded form, resetting the digest to the initial
285  * state before and after the process.
286  */
287 static VALUE
288 rb_digest_instance_hexdigest(int argc, VALUE *argv, VALUE self)
289 {
290  VALUE str, value;
291 
292  if (rb_scan_args(argc, argv, "01", &str) > 0) {
293  rb_funcall(self, id_reset, 0);
294  rb_funcall(self, id_update, 1, str);
295  value = rb_funcall(self, id_finish, 0);
296  rb_funcall(self, id_reset, 0);
297  } else {
298  value = rb_funcall(rb_obj_clone(self), id_finish, 0);
299  }
300 
301  return hexencode_str_new(value);
302 }
303 
304 /*
305  * call-seq:
306  * digest_obj.hexdigest! -> string
307  *
308  * Returns the resulting hash value in a hex-encoded form and resets
309  * the digest to the initial state.
310  */
311 static VALUE
312 rb_digest_instance_hexdigest_bang(VALUE self)
313 {
314  VALUE value = rb_funcall(self, id_finish, 0);
315  rb_funcall(self, id_reset, 0);
316 
317  return hexencode_str_new(value);
318 }
319 
320 /*
321  * call-seq:
322  * digest_obj.to_s -> string
323  *
324  * Returns digest_obj.hexdigest().
325  */
326 static VALUE
327 rb_digest_instance_to_s(VALUE self)
328 {
329  return rb_funcall(self, id_hexdigest, 0);
330 }
331 
332 /*
333  * call-seq:
334  * digest_obj.inspect -> string
335  *
336  * Creates a printable version of the digest object.
337  */
338 static VALUE
339 rb_digest_instance_inspect(VALUE self)
340 {
341  VALUE str;
342  size_t digest_len = 32; /* about this size at least */
343  const char *cname;
344 
345  cname = rb_obj_classname(self);
346 
347  /* #<Digest::ClassName: xxxxx...xxxx> */
348  str = rb_str_buf_new(2 + strlen(cname) + 2 + digest_len * 2 + 1);
349  rb_str_buf_cat2(str, "#<");
350  rb_str_buf_cat2(str, cname);
351  rb_str_buf_cat2(str, ": ");
352  rb_str_buf_append(str, rb_digest_instance_hexdigest(0, 0, self));
353  rb_str_buf_cat2(str, ">");
354  return str;
355 }
356 
357 /*
358  * call-seq:
359  * digest_obj == another_digest_obj -> boolean
360  * digest_obj == string -> boolean
361  *
362  * If a string is given, checks whether it is equal to the hex-encoded
363  * hash value of the digest object. If another digest instance is
364  * given, checks whether they have the same hash value. Otherwise
365  * returns false.
366  */
367 static VALUE
368 rb_digest_instance_equal(VALUE self, VALUE other)
369 {
370  VALUE str1, str2;
371 
372  if (rb_obj_is_kind_of(other, rb_mDigest_Instance) == Qtrue) {
373  str1 = rb_digest_instance_digest(0, 0, self);
374  str2 = rb_digest_instance_digest(0, 0, other);
375  } else {
376  str1 = rb_digest_instance_to_s(self);
377  str2 = rb_check_string_type(other);
378  if (NIL_P(str2)) return Qfalse;
379  }
380 
381  /* never blindly assume that subclass methods return strings */
382  StringValue(str1);
383  StringValue(str2);
384 
385  if (RSTRING_LEN(str1) == RSTRING_LEN(str2) &&
386  rb_str_cmp(str1, str2) == 0) {
387  return Qtrue;
388  }
389  return Qfalse;
390 }
391 
392 /*
393  * call-seq:
394  * digest_obj.digest_length -> integer
395  *
396  * Returns the length of the hash value of the digest.
397  *
398  * This method should be overridden by each implementation subclass.
399  * If not, digest_obj.digest().length() is returned.
400  */
401 static VALUE
402 rb_digest_instance_digest_length(VALUE self)
403 {
404  /* subclasses really should redefine this method */
405  VALUE digest = rb_digest_instance_digest(0, 0, self);
406 
407  /* never blindly assume that #digest() returns a string */
408  StringValue(digest);
409  return INT2NUM(RSTRING_LEN(digest));
410 }
411 
412 /*
413  * call-seq:
414  * digest_obj.length -> integer
415  * digest_obj.size -> integer
416  *
417  * Returns digest_obj.digest_length().
418  */
419 static VALUE
420 rb_digest_instance_length(VALUE self)
421 {
422  return rb_funcall(self, id_digest_length, 0);
423 }
424 
425 /*
426  * call-seq:
427  * digest_obj.block_length -> integer
428  *
429  * Returns the block length of the digest.
430  *
431  * This method is overridden by each implementation subclass.
432  */
433 static VALUE
434 rb_digest_instance_block_length(VALUE self)
435 {
436  rb_digest_instance_method_unimpl(self, "block_length");
437 
438  UNREACHABLE;
439 }
440 
441 /*
442  * Document-class: Digest::Class
443  *
444  * This module stands as a base class for digest implementation
445  * classes.
446  */
447 
448 /*
449  * call-seq:
450  * Digest::Class.digest(string, *parameters) -> hash_string
451  *
452  * Returns the hash value of a given _string_. This is equivalent to
453  * Digest::Class.new(*parameters).digest(string), where extra
454  * _parameters_, if any, are passed through to the constructor and the
455  * _string_ is passed to #digest().
456  */
457 static VALUE
458 rb_digest_class_s_digest(int argc, VALUE *argv, VALUE klass)
459 {
460  VALUE str;
461  volatile VALUE obj;
462 
463  if (argc < 1) {
464  rb_raise(rb_eArgError, "no data given");
465  }
466 
467  str = *argv++;
468  argc--;
469 
470  StringValue(str);
471 
472  obj = rb_obj_alloc(klass);
473  rb_obj_call_init(obj, argc, argv);
474 
475  return rb_funcall(obj, id_digest, 1, str);
476 }
477 
478 /*
479  * call-seq:
480  * Digest::Class.hexdigest(string[, ...]) -> hash_string
481  *
482  * Returns the hex-encoded hash value of a given _string_. This is
483  * almost equivalent to
484  * Digest.hexencode(Digest::Class.new(*parameters).digest(string)).
485  */
486 static VALUE
487 rb_digest_class_s_hexdigest(int argc, VALUE *argv, VALUE klass)
488 {
489  return hexencode_str_new(rb_funcallv(klass, id_digest, argc, argv));
490 }
491 
492 /* :nodoc: */
493 static VALUE
494 rb_digest_class_init(VALUE self)
495 {
496  return self;
497 }
498 
499 /*
500  * Document-class: Digest::Base
501  *
502  * This abstract class provides a common interface to message digest
503  * implementation classes written in C.
504  *
505  * ==Write a Digest subclass in C
506  * Digest::Base provides a common interface to message digest
507  * classes written in C. These classes must provide a struct
508  * of type rb_digest_metadata_t:
509  * typedef int (*rb_digest_hash_init_func_t)(void *);
510  * typedef void (*rb_digest_hash_update_func_t)(void *, unsigned char *, size_t);
511  * typedef int (*rb_digest_hash_finish_func_t)(void *, unsigned char *);
512  *
513  * typedef struct {
514  * int api_version;
515  * size_t digest_len;
516  * size_t block_len;
517  * size_t ctx_size;
518  * rb_digest_hash_init_func_t init_func;
519  * rb_digest_hash_update_func_t update_func;
520  * rb_digest_hash_finish_func_t finish_func;
521  * } rb_digest_metadata_t;
522  *
523  * This structure must be set as an instance variable named +metadata+
524  * (without the +@+ in front of the name). By example:
525  * static const rb_digest_metadata_t sha1 = {
526  * RUBY_DIGEST_API_VERSION,
527  * SHA1_DIGEST_LENGTH,
528  * SHA1_BLOCK_LENGTH,
529  * sizeof(SHA1_CTX),
530  * (rb_digest_hash_init_func_t)SHA1_Init,
531  * (rb_digest_hash_update_func_t)SHA1_Update,
532  * (rb_digest_hash_finish_func_t)SHA1_Finish,
533  * };
534  *
535  *
536  * rb_ivar_set(cDigest_SHA1, rb_intern("metadata"),
537  * Data_Wrap_Struct(0, 0, 0, (void *)&sha1));
538  */
539 
540 static rb_digest_metadata_t *
541 get_digest_base_metadata(VALUE klass)
542 {
543  VALUE p;
544  VALUE obj;
545  rb_digest_metadata_t *algo;
546 
547  for (p = klass; !NIL_P(p); p = rb_class_superclass(p)) {
548  if (rb_ivar_defined(p, id_metadata)) {
549  obj = rb_ivar_get(p, id_metadata);
550  break;
551  }
552  }
553 
554  if (NIL_P(p))
555  rb_raise(rb_eRuntimeError, "Digest::Base cannot be directly inherited in Ruby");
556 
557 #undef RUBY_UNTYPED_DATA_WARNING
558 #define RUBY_UNTYPED_DATA_WARNING 0
560 
561  switch (algo->api_version) {
562  case 3:
563  break;
564 
565  /*
566  * put conversion here if possible when API is updated
567  */
568 
569  default:
570  rb_raise(rb_eRuntimeError, "Incompatible digest API version");
571  }
572 
573  return algo;
574 }
575 
576 static const rb_data_type_t digest_type = {
577  "digest",
578  {0, RUBY_TYPED_DEFAULT_FREE, 0,},
579  0, 0,
581 };
582 
583 static inline void
584 algo_init(const rb_digest_metadata_t *algo, void *pctx)
585 {
586  if (algo->init_func(pctx) != 1) {
587  rb_raise(rb_eRuntimeError, "Digest initialization failed.");
588  }
589 }
590 
591 static VALUE
592 rb_digest_base_alloc(VALUE klass)
593 {
594  rb_digest_metadata_t *algo;
595  VALUE obj;
596  void *pctx;
597 
598  if (klass == rb_cDigest_Base) {
599  rb_raise(rb_eNotImpError, "Digest::Base is an abstract class");
600  }
601 
602  algo = get_digest_base_metadata(klass);
603 
604  obj = rb_data_typed_object_zalloc(klass, algo->ctx_size, &digest_type);
605  pctx = RTYPEDDATA_DATA(obj);
606  algo_init(algo, pctx);
607 
608  return obj;
609 }
610 
611 /* :nodoc: */
612 static VALUE
613 rb_digest_base_copy(VALUE copy, VALUE obj)
614 {
615  rb_digest_metadata_t *algo;
616  void *pctx1, *pctx2;
617 
618  if (copy == obj) return copy;
619 
620  rb_check_frozen(copy);
621 
622  algo = get_digest_base_metadata(rb_obj_class(copy));
623  if (algo != get_digest_base_metadata(rb_obj_class(obj)))
624  rb_raise(rb_eTypeError, "different algorithms");
625 
626  TypedData_Get_Struct(obj, void, &digest_type, pctx1);
627  TypedData_Get_Struct(copy, void, &digest_type, pctx2);
628  memcpy(pctx2, pctx1, algo->ctx_size);
629 
630  return copy;
631 }
632 
633 /*
634  * call-seq: digest_base.reset -> digest_base
635  *
636  * Reset the digest to its initial state and return +self+.
637  */
638 static VALUE
639 rb_digest_base_reset(VALUE self)
640 {
641  rb_digest_metadata_t *algo;
642  void *pctx;
643 
644  algo = get_digest_base_metadata(rb_obj_class(self));
645 
646  TypedData_Get_Struct(self, void, &digest_type, pctx);
647 
648  algo_init(algo, pctx);
649 
650  return self;
651 }
652 
653 /*
654  * call-seq:
655  * digest_base.update(string) -> digest_base
656  * digest_base << string -> digest_base
657  *
658  * Update the digest using given _string_ and return +self+.
659  */
660 static VALUE
661 rb_digest_base_update(VALUE self, VALUE str)
662 {
663  rb_digest_metadata_t *algo;
664  void *pctx;
665 
666  algo = get_digest_base_metadata(rb_obj_class(self));
667 
668  TypedData_Get_Struct(self, void, &digest_type, pctx);
669 
670  StringValue(str);
671  algo->update_func(pctx, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str));
672  RB_GC_GUARD(str);
673 
674  return self;
675 }
676 
677 /* :nodoc: */
678 static VALUE
679 rb_digest_base_finish(VALUE self)
680 {
681  rb_digest_metadata_t *algo;
682  void *pctx;
683  VALUE str;
684 
685  algo = get_digest_base_metadata(rb_obj_class(self));
686 
687  TypedData_Get_Struct(self, void, &digest_type, pctx);
688 
689  str = rb_str_new(0, algo->digest_len);
690  algo->finish_func(pctx, (unsigned char *)RSTRING_PTR(str));
691 
692  /* avoid potential coredump caused by use of a finished context */
693  algo_init(algo, pctx);
694 
695  return str;
696 }
697 
698 /*
699  * call-seq: digest_base.digest_length -> Integer
700  *
701  * Return the length of the hash value in bytes.
702  */
703 static VALUE
704 rb_digest_base_digest_length(VALUE self)
705 {
706  rb_digest_metadata_t *algo;
707 
708  algo = get_digest_base_metadata(rb_obj_class(self));
709 
710  return INT2NUM(algo->digest_len);
711 }
712 
713 /*
714  * call-seq: digest_base.block_length -> Integer
715  *
716  * Return the block length of the digest in bytes.
717  */
718 static VALUE
719 rb_digest_base_block_length(VALUE self)
720 {
721  rb_digest_metadata_t *algo;
722 
723  algo = get_digest_base_metadata(rb_obj_class(self));
724 
725  return INT2NUM(algo->block_len);
726 }
727 
728 void
730 {
731  id_reset = rb_intern("reset");
732  id_update = rb_intern("update");
733  id_finish = rb_intern("finish");
734  id_digest = rb_intern("digest");
735  id_hexdigest = rb_intern("hexdigest");
736  id_digest_length = rb_intern("digest_length");
737 
738  /*
739  * module Digest
740  */
741  rb_mDigest = rb_define_module("Digest");
742 
743  /* module functions */
744  rb_define_module_function(rb_mDigest, "hexencode", rb_digest_s_hexencode, 1);
745 
746  /*
747  * module Digest::Instance
748  */
749  rb_mDigest_Instance = rb_define_module_under(rb_mDigest, "Instance");
750 
751  /* instance methods that should be overridden */
752  rb_define_method(rb_mDigest_Instance, "update", rb_digest_instance_update, 1);
753  rb_define_method(rb_mDigest_Instance, "<<", rb_digest_instance_update, 1);
754  rb_define_private_method(rb_mDigest_Instance, "finish", rb_digest_instance_finish, 0);
755  rb_define_method(rb_mDigest_Instance, "reset", rb_digest_instance_reset, 0);
756  rb_define_method(rb_mDigest_Instance, "digest_length", rb_digest_instance_digest_length, 0);
757  rb_define_method(rb_mDigest_Instance, "block_length", rb_digest_instance_block_length, 0);
758 
759  /* instance methods that may be overridden */
760  rb_define_method(rb_mDigest_Instance, "==", rb_digest_instance_equal, 1);
761  rb_define_method(rb_mDigest_Instance, "inspect", rb_digest_instance_inspect, 0);
762 
763  /* instance methods that need not usually be overridden */
764  rb_define_method(rb_mDigest_Instance, "new", rb_digest_instance_new, 0);
765  rb_define_method(rb_mDigest_Instance, "digest", rb_digest_instance_digest, -1);
766  rb_define_method(rb_mDigest_Instance, "digest!", rb_digest_instance_digest_bang, 0);
767  rb_define_method(rb_mDigest_Instance, "hexdigest", rb_digest_instance_hexdigest, -1);
768  rb_define_method(rb_mDigest_Instance, "hexdigest!", rb_digest_instance_hexdigest_bang, 0);
769  rb_define_method(rb_mDigest_Instance, "to_s", rb_digest_instance_to_s, 0);
770  rb_define_method(rb_mDigest_Instance, "length", rb_digest_instance_length, 0);
771  rb_define_method(rb_mDigest_Instance, "size", rb_digest_instance_length, 0);
772 
773  /*
774  * class Digest::Class
775  */
776  rb_cDigest_Class = rb_define_class_under(rb_mDigest, "Class", rb_cObject);
777  rb_define_method(rb_cDigest_Class, "initialize", rb_digest_class_init, 0);
778  rb_include_module(rb_cDigest_Class, rb_mDigest_Instance);
779 
780  /* class methods */
781  rb_define_singleton_method(rb_cDigest_Class, "digest", rb_digest_class_s_digest, -1);
782  rb_define_singleton_method(rb_cDigest_Class, "hexdigest", rb_digest_class_s_hexdigest, -1);
783 
784  id_metadata = rb_intern("metadata");
785 
786  /* class Digest::Base < Digest::Class */
787  rb_cDigest_Base = rb_define_class_under(rb_mDigest, "Base", rb_cDigest_Class);
788 
789  rb_define_alloc_func(rb_cDigest_Base, rb_digest_base_alloc);
790 
791  rb_define_method(rb_cDigest_Base, "initialize_copy", rb_digest_base_copy, 1);
792  rb_define_method(rb_cDigest_Base, "reset", rb_digest_base_reset, 0);
793  rb_define_method(rb_cDigest_Base, "update", rb_digest_base_update, 1);
794  rb_define_method(rb_cDigest_Base, "<<", rb_digest_base_update, 1);
795  rb_define_private_method(rb_cDigest_Base, "finish", rb_digest_base_finish, 0);
796  rb_define_method(rb_cDigest_Base, "digest_length", rb_digest_base_digest_length, 0);
797  rb_define_method(rb_cDigest_Base, "block_length", rb_digest_base_block_length, 0);
798 }
rb_digest_hash_update_func_t update_func
Definition: digest.h:30
size_t digest_len
Definition: digest.h:26
rb_digest_hash_finish_func_t finish_func
Definition: digest.h:31
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1138
size_t strlen(const char *)
#define INT2NUM(x)
Definition: ruby.h:1538
#define Data_Get_Struct(obj, type, sval)
Definition: ruby.h:1180
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1716
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2284
#define Qtrue
Definition: ruby.h:437
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1183
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1527
#define UNREACHABLE
Definition: ruby.h:46
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:693
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1210
#define RB_GC_GUARD(v)
Definition: ruby.h:552
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:2121
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:864
int rb_str_cmp(VALUE, VALUE)
Definition: string.c:3159
void rb_obj_call_init(VALUE obj, int argc, const VALUE *argv)
Calls #initialize method of obj with the given arguments.
Definition: eval.c:1583
VALUE rb_str_buf_append(VALUE, VALUE)
Definition: string.c:2884
VALUE rb_ivar_defined(VALUE, ID)
Definition: variable.c:1374
const char * rb_obj_classname(VALUE)
Definition: variable.c:459
VALUE rb_eArgError
Definition: error.c:802
VALUE rb_obj_class(VALUE)
call-seq: obj.class -> class
Definition: object.c:277
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
Definition: object.c:842
#define RUBY_TYPED_WB_PROTECTED
Definition: ruby.h:1139
NORETURN(static void rb_digest_instance_method_unimpl(VALUE self, const char *method))
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1893
VALUE rb_str_buf_cat2(VALUE, const char *)
#define NIL_P(v)
Definition: ruby.h:451
void Init_digest(void)
Definition: digest.c:729
int argc
Definition: ruby.c:187
#define Qfalse
Definition: ruby.h:436
#define LONG_MAX
Definition: ruby.h:189
#define RSTRING_LEN(str)
Definition: ruby.h:971
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1731
#define RUBY_EXTERN
Definition: missing.h:77
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1908
unsigned long ID
Definition: ruby.h:86
unsigned long VALUE
Definition: ruby.h:85
size_t block_len
Definition: digest.h:27
VALUE rb_eNotImpError
Definition: error.c:811
VALUE rb_eTypeError
Definition: error.c:801
#define rb_funcallv
Definition: console.c:21
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:790
rb_digest_hash_init_func_t init_func
Definition: digest.h:29
VALUE rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type)
#define RSTRING_PTR(str)
Definition: ruby.h:975
VALUE rb_class_superclass(VALUE)
call-seq: class.superclass -> a_super_class or nil
Definition: object.c:2204
VALUE rb_eRuntimeError
Definition: error.c:800
VALUE rb_check_string_type(VALUE)
Definition: string.c:2246
#define RTYPEDDATA_DATA(v)
Definition: ruby.h:1110
#define rb_check_frozen(obj)
Definition: intern.h:271
#define RUBY_TYPED_DEFAULT_FREE
Definition: ruby.h:1134
RUBY_EXTERN void Init_digest_base(void)
VALUE rb_define_module(const char *name)
Definition: class.c:768
#define rb_intern(str)
VALUE rb_str_buf_new(long)
Definition: string.c:1282
VALUE rb_usascii_str_new(const char *, long)
Definition: string.c:743
VALUE rb_obj_clone(VALUE)
:nodoc Almost same as Object::clone ++
Definition: object.c:475
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
char ** argv
Definition: ruby.c:188
#define StringValue(v)
Definition: ruby.h:569
VALUE rb_str_new(const char *, long)
Definition: string.c:737