cgen: fix mutable array arguments (#5769)
parent
9fd0bc93f0
commit
0c9c66dd6b
|
@ -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]
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue