1*592efe25SPierre Pronchery /* 2*592efe25SPierre Pronchery * oom.h 3*592efe25SPierre Pronchery * Exhaustive allocation-failure test driver, built on the fuzzer/alloc-inject 4*592efe25SPierre Pronchery * fault injector. 5*592efe25SPierre Pronchery * 6*592efe25SPierre Pronchery * SPDX-License-Identifier: pkgconf 7*592efe25SPierre Pronchery * 8*592efe25SPierre Pronchery * Copyright (c) 2026 pkgconf authors (see AUTHORS). 9*592efe25SPierre Pronchery * 10*592efe25SPierre Pronchery * Permission to use, copy, modify, and/or distribute this software for any 11*592efe25SPierre Pronchery * purpose with or without fee is hereby granted, provided that the above 12*592efe25SPierre Pronchery * copyright notice and this permission notice appear in all copies. 13*592efe25SPierre Pronchery * 14*592efe25SPierre Pronchery * This software is provided 'as is' and without any warranty, express or 15*592efe25SPierre Pronchery * implied. In no event shall the authors be liable for any damages arising 16*592efe25SPierre Pronchery * from the use of this software. 17*592efe25SPierre Pronchery */ 18*592efe25SPierre Pronchery 19*592efe25SPierre Pronchery #ifndef TEST_API_OOM_H 20*592efe25SPierre Pronchery #define TEST_API_OOM_H 21*592efe25SPierre Pronchery 22*592efe25SPierre Pronchery #include "test-api.h" 23*592efe25SPierre Pronchery #include "alloc-inject.h" 24*592efe25SPierre Pronchery 25*592efe25SPierre Pronchery /* 26*592efe25SPierre Pronchery * Exhaustively fail each successive allocation an expression makes until it can 27*592efe25SPierre Pronchery * complete with none failing. Every injected failure must be reported 28*592efe25SPierre Pronchery * gracefully (NULL for OOM_TEST_PTR, false for OOM_TEST_BOOL); on the run where 29*592efe25SPierre Pronchery * no allocation fails the value succeeds and the loop ends. Under ASAN this 30*592efe25SPierre Pronchery * also asserts each partial-construction error path leaks nothing. 31*592efe25SPierre Pronchery */ 32*592efe25SPierre Pronchery #define OOM_TEST_PTR(objvar, make_expr, free_stmt) \ 33*592efe25SPierre Pronchery do { \ 34*592efe25SPierre Pronchery for (unsigned long _oom_n = 1; ; _oom_n++) \ 35*592efe25SPierre Pronchery { \ 36*592efe25SPierre Pronchery alloc_inject_arm(_oom_n); \ 37*592efe25SPierre Pronchery (objvar) = (make_expr); \ 38*592efe25SPierre Pronchery bool _oom_f = alloc_inject_fired(); \ 39*592efe25SPierre Pronchery alloc_inject_disarm(); \ 40*592efe25SPierre Pronchery if (!_oom_f) { free_stmt; break; } \ 41*592efe25SPierre Pronchery TEST_ASSERT_NULL(objvar); \ 42*592efe25SPierre Pronchery free_stmt; \ 43*592efe25SPierre Pronchery } \ 44*592efe25SPierre Pronchery } while (0) 45*592efe25SPierre Pronchery 46*592efe25SPierre Pronchery #define OOM_TEST_BOOL(make_expr) \ 47*592efe25SPierre Pronchery do { \ 48*592efe25SPierre Pronchery for (unsigned long _oom_n = 1; ; _oom_n++) \ 49*592efe25SPierre Pronchery { \ 50*592efe25SPierre Pronchery alloc_inject_arm(_oom_n); \ 51*592efe25SPierre Pronchery bool _oom_ok = (make_expr); \ 52*592efe25SPierre Pronchery bool _oom_f = alloc_inject_fired(); \ 53*592efe25SPierre Pronchery alloc_inject_disarm(); \ 54*592efe25SPierre Pronchery if (!_oom_f) { TEST_ASSERT_TRUE(_oom_ok); break; } \ 55*592efe25SPierre Pronchery TEST_ASSERT_FALSE(_oom_ok); \ 56*592efe25SPierre Pronchery } \ 57*592efe25SPierre Pronchery } while (0) 58*592efe25SPierre Pronchery 59*592efe25SPierre Pronchery #endif // TEST_API_OOM_H 60