Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

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 if (!RB_TYPE_P(obj, T_DATA) || RTYPEDDATA_P(obj)) {
558 wrong:
559 if (p == klass)
560 rb_raise(rb_eTypeError, "%"PRIsVALUE"::metadata is not initialized properly",
561 klass);
562 else
563 rb_raise(rb_eTypeError, "%"PRIsVALUE"(%"PRIsVALUE")::metadata is not initialized properly",
564 klass, p);
565 }
566
567 #undef RUBY_UNTYPED_DATA_WARNING
568 #define RUBY_UNTYPED_DATA_WARNING 0
569 Data_Get_Struct(obj, rb_digest_metadata_t, algo);
570
571 if (!algo) goto wrong;
572
573 switch (algo->api_version) {
574 case 3:
575 break;
576
577 /*
578 * put conversion here if possible when API is updated
579 */
580
581 default:
582 rb_raise(rb_eRuntimeError, "Incompatible digest API version");
583 }
584
585 return algo;
586 }
587
588 static rb_digest_metadata_t *
589 get_digest_obj_metadata(VALUE obj)
590 {
591 return get_digest_base_metadata(rb_obj_class(obj));
592 }
593
594 static const rb_data_type_t digest_type = {
595 "digest",
596 {0, RUBY_TYPED_DEFAULT_FREE, 0,},
597 0, 0,
598 (RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED),
599 };
600
601 static inline void
602 algo_init(const rb_digest_metadata_t *algo, void *pctx)
603 {
604 if (algo->init_func(pctx) != 1) {
605 rb_raise(rb_eRuntimeError, "Digest initialization failed.");
606 }
607 }
608
609 static VALUE
610 rb_digest_base_alloc(VALUE klass)
611 {
612 rb_digest_metadata_t *algo;
613 VALUE obj;
614 void *pctx;
615
616 if (klass == rb_cDigest_Base) {
617 rb_raise(rb_eNotImpError, "Digest::Base is an abstract class");
618 }
619
620 algo = get_digest_base_metadata(klass);
621
622 obj = rb_data_typed_object_zalloc(klass, algo->ctx_size, &digest_type);
623 pctx = RTYPEDDATA_DATA(obj);
624 algo_init(algo, pctx);
625
626 return obj;
627 }
628
629 /* :nodoc: */
630 static VALUE
631 rb_digest_base_copy(VALUE copy, VALUE obj)
632 {
633 rb_digest_metadata_t *algo;
634 void *pctx1, *pctx2;
635
636 if (copy == obj) return copy;
637
638 rb_check_frozen(copy);
639
640 algo = get_digest_obj_metadata(copy);
641 if (algo != get_digest_obj_metadata(obj))
642 rb_raise(rb_eTypeError, "different algorithms");
643
644 TypedData_Get_Struct(obj, void, &digest_type, pctx1);
645 TypedData_Get_Struct(copy, void, &digest_type, pctx2);
646 memcpy(pctx2, pctx1, algo->ctx_size);
647
648 return copy;
649 }
650
651 /*
652 * call-seq: digest_base.reset -> digest_base
653 *
654 * Reset the digest to its initial state and return +self+.
655 */
656 static VALUE
657 rb_digest_base_reset(VALUE self)
658 {
659 rb_digest_metadata_t *algo;
660 void *pctx;
661
662 algo = get_digest_obj_metadata(self);
663
664 TypedData_Get_Struct(self, void, &digest_type, pctx);
665
666 algo_init(algo, pctx);
667
668 return self;
669 }
670
671 /*
672 * call-seq:
673 * digest_base.update(string) -> digest_base
674 * digest_base << string -> digest_base
675 *
676 * Update the digest using given _string_ and return +self+.
677 */
678 static VALUE
679 rb_digest_base_update(VALUE self, VALUE str)
680 {
681 rb_digest_metadata_t *algo;
682 void *pctx;
683
684 algo = get_digest_obj_metadata(self);
685
686 TypedData_Get_Struct(self, void, &digest_type, pctx);
687
688 StringValue(str);
689 algo->update_func(pctx, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str));
690 RB_GC_GUARD(str);
691
692 return self;
693 }
694
695 /* :nodoc: */
696 static VALUE
697 rb_digest_base_finish(VALUE self)
698 {
699 rb_digest_metadata_t *algo;
700 void *pctx;
701 VALUE str;
702
703 algo = get_digest_obj_metadata(self);
704
705 TypedData_Get_Struct(self, void, &digest_type, pctx);
706
707 str = rb_str_new(0, algo->digest_len);
708 algo->finish_func(pctx, (unsigned char *)RSTRING_PTR(str));
709
710 /* avoid potential coredump caused by use of a finished context */
711 algo_init(algo, pctx);
712
713 return str;
714 }
715
716 /*
717 * call-seq: digest_base.digest_length -> Integer
718 *
719 * Return the length of the hash value in bytes.
720 */
721 static VALUE
722 rb_digest_base_digest_length(VALUE self)
723 {
724 rb_digest_metadata_t *algo;
725
726 algo = get_digest_obj_metadata(self);
727
728 return INT2NUM(algo->digest_len);
729 }
730
731 /*
732 * call-seq: digest_base.block_length -> Integer
733 *
734 * Return the block length of the digest in bytes.
735 */
736 static VALUE
737 rb_digest_base_block_length(VALUE self)
738 {
739 rb_digest_metadata_t *algo;
740
741 algo = get_digest_obj_metadata(self);
742
743 return INT2NUM(algo->block_len);
744 }
745
746 void
747 Init_digest(void)
748 {
749 #undef rb_intern
750 id_reset = rb_intern("reset");
751 id_update = rb_intern("update");
752 id_finish = rb_intern("finish");
753 id_digest = rb_intern("digest");
754 id_hexdigest = rb_intern("hexdigest");
755 id_digest_length = rb_intern("digest_length");
756 id_metadata = rb_id_metadata();
757 InitVM(digest);
758 }
759
760 void
761 InitVM_digest(void)
762 {
763 /*
764 * module Digest
765 */
766 rb_mDigest = rb_define_module("Digest");
767
768 /* module functions */
769 rb_define_module_function(rb_mDigest, "hexencode", rb_digest_s_hexencode, 1);
770
771 /*
772 * module Digest::Instance
773 */
774 rb_mDigest_Instance = rb_define_module_under(rb_mDigest, "Instance");
775
776 /* instance methods that should be overridden */
777 rb_define_method(rb_mDigest_Instance, "update", rb_digest_instance_update, 1);
778 rb_define_method(rb_mDigest_Instance, "<<", rb_digest_instance_update, 1);
779 rb_define_private_method(rb_mDigest_Instance, "finish", rb_digest_instance_finish, 0);
780 rb_define_method(rb_mDigest_Instance, "reset", rb_digest_instance_reset, 0);
781 rb_define_method(rb_mDigest_Instance, "digest_length", rb_digest_instance_digest_length, 0);
782 rb_define_method(rb_mDigest_Instance, "block_length", rb_digest_instance_block_length, 0);
783
784 /* instance methods that may be overridden */
785 rb_define_method(rb_mDigest_Instance, "==", rb_digest_instance_equal, 1);
786 rb_define_method(rb_mDigest_Instance, "inspect", rb_digest_instance_inspect, 0);
787
788 /* instance methods that need not usually be overridden */
789 rb_define_method(rb_mDigest_Instance, "new", rb_digest_instance_new, 0);
790 rb_define_method(rb_mDigest_Instance, "digest", rb_digest_instance_digest, -1);
791 rb_define_method(rb_mDigest_Instance, "digest!", rb_digest_instance_digest_bang, 0);
792 rb_define_method(rb_mDigest_Instance, "hexdigest", rb_digest_instance_hexdigest, -1);
793 rb_define_method(rb_mDigest_Instance, "hexdigest!", rb_digest_instance_hexdigest_bang, 0);
794 rb_define_method(rb_mDigest_Instance, "to_s", rb_digest_instance_to_s, 0);
795 rb_define_method(rb_mDigest_Instance, "length", rb_digest_instance_length, 0);
796 rb_define_method(rb_mDigest_Instance, "size", rb_digest_instance_length, 0);
797
798 /*
799 * class Digest::Class
800 */
801 rb_cDigest_Class = rb_define_class_under(rb_mDigest, "Class", rb_cObject);
802 rb_define_method(rb_cDigest_Class, "initialize", rb_digest_class_init, 0);
803 rb_include_module(rb_cDigest_Class, rb_mDigest_Instance);
804
805 /* class methods */
806 rb_define_singleton_method(rb_cDigest_Class, "digest", rb_digest_class_s_digest, -1);
807 rb_define_singleton_method(rb_cDigest_Class, "hexdigest", rb_digest_class_s_hexdigest, -1);
808
809 /* class Digest::Base < Digest::Class */
810 rb_cDigest_Base = rb_define_class_under(rb_mDigest, "Base", rb_cDigest_Class);
811
812 rb_define_alloc_func(rb_cDigest_Base, rb_digest_base_alloc);
813
814 rb_define_method(rb_cDigest_Base, "initialize_copy", rb_digest_base_copy, 1);
815 rb_define_method(rb_cDigest_Base, "reset", rb_digest_base_reset, 0);
816 rb_define_method(rb_cDigest_Base, "update", rb_digest_base_update, 1);
817 rb_define_method(rb_cDigest_Base, "<<", rb_digest_base_update, 1);
818 rb_define_private_method(rb_cDigest_Base, "finish", rb_digest_base_finish, 0);
819 rb_define_method(rb_cDigest_Base, "digest_length", rb_digest_base_digest_length, 0);
820 rb_define_method(rb_cDigest_Base, "block_length", rb_digest_base_block_length, 0);
821 }
rb_digest_metadata_t::block_len
size_t block_len
Definition: digest.h:27
ID
unsigned long ID
Definition: ruby.h:103
rb_include_module
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:869
LONG_MAX
#define LONG_MAX
Definition: ruby.h:220
rb_define_module_under
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:797
rb_str_buf_cat2
#define rb_str_buf_cat2
Definition: intern.h:911
rb_str_buf_new
VALUE rb_str_buf_new(long)
Definition: string.c:1315
InitVM_digest
void InitVM_digest(void)
Definition: digest.c:761
rb_scan_args
#define rb_scan_args(argc, argvp, fmt,...)
Definition: rb_mjit_min_header-2.7.0.h:6372
rb_digest_metadata_t::digest_len
size_t digest_len
Definition: digest.h:26
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
rb_class_superclass
VALUE rb_class_superclass(VALUE)
Returns the superclass of klass.
Definition: object.c:1976
VALUE
unsigned long VALUE
Definition: ruby.h:102
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
rb_intern
#define rb_intern(str)
RB_TYPE_P
#define RB_TYPE_P(obj, type)
Definition: ruby.h:560
rb_digest_metadata_t::api_version
int api_version
Definition: digest.h:25
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:772
StringValue
use StringValue() instead")))
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:2314
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1755
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
INT2NUM
#define INT2NUM(x)
Definition: ruby.h:1609
T_DATA
#define T_DATA
Definition: ruby.h:538
Qfalse
#define Qfalse
Definition: ruby.h:467
NORETURN
NORETURN(static void rb_digest_instance_method_unimpl(VALUE self, const char *method))
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
strlen
size_t strlen(const char *)
InitVM
#define InitVM(ext)
Definition: ruby.h:2329
rb_funcallv
#define rb_funcallv(recv, mid, argc, argv)
Definition: rb_mjit_min_header-2.7.0.h:7899
RUBY_TYPED_DEFAULT_FREE
#define RUBY_TYPED_DEFAULT_FREE
Definition: ruby.h:1203
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1070
rb_digest_metadata_t::init_func
rb_digest_hash_init_func_t init_func
Definition: digest.h:29
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.0.h:5742
rb_obj_class
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
Definition: object.c:217
rb_data_typed_object_zalloc
VALUE rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type)
memcpy
void * memcpy(void *__restrict, const void *__restrict, size_t)
rb_check_frozen
#define rb_check_frozen(obj)
Definition: intern.h:319
rb_digest_metadata_t
Definition: digest.h:24
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:922
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:920
RTYPEDDATA_DATA
#define RTYPEDDATA_DATA(v)
Definition: ruby.h:1179
Init_digest
void Init_digest(void)
Definition: digest.c:747
rb_eNotImpError
VALUE rb_eNotImpError
Definition: error.c:932
rb_str_buf_append
VALUE rb_str_buf_append(VALUE, VALUE)
Definition: string.c:2950
rb_define_module_function
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1771
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
TypedData_Get_Struct
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1252
rb_funcall
#define rb_funcall(recv, mid, argc,...)
Definition: rb_mjit_min_header-2.7.0.h:6585
digest.h
rb_digest_metadata_t::ctx_size
size_t ctx_size
Definition: digest.h:28
argv
char ** argv
Definition: ruby.c:223
UNREACHABLE
#define UNREACHABLE
Definition: ruby.h:63
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.0.h:13254
rb_obj_alloc
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:1895
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
rb_usascii_str_new
#define rb_usascii_str_new(str, len)
Definition: rb_mjit_min_header-2.7.0.h:6118
RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1207
rb_ivar_defined
VALUE rb_ivar_defined(VALUE, ID)
Definition: variable.c:1317
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
argc
int argc
Definition: ruby.c:222
rb_obj_classname
const char * rb_obj_classname(VALUE)
Definition: variable.c:289
rb_obj_call_init
void rb_obj_call_init(VALUE obj, int argc, const VALUE *argv)
Calls #initialize method of obj with the given arguments.
Definition: eval.c:1680
RUBY_EXTERN
#define RUBY_EXTERN
Definition: missing.h:77
Data_Get_Struct
#define Data_Get_Struct(obj, type, sval)
Definition: ruby.h:1249
rb_data_type_struct
Definition: ruby.h:1148
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.0.h:6116
Qtrue
#define Qtrue
Definition: ruby.h:468
RTYPEDDATA_P
#define RTYPEDDATA_P(v)
Definition: ruby.h:1177
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:698
rb_digest_metadata_t::update_func
rb_digest_hash_update_func_t update_func
Definition: digest.h:30
rb_digest_metadata_t::finish_func
rb_digest_hash_finish_func_t finish_func
Definition: digest.h:31
Init_digest_base
RUBY_EXTERN void Init_digest_base(void)
RB_GC_GUARD
#define RB_GC_GUARD(v)
Definition: ruby.h:585
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
rb_define_private_method
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1569
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
Definition: object.c:692
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
rb_obj_clone
VALUE rb_obj_clone(VALUE)
Almost same as Object::clone.
Definition: object.c:410
RUBY_TYPED_WB_PROTECTED
#define RUBY_TYPED_WB_PROTECTED
Definition: ruby.h:1208
rb_str_cmp
int rb_str_cmp(VALUE, VALUE)
Definition: string.c:3228