crypto.md5: fix calculating the same hash values, when .sum() is called several times (#19703)

This commit is contained in:
shove 2023-10-30 15:30:34 +08:00 committed by GitHub
parent 00bf5c4a16
commit 395b55f0cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 6 deletions

View File

@ -58,6 +58,14 @@ pub fn (mut d Digest) reset() {
d.len = 0 d.len = 0
} }
fn (d &Digest) clone() &Digest {
return &Digest{
...d
s: d.s.clone()
x: d.x.clone()
}
}
// new returns a new Digest (implementing hash.Hash) computing the MD5 checksum. // new returns a new Digest (implementing hash.Hash) computing the MD5 checksum.
pub fn new() &Digest { pub fn new() &Digest {
mut d := &Digest{} mut d := &Digest{}
@ -103,7 +111,7 @@ pub fn (mut d Digest) write(p_ []u8) !int {
// sum returns the md5 sum of the bytes in `b_in`. // sum returns the md5 sum of the bytes in `b_in`.
pub fn (d &Digest) sum(b_in []u8) []u8 { pub fn (d &Digest) sum(b_in []u8) []u8 {
// Make a copy of d so that caller can keep writing and summing. // Make a copy of d so that caller can keep writing and summing.
mut d0 := *d mut d0 := d.clone()
hash := d0.checksum() hash := d0.checksum()
mut b_out := b_in.clone() mut b_out := b_in.clone()
for b in hash { for b in hash {
@ -112,7 +120,10 @@ pub fn (d &Digest) sum(b_in []u8) []u8 {
return b_out return b_out
} }
// checksum returns the byte checksum of the `Digest`. // checksum returns the byte checksum of the `Digest`,
// it is an internal method and is not recommended because its results are not idempotent.
[deprecated: 'checksum() will be changed to a private method, use sum() instead']
[deprecated_after: '2024-04-30']
pub fn (mut d Digest) checksum() []u8 { pub fn (mut d Digest) checksum() []u8 {
// Append 0x80 to the end of the message and then append zeros // Append 0x80 to the end of the message and then append zeros
// until the length is a multiple of 56 bytes. Finally append // until the length is a multiple of 56 bytes. Finally append

View File

@ -11,7 +11,9 @@ fn test_crypto_md5_writer() {
mut digest := md5.new() mut digest := md5.new()
digest.write('this is a'.bytes()) or { assert false } digest.write('this is a'.bytes()) or { assert false }
digest.write(' md5 checksum.'.bytes()) or { assert false } digest.write(' md5 checksum.'.bytes()) or { assert false }
sum := digest.sum([]) mut sum := digest.sum([])
assert sum.hex() == '6fb421ff99036547655984da12973431'
sum = digest.sum([])
assert sum.hex() == '6fb421ff99036547655984da12973431' assert sum.hex() == '6fb421ff99036547655984da12973431'
} }

View File

@ -127,7 +127,10 @@ pub fn (d &Digest) sum(b_in []u8) []u8 {
return b_out return b_out
} }
// checksum returns the current byte checksum of the `Digest`. // checksum returns the current byte checksum of the `Digest`,
// it is an internal method and is not recommended because its results are not idempotent.
[deprecated: 'checksum() will be changed to a private method, use sum() instead']
[deprecated_after: '2024-04-30']
pub fn (mut d Digest) checksum() []u8 { pub fn (mut d Digest) checksum() []u8 {
mut len := d.len mut len := d.len
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.

View File

@ -167,7 +167,10 @@ pub fn (d &Digest) sum(b_in []u8) []u8 {
return b_out return b_out
} }
// checksum returns the current byte checksum of the Digest. // checksum returns the current byte checksum of the Digest,
// it is an internal method and is not recommended because its results are not idempotent.
[deprecated: 'checksum() will be changed to a private method, use sum() instead']
[deprecated_after: '2024-04-30']
pub fn (mut d Digest) checksum() []u8 { pub fn (mut d Digest) checksum() []u8 {
mut len := d.len mut len := d.len
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.

View File

@ -239,7 +239,10 @@ pub fn (d &Digest) sum(b_in []u8) []u8 {
return b_out return b_out
} }
// checksum returns the current byte checksum of the Digest. // checksum returns the current byte checksum of the Digest,
// it is an internal method and is not recommended because its results are not idempotent.
[deprecated: 'checksum() will be changed to a private method, use sum() instead']
[deprecated_after: '2024-04-30']
pub fn (mut d Digest) checksum() []u8 { pub fn (mut d Digest) checksum() []u8 {
// Padding. Add a 1 bit and 0 bits until 112 bytes mod 128. // Padding. Add a 1 bit and 0 bits until 112 bytes mod 128.
mut len := d.len mut len := d.len