Merge remote-tracking branch 'upstream/master' into sys-windows-2

# Conflicts:
#	core/sys/windows/shell32.odin
This commit is contained in:
Thomas la Cour
2024-07-25 10:05:41 +02:00
153 changed files with 9122 additions and 1426 deletions
@@ -28,6 +28,32 @@ benchmark_crypto :: proc(t: ^testing.T) {
strings.builder_destroy(&str)
}
{
name := "AES256-CTR 64 bytes"
options := &time.Benchmark_Options {
rounds = 1_000,
bytes = 64,
setup = _setup_sized_buf,
bench = _benchmark_aes256_ctr,
teardown = _teardown_sized_buf,
}
err := time.benchmark(options, context.allocator)
testing.expect(t, err == nil, name)
benchmark_print(&str, name, options)
name = "AES256-CTR 1024 bytes"
options.bytes = 1024
err = time.benchmark(options, context.allocator)
testing.expect(t, err == nil, name)
benchmark_print(&str, name, options)
name = "AES256-CTR 65536 bytes"
options.bytes = 65536
err = time.benchmark(options, context.allocator)
testing.expect(t, err == nil, name)
benchmark_print(&str, name, options)
}
{
name := "ChaCha20 64 bytes"
options := &time.Benchmark_Options {
@@ -323,6 +349,36 @@ _benchmark_chacha20poly1305 :: proc(
return nil
}
@(private)
_benchmark_aes256_ctr :: proc(
options: ^time.Benchmark_Options,
allocator := context.allocator,
) -> (
err: time.Benchmark_Error,
) {
buf := options.input
key := [aes.KEY_SIZE_256]byte {
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
}
nonce := [aes.CTR_IV_SIZE]byte {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}
ctx: aes.Context_CTR = ---
aes.init_ctr(&ctx, key[:], nonce[:])
for _ in 0 ..= options.rounds {
aes.xor_bytes_ctr(&ctx, buf, buf)
}
options.count = options.rounds
options.processed = options.rounds * options.bytes
return nil
}
_benchmark_aes256_gcm :: proc(
options: ^time.Benchmark_Options,
allocator := context.allocator,
+5 -7
View File
@@ -12,8 +12,6 @@ import "core:crypto/sha2"
test_aes :: proc(t: ^testing.T) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
log.info("Testing AES")
impls := make([dynamic]aes.Implementation, 0, 2)
defer delete(impls)
append(&impls, aes.Implementation.Portable)
@@ -29,7 +27,7 @@ test_aes :: proc(t: ^testing.T) {
}
test_aes_ecb :: proc(t: ^testing.T, impl: aes.Implementation) {
log.infof("Testing AES-ECB/%v", impl)
log.debugf("Testing AES-ECB/%v", impl)
test_vectors := []struct {
key: string,
@@ -136,7 +134,7 @@ test_aes_ecb :: proc(t: ^testing.T, impl: aes.Implementation) {
}
test_aes_ctr :: proc(t: ^testing.T, impl: aes.Implementation) {
log.infof("Testing AES-CTR/%v", impl)
log.debugf("Testing AES-CTR/%v", impl)
test_vectors := []struct {
key: string,
@@ -200,7 +198,7 @@ test_aes_ctr :: proc(t: ^testing.T, impl: aes.Implementation) {
ctx: aes.Context_CTR
key: [aes.KEY_SIZE_256]byte
nonce: [aes.CTR_IV_SIZE]byte
aes.init_ctr(&ctx, key[:], nonce[:])
aes.init_ctr(&ctx, key[:], nonce[:], impl)
h_ctx: sha2.Context_512
sha2.init_512_256(&h_ctx)
@@ -226,7 +224,7 @@ test_aes_ctr :: proc(t: ^testing.T, impl: aes.Implementation) {
}
test_aes_gcm :: proc(t: ^testing.T, impl: aes.Implementation) {
log.infof("Testing AES-GCM/%v", impl)
log.debugf("Testing AES-GCM/%v", impl)
// NIST did a reorg of their site, so the source of the test vectors
// is only available from an archive. The commented out tests are
@@ -431,7 +429,7 @@ test_aes_gcm :: proc(t: ^testing.T, impl: aes.Implementation) {
testing.expectf(
t,
ok && dst_str == v.plaintext,
"AES-GCM/%v: Expected: (%s, true) for open(%s, %s, %s, %s, %s), but got (%s, %s) instead",
"AES-GCM/%v: Expected: (%s, true) for open(%s, %s, %s, %s, %s), but got (%s, %v) instead",
impl,
v.plaintext,
v.key,
@@ -58,9 +58,9 @@ test_sqrt_ratio_m1 :: proc(t: ^testing.T) {
v_bytes, _ := hex.decode(transmute([]byte)(v.v), context.temp_allocator)
r_bytes, _ := hex.decode(transmute([]byte)(v.r), context.temp_allocator)
u_ := transmute(^[32]byte)(raw_data(u_bytes))
v_ := transmute(^[32]byte)(raw_data(v_bytes))
r_ := transmute(^[32]byte)(raw_data(r_bytes))
u_ := (^[32]byte)(raw_data(u_bytes))
v_ := (^[32]byte)(raw_data(v_bytes))
r_ := (^[32]byte)(raw_data(r_bytes))
u, vee, r: field.Tight_Field_Element
field.fe_from_bytes(&u, u_)
+1 -1
View File
@@ -161,7 +161,7 @@ test_pbkdf2 :: proc(t: ^testing.T) {
testing.expectf(
t,
dst_str == v.dk,
"HMAC-%s: Expected: %s for input of (%s, %s, %d), but got %s instead",
"PBKDF2-%s: Expected: %s for input of (%s, %s, %d), but got %s instead",
algo_name,
v.dk,
v.password,
+120
View File
@@ -0,0 +1,120 @@
package test_core_ini
import "base:runtime"
import "core:encoding/ini"
import "core:mem/virtual"
import "core:strings"
import "core:testing"
@test
parse_ini :: proc(t: ^testing.T) {
ini_data := `
[LOG]
level = "devel"
file = "/var/log/testing.log"
[USER]
first_name = "John"
surname = "Smith"
`
m, err := ini.load_map_from_string(ini_data, context.allocator)
defer ini.delete_map(m)
testing.expectf(
t,
strings.contains(m["LOG"]["level"], "devel"),
"Expected m[\"LOG\"][\"level\"] to be equal to 'devel' instead got %v",
m["LOG"]["level"],
)
testing.expectf(
t,
strings.contains(m["LOG"]["file"], "/var/log/testing.log"),
"Expected m[\"LOG\"][\"file\"] to be equal to '/var/log/testing.log' instead got %v",
m["LOG"]["file"],
)
testing.expectf(
t,
strings.contains(m["USER"]["first_name"], "John"),
"Expected m[\"USER\"][\"first_name\"] to be equal to 'John' instead got %v",
m["USER"]["first_name"],
)
testing.expectf(
t,
strings.contains(m["USER"]["surname"], "Smith"),
"Expected m[\"USER\"][\"surname\"] to be equal to 'Smith' instead got %v",
m["USER"]["surname"],
)
testing.expectf(t, err == nil, "Expected `ini.load_map_from_string` to return a nil error, got %v", err)
}
@test
ini_to_string :: proc(t: ^testing.T) {
m := ini.Map{
"LEVEL" = {
"LOG" = "debug",
},
}
str := ini.save_map_to_string(m, context.allocator)
defer delete(str)
delete(m["LEVEL"])
delete(m)
testing.expectf(
t,
strings.contains(str, "[LEVEL]LOG = debug"),
"Expected `ini.save_map_to_string` to return a string equal to \"[LEVEL]LOG = debug\", got %v",
str,
)
}
@test
ini_iterator :: proc(t: ^testing.T) {
ini_data := `
[LOG]
level = "devel"
file = "/var/log/testing.log"
[USER]
first_name = "John"
surname = "Smith"
`
i := 0
iterator := ini.iterator_from_string(ini_data)
for key, value in ini.iterate(&iterator) {
if strings.contains(key, "level") {
testing.expectf(
t,
strings.contains(value, "devel"),
"Expected 'level' to be equal to 'devel' instead got '%v'",
value,
)
} else if strings.contains(key, "file") {
testing.expectf(
t,
strings.contains(value, "/var/log/testing.log"),
"Expected 'file' to be equal to '/var/log/testing.log' instead got '%v'",
value,
)
} else if strings.contains(key, "first_name") {
testing.expectf(
t,
strings.contains(value, "John"),
"Expected 'first_name' to be equal to 'John' instead got '%v'",
value,
)
} else if strings.contains(key, "surname") {
testing.expectf(
t,
strings.contains(value, "Smith"),
"Expected 'surname' to be equal to 'Smith' instead got '%v'",
value,
)
}
i += 1
}
testing.expectf(t, i == 4, "Expected to loop 4 times, only looped %v times", i)
}
@@ -3,6 +3,7 @@ package test_core_json
import "core:encoding/json"
import "core:testing"
import "core:mem/virtual"
import "base:runtime"
@test
parse_json :: proc(t: ^testing.T) {
@@ -348,6 +349,24 @@ unmarshal_json :: proc(t: ^testing.T) {
}
}
@test
unmarshal_empty_struct :: proc(t: ^testing.T) {
TestStruct :: struct {}
test := make(map[string]TestStruct)
input: = `{
"test_1": {},
"test_2": {}
}`
err := json.unmarshal(transmute([]u8)input, &test)
defer {
for k in test {
delete(k)
}
delete(test)
}
testing.expect(t, err == nil, "Expected empty struct to unmarshal without error")
}
@test
surrogate :: proc(t: ^testing.T) {
input := `+ + * 😃 - /`
@@ -368,4 +387,60 @@ utf8_string_of_multibyte_characters :: proc(t: ^testing.T) {
val, err := json.parse_string(`"🐛✅"`)
defer json.destroy_value(val)
testing.expectf(t, err == nil, "Expected `json.parse` to return nil, got %v", err)
}
@test
struct_with_ignore_tags :: proc(t: ^testing.T) {
My_Struct :: struct {
a: string `json:"-"`,
}
my_struct := My_Struct{
a = "test",
}
my_struct_marshaled, marshal_err := json.marshal(my_struct)
defer delete(my_struct_marshaled)
testing.expectf(t, marshal_err == nil, "Expected `json.marshal` to return nil error, got %v", marshal_err)
my_struct_json := transmute(string)my_struct_marshaled
expected_json := `{}`
testing.expectf(t, expected_json == my_struct_json, "Expected `json.marshal` to return %s, got %s", expected_json, my_struct_json)
}
@test
map_with_integer_keys :: proc(t: ^testing.T) {
my_map := make(map[i32]string)
defer delete_map(my_map)
my_map[-1] = "a"
my_map[0] = "b"
my_map[42] = "c"
my_map[99999999] = "d"
marshaled_data, marshal_err := json.marshal(my_map)
defer delete(marshaled_data)
testing.expectf(t, marshal_err == nil, "Expected `json.marshal` to return nil error, got %v", marshal_err)
my_map2 := make(map[i32]string)
defer delete_map(my_map2)
unmarshal_err := json.unmarshal(marshaled_data, &my_map2)
defer for key, item in my_map2 {
runtime.delete_string(item)
}
testing.expectf(t, unmarshal_err == nil, "Expected `json.unmarshal` to return nil, got %v", unmarshal_err)
testing.expectf(t, len(my_map) == len(my_map2), "Expected %v map items to have been unmarshaled, got %v", len(my_map), len(my_map2))
for key, item in my_map {
testing.expectf(t, key in my_map2, "Expected key %v to be present in unmarshaled map", key)
if key in my_map2 {
testing.expectf(t, runtime.string_eq(item, my_map2[key]), "Expected value %s to be present in unmarshaled map", key)
}
}
}
+16
View File
@@ -372,6 +372,22 @@ test_odin_value_export :: proc(t: ^testing.T) {
}
}
@(test)
leaking_struct_tag :: proc(t: ^testing.T) {
My_Struct :: struct {
names: [^]string `fmt:"v,name_count"`,
name_count: int,
}
name := "hello?"
foo := My_Struct {
names = &name,
name_count = 1,
}
check(t, "My_Struct{names = [\"hello?\"], name_count = 1}", "%v", foo)
}
@(private)
check :: proc(t: ^testing.T, exp: string, format: string, args: ..any, loc := #caller_location) {
got := fmt.tprintf(format, ..args)
+1
View File
@@ -1,3 +1,4 @@
package tests_vendor
@(require) import "glfw"
@(require) import "lua/5.4"
+10
View File
@@ -0,0 +1,10 @@
-- defines a factorial function
function fact (n)
if n == 0 then
return 1
else
return n * fact(n-1)
end
end
return fact(10)
+71
View File
@@ -0,0 +1,71 @@
//+build windows, linux, darwin
package test_vendor_lua_54
import "core:testing"
import "core:c"
import lua "vendor:lua/5.4"
import "base:runtime"
@(test)
// Test context.allocator and returning a string
return_string_with_context_based_allocator :: proc(t: ^testing.T) {
_context := context
state: ^lua.State
state = lua.newstate(lua_context_allocator, &_context)
defer lua.close(state)
lua.L_dostring(state, "return 'somestring'")
str := lua.tostring(state, -1)
testing.expectf(
t, str == "somestring", "Expected Lua to return \"somestring\"",
)
}
@(test)
// Test lua.dofile and returning an integer
dofile_factorial :: proc(t: ^testing.T) {
state := lua.L_newstate()
defer lua.close(state)
FACT_10 :: 3628800
res := lua.L_dofile(state, #directory + "/factorial.lua")
testing.expectf(t, lua.Status(res) == .OK, "Expected L_dofile to return OKAY")
fact := lua.L_checkinteger(state, -1)
testing.expectf(t, fact == FACT_10, "Expected factorial(10) to return %v, got %v", FACT_10, fact)
}
@(test)
// Test that our bindings didn't get out of sync with the API version
verify_lua_api_version :: proc(t: ^testing.T) {
state := lua.L_newstate()
defer lua.close(state)
version := int(lua.version(state))
testing.expectf(t, version == lua.VERSION_NUM, "Expected lua.version to return %v, got %v", lua.VERSION_NUM, version)
}
// Simple context.allocator-based callback for Lua. Use `lua.newstate` to pass the context as user data.
lua_context_allocator :: proc "c" (ud: rawptr, ptr: rawptr, osize, nsize: c.size_t) -> (buf: rawptr) {
old_size := int(osize)
new_size := int(nsize)
context = (^runtime.Context)(ud)^
if ptr == nil {
data, err := runtime.mem_alloc(new_size)
return raw_data(data) if err == .None else nil
} else {
if nsize > 0 {
data, err := runtime.mem_resize(ptr, old_size, new_size)
return raw_data(data) if err == .None else nil
} else {
runtime.mem_free(ptr)
return
}
}
}