mirror of
https://github.com/luau-lang/luau.git
synced 2024-12-13 21:40:43 +00:00
e5ec0cdff3
## What's changed - `bit32.byteswap` added ([RFC](4f543ec23b/docs/function-bit32-byteswap.md
)) - Buffer library implementation ([RFC](4f543ec23b/docs/type-byte-buffer.md
)) - Fixed a missing `stdint.h` include - Fixed parser limiter for recursive type annotations being kind of weird (fixes #645) ### Native Codegen - Fixed a pair of issues when lowering `bit32.extract` - Fixed a narrow edge case that could result in an infinite loop without an interruption - Fixed a negative array out-of-bounds access issue - Temporarily reverted linear block predecessor value propagation ### New type solver - We now type check assignments to annotated variables - Fixed some test cases under local type inference - Moved `isPending` checks for type families to improve performance - Optimized our process for testing if a free type is sufficiently solved - Removed "none ptr" from lea instruction disassembly logging ### Build system & tooling - CMake configuration now validates dependencies to maintain separation between components - Improvements to the fuzzer coverage - Deduplicator for fuzzed callstacks --------- Co-authored-by: Arseny Kapoulkine <arseny.kapoulkine@gmail.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com> Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Aaron Weiss <aaronweiss@roblox.com> Co-authored-by: Vighnesh Vijay <vvijay@roblox.com>
540 lines
22 KiB
Lua
540 lines
22 KiB
Lua
-- This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
print("testing byte buffer library")
|
|
|
|
function call(fn, ...)
|
|
local ok, res = pcall(fn, ...)
|
|
assert(ok)
|
|
return res
|
|
end
|
|
|
|
function ecall(fn, ...)
|
|
local ok, err = pcall(fn, ...)
|
|
assert(not ok)
|
|
return err:sub((err:find(": ") or -1) + 2, #err)
|
|
end
|
|
|
|
local function simple_byte_reads()
|
|
local b = buffer.create(1024)
|
|
|
|
assert(buffer.len(b) == 1024)
|
|
|
|
assert(buffer.readi8(b, 5) == 0)
|
|
buffer.writei8(b, 10, 32)
|
|
assert(buffer.readi8(b, 10) == 32)
|
|
buffer.writei8(b, 15, 5)
|
|
buffer.writei8(b, 14, 4)
|
|
buffer.writei8(b, 13, 3)
|
|
buffer.writei8(b, 12, 2)
|
|
buffer.writei8(b, 11, 1)
|
|
assert(buffer.readi8(b, 11) == 1)
|
|
assert(buffer.readi8(b, 12) == 2)
|
|
assert(buffer.readi8(b, 13) == 3)
|
|
assert(buffer.readi8(b, 14) == 4)
|
|
assert(buffer.readi8(b, 15) == 5)
|
|
|
|
local x = buffer.readi8(b, 14) + buffer.readi8(b, 13)
|
|
assert(x == 7)
|
|
end
|
|
|
|
simple_byte_reads()
|
|
|
|
local function offset_byte_reads(start: number)
|
|
local b = buffer.create(1024)
|
|
|
|
buffer.writei8(b, start, 32)
|
|
assert(buffer.readi8(b, start) == 32)
|
|
buffer.writei8(b, start + 5, 5)
|
|
buffer.writei8(b, start + 4, 4)
|
|
buffer.writei8(b, start + 3, 3)
|
|
buffer.writei8(b, start + 2, 2)
|
|
buffer.writei8(b, start + 1, 1)
|
|
assert(buffer.readi8(b, start + 1) == 1)
|
|
assert(buffer.readi8(b, start + 2) == 2)
|
|
assert(buffer.readi8(b, start + 3) == 3)
|
|
assert(buffer.readi8(b, start + 4) == 4)
|
|
assert(buffer.readi8(b, start + 5) == 5)
|
|
|
|
local x = buffer.readi8(b, start + 4) + buffer.readi8(b, start + 3)
|
|
assert(x == 7)
|
|
end
|
|
|
|
offset_byte_reads(5)
|
|
offset_byte_reads(30)
|
|
|
|
local function simple_float_reinterpret()
|
|
local b = buffer.create(1024)
|
|
|
|
buffer.writei32(b, 10, 0x3f800000)
|
|
local one = buffer.readf32(b, 10)
|
|
assert(one == 1.0)
|
|
|
|
buffer.writef32(b, 10, 2.75197)
|
|
local magic = buffer.readi32(b, 10)
|
|
assert(magic == 0x40302047)
|
|
end
|
|
|
|
simple_float_reinterpret()
|
|
|
|
local function simple_double_reinterpret()
|
|
local b = buffer.create(1024)
|
|
|
|
buffer.writei32(b, 10, 0x00000000)
|
|
buffer.writei32(b, 14, 0x3ff00000)
|
|
local one = buffer.readf64(b, 10)
|
|
assert(one == 1.0)
|
|
|
|
buffer.writef64(b, 10, 1.437576533064206)
|
|
local magic1 = buffer.readi32(b, 10)
|
|
local magic2 = buffer.readi32(b, 14)
|
|
|
|
assert(magic1 == 0x40302010)
|
|
assert(magic2 == 0x3ff70050)
|
|
end
|
|
|
|
simple_double_reinterpret()
|
|
|
|
local function simple_string_ops()
|
|
local b = buffer.create(1024)
|
|
|
|
buffer.writestring(b, 15, " world")
|
|
buffer.writestring(b, 10, "hello")
|
|
buffer.writei8(b, 21, string.byte('!'))
|
|
assert(buffer.readstring(b, 10, 12) == "hello world!")
|
|
|
|
buffer.writestring(b, 10, "hellommm", 5)
|
|
assert(buffer.readstring(b, 10, 12) == "hello world!")
|
|
|
|
buffer.writestring(b, 10, string.rep("hellommm", 1000), 5)
|
|
assert(buffer.readstring(b, 10, 12) == "hello world!")
|
|
end
|
|
|
|
simple_string_ops()
|
|
|
|
local function simple_copy_ops()
|
|
local b1 = buffer.create(1024)
|
|
local b2 = buffer.create(1024)
|
|
|
|
buffer.writestring(b1, 200, "hello")
|
|
buffer.writestring(b1, 100, "world")
|
|
|
|
buffer.copy(b1, 300, b1, 100, 5)
|
|
|
|
buffer.writei8(b2, 35, string.byte(' '))
|
|
buffer.writei8(b2, 41, string.byte('!'))
|
|
|
|
buffer.copy(b2, 30, b1, 200, 5)
|
|
buffer.copy(b2, 36, b1, 300, 5)
|
|
|
|
assert(buffer.readstring(b2, 30, 12) == "hello world!")
|
|
|
|
local b3 = buffer.create(9)
|
|
buffer.writestring(b3, 0, "say hello")
|
|
buffer.copy(b2, 36, b3, 4)
|
|
assert(buffer.readstring(b2, 30, 12) == "hello hello!")
|
|
|
|
local b4 = buffer.create(5)
|
|
buffer.writestring(b4, 0, "world")
|
|
buffer.copy(b2, 36, b4)
|
|
assert(buffer.readstring(b2, 30, 12) == "hello world!")
|
|
|
|
buffer.writestring(b1, 200, "abcdefgh");
|
|
buffer.copy(b1, 200, b1, 202, 6)
|
|
assert(buffer.readstring(b1, 200, 8) == "cdefghgh")
|
|
buffer.copy(b1, 202, b1, 200, 6)
|
|
assert(buffer.readstring(b1, 200, 8) == "cdcdefgh")
|
|
end
|
|
|
|
simple_copy_ops()
|
|
|
|
-- bounds checking
|
|
|
|
local function createchecks()
|
|
assert(ecall(function() buffer.create(-1) end) == "size cannot be negative")
|
|
assert(ecall(function() buffer.create(-1000000) end) == "size cannot be negative")
|
|
end
|
|
|
|
createchecks()
|
|
|
|
local function boundchecks()
|
|
local b = buffer.create(1024)
|
|
|
|
assert(call(function() return buffer.readi8(b, 1023) end) == 0)
|
|
assert(ecall(function() buffer.readi8(b, 1024) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi8(b, -1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi8(b, -100000) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writei8(b, 1023, 0) end)
|
|
assert(ecall(function() buffer.writei8(b, 1024, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei8(b, -1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei8(b, -100000, 0) end) == "buffer access out of bounds")
|
|
|
|
-- i16
|
|
assert(call(function() return buffer.readi16(b, 1022) end) == 0)
|
|
assert(ecall(function() buffer.readi16(b, 1023) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, -1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, -100000) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, 0x7fffffff) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, 0x7ffffffe) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, 0x7ffffffd) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, 0x80000000) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writei16(b, 1022, 0) end)
|
|
assert(ecall(function() buffer.writei16(b, 1023, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei16(b, -1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei16(b, -100000, 0) end) == "buffer access out of bounds")
|
|
|
|
-- i32
|
|
assert(call(function() return buffer.readi32(b, 1020) end) == 0)
|
|
assert(ecall(function() buffer.readi32(b, 1021) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi32(b, -1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi32(b, -100000) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writei32(b, 1020, 0) end)
|
|
assert(ecall(function() buffer.writei32(b, 1021, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei32(b, -1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei32(b, -100000, 0) end) == "buffer access out of bounds")
|
|
|
|
-- f32
|
|
assert(call(function() return buffer.readf32(b, 1020) end) == 0)
|
|
assert(ecall(function() buffer.readf32(b, 1021) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf32(b, -1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf32(b, -100000) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writef32(b, 1020, 0) end)
|
|
assert(ecall(function() buffer.writef32(b, 1021, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef32(b, -1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef32(b, -100000, 0) end) == "buffer access out of bounds")
|
|
|
|
-- f64
|
|
assert(call(function() return buffer.readf64(b, 1016) end) == 0)
|
|
assert(ecall(function() buffer.readf64(b, 1017) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf64(b, -1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf64(b, -100000) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writef64(b, 1016, 0) end)
|
|
assert(ecall(function() buffer.writef64(b, 1017, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef64(b, -1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef64(b, -100000, 0) end) == "buffer access out of bounds")
|
|
|
|
-- string
|
|
assert(call(function() return buffer.readstring(b, 1016, 8) end) == "\0\0\0\0\0\0\0\0")
|
|
assert(ecall(function() buffer.readstring(b, 1017, 8) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readstring(b, -1, -8) end) == "size cannot be negative")
|
|
assert(ecall(function() buffer.readstring(b, -100000, 8) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readstring(b, -100000, 8) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writestring(b, 1016, "abcdefgh") end)
|
|
assert(ecall(function() buffer.writestring(b, 1017, "abcdefgh") end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writestring(b, -1, "abcdefgh") end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writestring(b, -100000, "abcdefgh") end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writestring(b, 100, "abcd", -5) end) == "count cannot be negative")
|
|
assert(ecall(function() buffer.writestring(b, 100, "abcd", 50) end) == "string length overflow")
|
|
|
|
-- copy
|
|
assert(ecall(function() buffer.copy(b, 30, b, 200, 1000) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.copy(b, 30, b, 200, -5) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.copy(b, 30, b, 2000, 10) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.copy(b, 30, b, -1, 10) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.copy(b, 30, b, -10, 10) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.copy(b, 30, b, -100000, 10) end) == "buffer access out of bounds")
|
|
|
|
local b2 = buffer.create(1024)
|
|
assert(ecall(function() buffer.copy(b, -200, b, 200, 200) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.copy(b, 825, b, 200, 200) end) == "buffer access out of bounds")
|
|
end
|
|
|
|
boundchecks()
|
|
|
|
local function boundchecksnonconst(size, minus1, minusbig, intmax)
|
|
local b = buffer.create(size)
|
|
|
|
assert(call(function() return buffer.readi8(b, size-1) end) == 0)
|
|
assert(ecall(function() buffer.readi8(b, size) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi8(b, minus1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi8(b, minusbig) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writei8(b, size-1, 0) end)
|
|
assert(ecall(function() buffer.writei8(b, size, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei8(b, minus1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei8(b, minusbig, 0) end) == "buffer access out of bounds")
|
|
|
|
-- i16
|
|
assert(call(function() return buffer.readi16(b, size-2) end) == 0)
|
|
assert(ecall(function() buffer.readi16(b, size-1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, minus1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, minusbig) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, intmax) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, intmax-1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, intmax-2) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, intmax+1) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writei16(b, size-2, 0) end)
|
|
assert(ecall(function() buffer.writei16(b, size-1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei16(b, minus1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei16(b, minusbig, 0) end) == "buffer access out of bounds")
|
|
|
|
-- i32
|
|
assert(call(function() return buffer.readi32(b, size-4) end) == 0)
|
|
assert(ecall(function() buffer.readi32(b, size-3) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi32(b, minus1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi32(b, minusbig) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writei32(b, size-4, 0) end)
|
|
assert(ecall(function() buffer.writei32(b, size-3, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei32(b, minus1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei32(b, minusbig, 0) end) == "buffer access out of bounds")
|
|
|
|
-- f32
|
|
assert(call(function() return buffer.readf32(b, size-4) end) == 0)
|
|
assert(ecall(function() buffer.readf32(b, size-3) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf32(b, minus1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf32(b, minusbig) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writef32(b, size-4, 0) end)
|
|
assert(ecall(function() buffer.writef32(b, size-3, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef32(b, minus1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef32(b, minusbig, 0) end) == "buffer access out of bounds")
|
|
|
|
-- f64
|
|
assert(call(function() return buffer.readf64(b, size-8) end) == 0)
|
|
assert(ecall(function() buffer.readf64(b, size-7) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf64(b, minus1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf64(b, minusbig) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writef64(b, size-8, 0) end)
|
|
assert(ecall(function() buffer.writef64(b, size-7, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef64(b, minus1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef64(b, minusbig, 0) end) == "buffer access out of bounds")
|
|
|
|
-- string
|
|
assert(call(function() return buffer.readstring(b, size-8, 8) end) == "\0\0\0\0\0\0\0\0")
|
|
assert(ecall(function() buffer.readstring(b, size-7, 8) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readstring(b, minus1, 8) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readstring(b, minusbig, 8) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writestring(b, size-8, "abcdefgh") end)
|
|
assert(ecall(function() buffer.writestring(b, size-7, "abcdefgh") end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writestring(b, minus1, "abcdefgh") end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writestring(b, minusbig, "abcdefgh") end) == "buffer access out of bounds")
|
|
end
|
|
|
|
boundchecksnonconst(1024, -1, -100000, 0x7fffffff)
|
|
|
|
local function boundcheckssmall()
|
|
local b = buffer.create(1)
|
|
|
|
assert(call(function() return buffer.readi8(b, 0) end) == 0)
|
|
assert(ecall(function() buffer.readi8(b, 1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi8(b, -1) end) == "buffer access out of bounds")
|
|
|
|
call(function() buffer.writei8(b, 0, 0) end)
|
|
assert(ecall(function() buffer.writei8(b, 1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei8(b, -1, 0) end) == "buffer access out of bounds")
|
|
|
|
-- i16
|
|
assert(ecall(function() buffer.readi16(b, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, -1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi16(b, -2) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei16(b, 0, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei16(b, -1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei16(b, -2, 0) end) == "buffer access out of bounds")
|
|
|
|
-- i32
|
|
assert(ecall(function() buffer.readi32(b, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi32(b, -1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi32(b, -4) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei32(b, 0, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei32(b, -1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei32(b, -4, 0) end) == "buffer access out of bounds")
|
|
|
|
-- f32
|
|
assert(ecall(function() buffer.readf32(b, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf32(b, -1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf32(b, -4) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef32(b, 0, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef32(b, -1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef32(b, -4, 0) end) == "buffer access out of bounds")
|
|
|
|
-- f64
|
|
assert(ecall(function() buffer.readf64(b, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf64(b, -1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf64(b, -8) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef64(b, 0, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef64(b, -1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writef64(b, -7, 0) end) == "buffer access out of bounds")
|
|
|
|
-- string
|
|
assert(ecall(function() buffer.readstring(b, 0, 8) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readstring(b, -1, 8) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readstring(b, -8, 8) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writestring(b, 0, "abcdefgh") end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writestring(b, -1, "abcdefgh") end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writestring(b, -7, "abcdefgh") end) == "buffer access out of bounds")
|
|
end
|
|
|
|
boundcheckssmall()
|
|
|
|
local function boundchecksempty()
|
|
local b = buffer.create(0) -- useless, but probably more generic
|
|
|
|
assert(ecall(function() buffer.readi8(b, 1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi8(b, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi8(b, -1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei8(b, 1, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei8(b, 0, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.writei8(b, -1, 0) end) == "buffer access out of bounds")
|
|
|
|
assert(ecall(function() buffer.readi16(b, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readi32(b, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf32(b, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readf64(b, 0) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readstring(b, 0, 1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.readstring(b, 0, 8) end) == "buffer access out of bounds")
|
|
end
|
|
|
|
boundchecksempty()
|
|
|
|
local function intuint()
|
|
local b = buffer.create(32)
|
|
|
|
buffer.writeu32(b, 0, 0xffffffff)
|
|
assert(buffer.readi8(b, 0) == -1)
|
|
assert(buffer.readu8(b, 0) == 255)
|
|
assert(buffer.readi16(b, 0) == -1)
|
|
assert(buffer.readu16(b, 0) == 65535)
|
|
assert(buffer.readi32(b, 0) == -1)
|
|
assert(buffer.readu32(b, 0) == 4294967295)
|
|
|
|
buffer.writei32(b, 0, -1)
|
|
assert(buffer.readi8(b, 0) == -1)
|
|
assert(buffer.readu8(b, 0) == 255)
|
|
assert(buffer.readi16(b, 0) == -1)
|
|
assert(buffer.readu16(b, 0) == 65535)
|
|
assert(buffer.readi32(b, 0) == -1)
|
|
assert(buffer.readu32(b, 0) == 4294967295)
|
|
|
|
buffer.writei16(b, 0, 65535)
|
|
buffer.writei16(b, 2, -1)
|
|
assert(buffer.readi8(b, 0) == -1)
|
|
assert(buffer.readu8(b, 0) == 255)
|
|
assert(buffer.readi16(b, 0) == -1)
|
|
assert(buffer.readu16(b, 0) == 65535)
|
|
assert(buffer.readi32(b, 0) == -1)
|
|
assert(buffer.readu32(b, 0) == 4294967295)
|
|
|
|
buffer.writeu16(b, 0, 65535)
|
|
buffer.writeu16(b, 2, -1)
|
|
assert(buffer.readi8(b, 0) == -1)
|
|
assert(buffer.readu8(b, 0) == 255)
|
|
assert(buffer.readi16(b, 0) == -1)
|
|
assert(buffer.readu16(b, 0) == 65535)
|
|
assert(buffer.readi32(b, 0) == -1)
|
|
assert(buffer.readu32(b, 0) == 4294967295)
|
|
end
|
|
|
|
intuint()
|
|
|
|
local function intuinttricky()
|
|
local b = buffer.create(32)
|
|
|
|
buffer.writeu8(b, 0, 0xffffffff)
|
|
assert(buffer.readi8(b, 0) == -1)
|
|
assert(buffer.readu8(b, 0) == 255)
|
|
assert(buffer.readi16(b, 0) == 255)
|
|
assert(buffer.readu16(b, 0) == 255)
|
|
assert(buffer.readi32(b, 0) == 255)
|
|
assert(buffer.readu32(b, 0) == 255)
|
|
|
|
buffer.writeu16(b, 0, 0xffffffff)
|
|
assert(buffer.readi8(b, 0) == -1)
|
|
assert(buffer.readu8(b, 0) == 255)
|
|
assert(buffer.readi16(b, 0) == -1)
|
|
assert(buffer.readu16(b, 0) == 65535)
|
|
assert(buffer.readi32(b, 0) == 65535)
|
|
assert(buffer.readu32(b, 0) == 65535)
|
|
|
|
buffer.writei32(b, 8, 0xffffffff)
|
|
buffer.writeu32(b, 12, 0xffffffff)
|
|
assert(buffer.readstring(b, 8, 4) == buffer.readstring(b, 12, 4))
|
|
|
|
buffer.writei32(b, 8, -2147483648)
|
|
buffer.writeu32(b, 12, 0x80000000)
|
|
assert(buffer.readstring(b, 8, 4) == buffer.readstring(b, 12, 4))
|
|
end
|
|
|
|
intuinttricky()
|
|
|
|
local function fromtostring()
|
|
local b = buffer.fromstring("1234567890")
|
|
assert(buffer.tostring(b) == "1234567890")
|
|
|
|
buffer.writestring(b, 4, "xyz")
|
|
assert(buffer.tostring(b) == "1234xyz890")
|
|
|
|
local b2 = buffer.fromstring("abcd\0ef")
|
|
assert(buffer.tostring(b2) == "abcd\0ef")
|
|
end
|
|
|
|
fromtostring()
|
|
|
|
local function fill()
|
|
local b = buffer.create(10)
|
|
|
|
buffer.fill(b, 0, 0x61)
|
|
assert(buffer.tostring(b) == "aaaaaaaaaa")
|
|
|
|
buffer.fill(b, 0, 0x62, 5)
|
|
assert(buffer.tostring(b) == "bbbbbaaaaa")
|
|
|
|
buffer.fill(b, 4, 0x63)
|
|
assert(buffer.tostring(b) == "bbbbcccccc")
|
|
|
|
buffer.fill(b, 6, 0x64, 3)
|
|
assert(buffer.tostring(b) == "bbbbccdddc")
|
|
|
|
buffer.fill(b, 2, 0xffffff65, 8)
|
|
assert(buffer.tostring(b) == "bbeeeeeeee")
|
|
|
|
-- out of bounds
|
|
assert(ecall(function() buffer.fill(b, -10, 1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.fill(b, 11, 1) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.fill(b, 0, 1, 11) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.fill(b, 5, 1, 6) end) == "buffer access out of bounds")
|
|
assert(ecall(function() buffer.fill(b, 5, 1, -1) end) == "buffer access out of bounds")
|
|
end
|
|
|
|
fill()
|
|
|
|
local function misc()
|
|
local b = buffer.create(1000)
|
|
|
|
assert(select('#', buffer.writei32(b, 10, 40)) == 0)
|
|
assert(select('#', buffer.writef32(b, 20, 40.0)) == 0)
|
|
end
|
|
|
|
misc()
|
|
|
|
local function testslowcalls()
|
|
getfenv()
|
|
|
|
simple_byte_reads()
|
|
offset_byte_reads(5)
|
|
offset_byte_reads(30)
|
|
simple_float_reinterpret()
|
|
simple_double_reinterpret()
|
|
simple_string_ops()
|
|
createchecks()
|
|
boundchecks()
|
|
boundchecksnonconst(1024, -1, -100000, 0x7fffffff)
|
|
boundcheckssmall()
|
|
boundchecksempty()
|
|
intuint()
|
|
intuinttricky()
|
|
fromtostring()
|
|
fill()
|
|
misc()
|
|
end
|
|
|
|
testslowcalls()
|
|
|
|
return('OK')
|