rizin/test/unit/test_skyline.c
GustavoLCR cfc504e1e9
Fix #1506 - Fix unsigned integer overflow in RzIO cache skyline (#1512)
* Fix #1506 - Fix unsigned integer overflow in RzIO cache skyline
* Add overflow check to `RzSkyline` APIs
2021-08-25 16:36:20 +08:00

105 lines
4.8 KiB
C

// SPDX-FileCopyrightText: 2020 GustavoLCR <gugulcr@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_util.h>
#include <rz_skyline.h>
#include "minunit.h"
bool test_rz_skyline(void) {
RzSkyline sky;
rz_skyline_init(&sky);
rz_skyline_add(&sky, (RzInterval){ 0, 1 }, (void *)1);
mu_assert_true(rz_skyline_contains(&sky, 0), "Skyline should contain 0");
mu_assert_false(rz_skyline_contains(&sky, 1), "Skyline shouldn't contain 1");
rz_skyline_add(&sky, (RzInterval){ 2, 4 }, (void *)2);
mu_assert_true(rz_skyline_contains(&sky, 2), "Skyline should contain 2");
mu_assert_eq((size_t)rz_skyline_get(&sky, 0), 1, "rz_skyline_get should get first map");
mu_assert_eq((size_t)rz_skyline_get(&sky, 2), 2, "rz_skyline_get should get second map");
mu_assert_eq((size_t)rz_skyline_get(&sky, 3), 2, "rz_skyline_get should get second map");
mu_assert_eq((size_t)rz_skyline_get_intersect(&sky, 1, 2), 2, "rz_skyline_get_intersect should get second map");
rz_skyline_add(&sky, (RzInterval){ 0, 3 }, (void *)3);
mu_assert_true(rz_skyline_contains(&sky, 0) && rz_skyline_contains(&sky, 3),
"Skyline should still contain 0 to 3 after overlap");
mu_assert_eq((size_t)rz_skyline_get(&sky, 0), 3, "rz_skyline_get should get third map");
rz_skyline_add(&sky, (RzInterval){ UT64_MAX - 1, 2 }, (void *)4);
mu_assert_true(rz_skyline_contains(&sky, UT64_MAX), "Skyline should contain UT64_MAX");
mu_assert_eq((size_t)rz_skyline_get(&sky, UT64_MAX), 4, "rz_skyline_get should get fourth map");
rz_skyline_fini(&sky);
rz_skyline_init(&sky);
rz_skyline_add(&sky, (RzInterval){ 1, 1 }, (void *)1);
mu_assert_false(rz_skyline_contains(&sky, 0), "Skyline shouldn't contain 0");
rz_skyline_fini(&sky);
mu_end;
}
bool test_rz_skyline_overlaps(void) {
RzSkyline sky;
rz_skyline_init(&sky);
rz_skyline_add(&sky, (RzInterval){ 10, 10 }, (void *)1);
const RzSkylineItem *item = rz_skyline_get_item(&sky, 10);
mu_assert_eq((size_t)item->user, 1, "rz_skyline_get should get 1st map");
rz_skyline_add(&sky, (RzInterval){ 9, 2 }, (void *)2);
item = rz_skyline_get_item(&sky, 10);
mu_assert_eq((size_t)item->user, 2, "rz_skyline_get should get 2nd map");
rz_skyline_add(&sky, (RzInterval){ 19, 2 }, (void *)3);
item = rz_skyline_get_item(&sky, 19);
mu_assert_eq((size_t)item->user, 3, "rz_skyline_get should get 3rd map");
rz_skyline_add(&sky, (RzInterval){ 14, 3 }, (void *)4);
item = rz_skyline_get_item(&sky, 14);
mu_assert_eq((size_t)item->user, 4, "rz_skyline_get should get 4th map");
item = rz_skyline_get_item(&sky, 12);
mu_assert_eq((size_t)item->user, 1, "rz_skyline_get should get 1st map head after it was overlapped");
mu_assert_eq(rz_itv_begin(item->itv), 11, "1st map head should start at 11");
mu_assert_eq(rz_itv_end(item->itv), 14, "1st map head should end at 14");
item = rz_skyline_get_item(&sky, 17);
mu_assert_eq((size_t)item->user, 1, "rz_skyline_get should get 1st map tail after it was overlapped");
mu_assert_eq(rz_itv_begin(item->itv), 17, "1st map tail should start at 17");
mu_assert_eq(rz_itv_end(item->itv), 19, "1st map tail should end at 19");
rz_skyline_add(&sky, (RzInterval){ 0, 30 }, (void *)5);
mu_assert_eq(rz_vector_len(&sky.v), 1, "5th map should cover entire skyline");
item = rz_skyline_get_item(&sky, 10);
mu_assert_eq((size_t)item->user, 5, "rz_skyline_get should get 5th map");
mu_assert_eq(rz_itv_size(item->itv), 30, "5th map should have size of 30");
rz_skyline_add(&sky, (RzInterval){ 0, 10 }, (void *)6);
rz_skyline_add(&sky, (RzInterval){ 10, 10 }, (void *)7);
rz_skyline_add(&sky, (RzInterval){ 20, 10 }, (void *)8);
rz_skyline_add(&sky, (RzInterval){ 30, 10 }, (void *)9);
mu_assert_eq(rz_vector_len(&sky.v), 4, "maps 5 through 9 should be the only ones existing");
rz_skyline_add(&sky, (RzInterval){ 5, 30 }, (void *)10);
mu_assert_eq(rz_vector_len(&sky.v), 3, "10th map should remove all maps it covered, leaving a head and a tail");
item = rz_skyline_get_item(&sky, 35);
mu_assert_eq(rz_itv_begin(item->itv), 35, "9th map should begin at 35 after 10th covered its beginning");
rz_skyline_add(&sky, (RzInterval){ 3, 5 }, (void *)11);
item = rz_skyline_get_item(&sky, 0);
mu_assert_eq(rz_itv_size(item->itv), 3, "6th map should have size of 3 after 11th covered its end");
item = rz_skyline_get_item(&sky, 20);
mu_assert_eq(rz_itv_begin(item->itv), 8, "10th map should begin at 8 after 11th covered its beginning");
rz_skyline_add(&sky, (RzInterval){ 3, 5 }, (void *)12);
item = rz_skyline_get_item(&sky, 3);
bool cond = rz_vector_len(&sky.v) == 4 && rz_itv_begin(item->itv) == 3 && rz_itv_end(item->itv) == 8 && (size_t)item->user == 12;
mu_assert_true(cond, "12th map should completely cover 11th");
rz_skyline_fini(&sky);
mu_end;
}
static int all_tests(void) {
mu_run_test(test_rz_skyline);
mu_run_test(test_rz_skyline_overlaps);
return tests_passed != tests_run;
}
mu_main(all_tests)