From d9532eda3033d2713e1a6509f0357077e1e097e1 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Tue, 19 Jan 2021 14:34:25 +0200 Subject: [PATCH] checker: error on a.slice(x,y) outside `builtin` --- .../modules/neuroevolution/neuronevolution.v | 2 +- vlib/builtin/array_test.v | 6 ++--- vlib/crypto/aes/aes_cbc.v | 15 ++++++------ vlib/crypto/aes/block_generic.v | 24 +++++++++---------- vlib/v/checker/checker.v | 4 ++++ vlib/v/checker/tests/method_array_slice.out | 7 ++++++ vlib/v/checker/tests/method_array_slice.vv | 7 ++++++ 7 files changed, 41 insertions(+), 24 deletions(-) create mode 100644 vlib/v/checker/tests/method_array_slice.out create mode 100644 vlib/v/checker/tests/method_array_slice.vv diff --git a/examples/flappylearning/modules/neuroevolution/neuronevolution.v b/examples/flappylearning/modules/neuroevolution/neuronevolution.v index d81462475e..9a034145af 100644 --- a/examples/flappylearning/modules/neuroevolution/neuronevolution.v +++ b/examples/flappylearning/modules/neuroevolution/neuronevolution.v @@ -50,7 +50,7 @@ mut: fn (mut n Network) populate(network []int) { assert network.len >= 2 input := network[0] - hiddens := network.slice(1, network.len - 1) + hiddens := network[1..network.len-1] output := network[network.len - 1] mut index := 0 mut previous_neurons := 0 diff --git a/vlib/builtin/array_test.v b/vlib/builtin/array_test.v index 7762af060a..6a2a8c0c6c 100644 --- a/vlib/builtin/array_test.v +++ b/vlib/builtin/array_test.v @@ -255,9 +255,9 @@ fn test_left() { fn test_slice() { a := [1, 2, 3, 4] - b := a.slice(2, 4) + b := a[2..4] assert b.len == 2 - assert a.slice(1, 2).len == 1 + assert a[1..2].len == 1 assert a.len == 4 } @@ -355,7 +355,7 @@ fn test_clone() { assert nums2.len == 5 assert nums.str() == '[1, 2, 3, 4, 100]' assert nums2.str() == '[1, 2, 3, 4, 100]' - assert nums.slice(1, 3).str() == '[2, 3]' + assert nums[1..3].str() == '[2, 3]' } /* diff --git a/vlib/crypto/aes/aes_cbc.v b/vlib/crypto/aes/aes_cbc.v index 5a7e224ff8..91bc4047e3 100644 --- a/vlib/crypto/aes/aes_cbc.v +++ b/vlib/crypto/aes/aes_cbc.v @@ -94,21 +94,20 @@ pub fn (mut x AesCbc) decrypt_blocks(mut dst []byte, src []byte) { mut start := end - x.block_size mut prev := start - x.block_size // Copy the last block of ciphertext in preparation as the new iv. - copy(x.tmp, src.slice(start, end)) + copy(x.tmp, src[start..end]) // Loop over all but the first block. for start > 0 { - mut src_chunk := src.slice(start, end) - x.b.decrypt(mut (*dst).slice(start, end), mut src_chunk) - cipher.xor_bytes(mut (*dst).slice(start, end), (*dst).slice(start, end), src.slice(prev, - start)) + mut src_chunk := src[start..end] + x.b.decrypt(mut (*dst)[start..end], mut src_chunk) + cipher.xor_bytes(mut (*dst)[start..end], (*dst)[start..end], src[prev..start]) end = start start = prev prev -= x.block_size } // The first block is special because it uses the saved iv. - mut src_chunk := src.slice(start, end) - x.b.decrypt(mut (*dst).slice(start, end), mut src_chunk) - cipher.xor_bytes(mut (*dst).slice(start, end), (*dst).slice(start, end), x.iv) + mut src_chunk := src[start..end] + x.b.decrypt(mut (*dst)[start..end], mut src_chunk) + cipher.xor_bytes(mut (*dst)[start..end], (*dst)[start..end], x.iv) // Set the new iv to the first block we copied earlier. x.iv = x.tmp x.tmp = x.iv diff --git a/vlib/crypto/aes/block_generic.v b/vlib/crypto/aes/block_generic.v index 2927daa7f2..3b52c3b196 100644 --- a/vlib/crypto/aes/block_generic.v +++ b/vlib/crypto/aes/block_generic.v @@ -41,9 +41,9 @@ import encoding.binary fn encrypt_block_generic(xk []u32, mut dst []byte, src []byte) { _ = src[15] // early bounds check mut s0 := binary.big_endian_u32(src[..4]) - mut s1 := binary.big_endian_u32(src.slice(4, 8)) - mut s2 := binary.big_endian_u32(src.slice(8, 12)) - mut s3 := binary.big_endian_u32(src.slice(12, 16)) + mut s1 := binary.big_endian_u32(src[4..8]) + mut s2 := binary.big_endian_u32(src[8..12]) + mut s3 := binary.big_endian_u32(src[12..16]) // First round just XORs input with key. s0 ^= xk[0] s1 ^= xk[1] @@ -83,18 +83,18 @@ fn encrypt_block_generic(xk []u32, mut dst []byte, src []byte) { s3 ^= xk[k + 3] _ := dst[15] // early bounds check binary.big_endian_put_u32(mut (*dst)[0..4], s0) - binary.big_endian_put_u32(mut (*dst).slice(4, 8), s1) - binary.big_endian_put_u32(mut (*dst).slice(8, 12), s2) - binary.big_endian_put_u32(mut (*dst).slice(12, 16), s3) + binary.big_endian_put_u32(mut (*dst)[4..8], s1) + binary.big_endian_put_u32(mut (*dst)[8..12], s2) + binary.big_endian_put_u32(mut (*dst)[12..16], s3) } // Decrypt one block from src into dst, using the expanded key xk. fn decrypt_block_generic(xk []u32, mut dst []byte, src []byte) { _ = src[15] // early bounds check mut s0 := binary.big_endian_u32(src[0..4]) - mut s1 := binary.big_endian_u32(src.slice(4, 8)) - mut s2 := binary.big_endian_u32(src.slice(8, 12)) - mut s3 := binary.big_endian_u32(src.slice(12, 16)) + mut s1 := binary.big_endian_u32(src[4..8]) + mut s2 := binary.big_endian_u32(src[8..12]) + mut s3 := binary.big_endian_u32(src[12..16]) // First round just XORs input with key. s0 ^= xk[0] s1 ^= xk[1] @@ -134,9 +134,9 @@ fn decrypt_block_generic(xk []u32, mut dst []byte, src []byte) { s3 ^= xk[k + 3] _ = dst[15] // early bounds check binary.big_endian_put_u32(mut (*dst)[..4], s0) - binary.big_endian_put_u32(mut (*dst).slice(4, 8), s1) - binary.big_endian_put_u32(mut (*dst).slice(8, 12), s2) - binary.big_endian_put_u32(mut (*dst).slice(12, 16), s3) + binary.big_endian_put_u32(mut (*dst)[4..8], s1) + binary.big_endian_put_u32(mut (*dst)[8..12], s2) + binary.big_endian_put_u32(mut (*dst)[12..16], s3) } // Apply s_box0 to each byte in w. diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 3ee80560f9..876d061515 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1270,6 +1270,10 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { mut elem_typ := table.void_type is_filter_map := method_name in ['filter', 'map'] is_sort := method_name == 'sort' + is_slice := method_name == 'slice' + if is_slice && !c.is_builtin_mod { + c.error('.slice() is a private method, use `x[start..end]` instead', call_expr.pos) + } if is_filter_map || is_sort { array_info := left_type_sym.info as table.Array if is_filter_map { diff --git a/vlib/v/checker/tests/method_array_slice.out b/vlib/v/checker/tests/method_array_slice.out new file mode 100644 index 0000000000..dde905525b --- /dev/null +++ b/vlib/v/checker/tests/method_array_slice.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/method_array_slice.vv:5:12: error: .slice() is a private method, use `x[start..end]` instead + 3 | fn main() { + 4 | a := os.args.clone() + 5 | println(a.slice(1)) + | ~~~~~~~~ + 6 | println(a[1..]) + 7 | } diff --git a/vlib/v/checker/tests/method_array_slice.vv b/vlib/v/checker/tests/method_array_slice.vv new file mode 100644 index 0000000000..cfb77f3ce7 --- /dev/null +++ b/vlib/v/checker/tests/method_array_slice.vv @@ -0,0 +1,7 @@ +import os + +fn main() { + a := os.args.clone() + println(a.slice(1)) + println(a[1..]) +}