Files
nunuhara_xsystem4/test/Source/arrays.jaf
T
kichikuou a0d833649a Fix vm_copy() for reference types
This fixes a use-after-free bug in the first battle of Rance VI.
2021-05-01 19:50:09 +09:00

246 lines
5.2 KiB
C
Executable File

// -*-mode: C; coding: sjis; -*-
void test_array_set(void)
{
array@int ar[2];
test_equal("uninitialized array get", ar[0], 0);
ar[0] = 1;
ar[1] = 2;
test_equal("array get [0]", ar[0], 1);
test_equal("array get [1]", ar[1], 2);
}
void test_array_rank2(void)
{
array@int@2 ar[2][4];
int i, j;
for (i = 0; i < 2; i++) {
for (j = 0; j < 4; j++) {
ar[i][j] = i*4 + j;
}
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 4; j++) {
test_equal("array get [" + string(i) + "][" + string(j) + "]", ar[i][j], i*4 + j);
}
}
}
void test_array_alloc(void)
{
array@int@2 ar;
ar.Alloc(2, 4);
ar[0][0] = 1;
ar[1][0] = 2;
test_equal("array get [0][0]", ar[0][0], 1);
test_equal("array get [1][0]", ar[1][0], 2);
ar.Free();
ar.Alloc(4, 2);
ar[2][0] = 3;
ar[3][0] = 4;
test_equal("array get [2][0]", ar[2][0], 3);
test_equal("array get [3][0]", ar[3][0], 4);
}
void test_array_realloc(void)
{
array@int ar[1];
test_equal("array.Realloc()", (ar.Realloc(4), ar[3] = 1, ar[3]), 1);
}
void test_array_numof(void)
{
array@int ar1[2];
array@int@2 ar2[3][4];
test_equal("array.Numof()", ar1.Numof(), 2);
test_equal("array.Numof(1)", ar2.Numof(1), 3);
test_equal("array.Numof(2)", ar2.Numof(2), 4);
}
void init_array(ref array@int ar, int n)
{
int i;
for (i = 0; i < n; i++) {
ar[i] = i;
}
}
void do_test_array_copy(ref array@int dst, int dst_i, ref array@int src, int src_i, int n)
{
int i;
bool failed = false;
init_array(src, 8);
dst.Copy(dst_i, src, src_i, n);
for (i = 0; i < n; i++) {
if (src[src_i + i] != dst[dst_i + i]) {
failed = true;
}
}
test_bool("array.Copy(" + string(dst_i) + ", src, " + string(src_i) + ", " + string(n) + ")", !failed, true);
}
void test_array_copy(void)
{
array@int dst[8];
array@int src[8];
do_test_array_copy(dst, 0, src, 0, -2);
do_test_array_copy(dst, 0, src, 0, 0);
do_test_array_copy(dst, 0, src, 0, 8);
do_test_array_copy(dst, 2, src, 0, 6);
do_test_array_copy(dst, 0, src, 2, 6);
}
void test_array_fill(void)
{
array@int ar[8];
int n;
n = ar.Fill(7, 1, 1);
test_bool("array.Fill(7, 1, 1)", ar[7] == 1 && n == 1, true);
n = ar.Fill(0, 2, 2);
test_bool("array.Fill(0, 2, 2)", ar[0] == 2 && ar[1] == 2 && ar[2] != 2 && n == 2, true);
n = ar.Fill(-2, 4, 3);
test_bool("array.Fill(-2, 4, 3)", ar[0] == 3 && ar[1] == 3 && ar[2] != 3 && n == 2, true);
n = ar.Fill(6, 8, 4);
test_bool("array.Fill(6, 8, 4)", ar[5] != 4 && ar[6] == 4 && ar[7] == 4 && n == 2, true);
}
void test_array_push_pop(void)
{
int i;
bool failed = false;
array@int ar;
for (i = 0; i < 4; i++) {
ar.PushBack(i);
}
for (i = 3; i >= 0 && !failed; i--) {
failed = ar[i] != i;
ar.PopBack();
failed = failed || ar.Numof() != i;
}
test_bool("array.PushBack(i)/array.PopBack()", !failed, true);
ar.PopBack(); // check possible crash
}
void test_array_empty(void)
{
array@int empty_ar;
array@int full_ar[1];
test_bool("array.Empty()", empty_ar.Empty(), true);
test_bool("array.Empty()", full_ar.Empty(), false);
}
void test_array_erase(void)
{
int r;
array@int ar[2];
ar[0] = 0;
ar[1] = 1;
r = ar.Erase(0);
test_bool("array.Erase(0)", ar[0] == 1 && ar.Numof() == 1 && r, true);
r = ar.Erase(-1);
test_bool("array.Erase(-1)", ar[0] == 1 && ar.Numof() == 1 && !r, true);
r = ar.Erase(1);
test_bool("array.Erase(1)", ar[0] == 1 && ar.Numof() == 1 && !r, true);
r = ar.Erase(0);
test_bool("array.Erase(last)", ar.Empty() && r, true);
ar.Erase(0); // check possible crash
}
void print_array(ref array@int ar)
{
int i;
int n = ar.Numof();
for (i = 0; i < n; i++) {
system.Output("ar[" + string(i) + "] = " + string(ar[i]) + "\n");
}
system.Output("\n");
}
void test_array_insert(void)
{
int i;
array@int ar;
ar.Insert(0, 2);
ar.Insert(1, 0); // XXX: index is clamped to 0 here
ar.Insert(1, 1);
test_bool("array.Insert()", ar.Numof() == 3 && ar[0] == 0 && ar[1] == 1 && ar[2] == 2, true);
}
int compare_int(int a, int b)
{
return a - b;
}
void test_array_sort(void)
{
int i;
bool failed = false;
array@int ar[8];
for (i = 0; i < 8; i++) {
ar[i] = 7 - i;
}
ar.Sort(&compare_int);
for (i = 0; i < 8 && !failed; i++) {
failed = ar[i] != i;
}
test_bool("array.Sort()", !failed, true);
}
int ctor_ctr = 0;
struct array_ctor {
int i;
array_ctor() { i = ctor_ctr++; }
};
void test_array_constructors(void)
{
int i;
bool failed = false;
array@array_ctor ar[4];
ar.Realloc(8);
for (i = 0; i < 8 && !failed; i++) {
failed = ar[i].i != i;
}
test_bool("array constructors", !failed, true);
}
struct struct_with_ref {
ref inner_struct s;
};
void test_array_push_struct_with_ref(void)
{
array@struct_with_ref ar;
struct_with_ref o;
inner_struct i;
o.s <- i;
ar.PushBack(o);
// Returning from this function should not double-free i.
}
void test_arrays(void)
{
test_array_set();
test_array_rank2();
test_array_alloc();
test_array_realloc();
test_array_numof();
test_array_copy();
test_array_fill();
test_array_push_pop();
test_array_empty();
test_array_erase();
test_array_insert();
test_array_sort();
test_array_constructors();
test_array_push_struct_with_ref();
}