cgen: fix mutable array arguments (#5769)

pull/5794/head
yuyi 2020-07-11 00:04:51 +08:00 committed by GitHub
parent 9fd0bc93f0
commit 0c9c66dd6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 12 deletions

View File

@ -910,3 +910,25 @@ fn test_array_in_mut() {
array_in_mut(mut a)
assert a == [2,2]
}
// test array delete in function with mut argument
fn delete_nums(mut arr []int) {
arr.delete(0)
}
fn test_array_delete_in_mut() {
mut nums := [1, 2, 3]
delete_nums(mut nums)
assert nums == [2, 3]
}
// test array add in function with mut argument
fn add_nums(mut arr []int) {
arr << 4
}
fn test_array_add_in_mut() {
mut nums := [1, 2, 3]
add_nums(mut nums)
assert nums == [1, 2, 3, 4]
}

View File

@ -46,7 +46,8 @@ pub fn new_cbc(b AesCipher, iv []byte) AesCbc {
pub fn (x &AesCbc) block_size() int { return x.block_size }
pub fn (x &AesCbc) encrypt_blocks(mut dst []byte, src_ []byte) {
pub fn (x &AesCbc) encrypt_blocks(mut dst_ []byte, src_ []byte) {
mut dst := *dst_
mut src := src_
if src.len%x.block_size != 0 {
panic('crypto.cipher: input not full blocks')
@ -54,7 +55,7 @@ pub fn (x &AesCbc) encrypt_blocks(mut dst []byte, src_ []byte) {
if dst.len < src.len {
panic('crypto.cipher: output smaller than input')
}
if subtle.inexact_overlap((*dst)[..src.len], src_) {
if subtle.inexact_overlap(dst[..src.len], src_) {
panic('crypto.cipher: invalid buffer overlap')
}
@ -62,17 +63,17 @@ pub fn (x &AesCbc) encrypt_blocks(mut dst []byte, src_ []byte) {
for src.len > 0 {
// Write the xor to dst, then encrypt in place.
cipher.xor_bytes(mut (*dst)[..x.block_size], src[..x.block_size], iv)
x.b.encrypt(mut (*dst)[..x.block_size], mut (*dst)[..x.block_size])
cipher.xor_bytes(mut dst[..x.block_size], src[..x.block_size], iv)
x.b.encrypt(mut dst[..x.block_size], mut dst[..x.block_size])
// Move to the next block with this block as the next iv.
iv = (*dst)[..x.block_size]
iv = dst[..x.block_size]
if x.block_size >= src.len {
src = []
} else {
src = src[x.block_size..]
}
(*dst) = (*dst)[x.block_size..]
dst = dst[x.block_size..]
}
// Save the iv for the next crypt_blocks call.

View File

@ -21,7 +21,8 @@ fn test_crypto_aes() {
panic('ciphertext is not a multiple of the block size')
}
mode := aes.new_cbc(block, iv)
mode.encrypt_blocks(mut ciphertext, ciphertext)
cipher_clone := ciphertext.clone()
mode.encrypt_blocks(mut ciphertext, cipher_clone)
assert ciphertext.hex() == 'c210459b514668ddc44674885e4979215265a6c44431a248421254ef357a8c2a308a8bddf5623af9df91737562041cf1'
}

View File

@ -624,11 +624,16 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) {
} else if arg_is_ptr && !expr_is_ptr {
if arg.is_mut {
if exp_sym.kind == .array {
// Special case for mutable arrays. We can't `&` function
// results, have to use `(array[]){ expr }[0]` hack.
g.write('&/*111*/(array[]){')
g.expr(arg.expr)
g.write('}[0]')
if arg.expr is ast.Ident && (arg.expr as ast.Ident).kind == .variable {
g.write('&/*arr*/')
g.expr(arg.expr)
} else {
// Special case for mutable arrays. We can't `&` function
// results, have to use `(array[]){ expr }[0]` hack.
g.write('&/*111*/(array[]){')
g.expr(arg.expr)
g.write('}[0]')
}
return
}
}