diff options
Diffstat (limited to 'src/tests/fuzz')
-rw-r--r-- | src/tests/fuzz/lut.c | 24 | ||||
-rw-r--r-- | src/tests/fuzz/options.c | 26 | ||||
-rw-r--r-- | src/tests/fuzz/shaders.c | 166 | ||||
-rw-r--r-- | src/tests/fuzz/user_shaders.c | 28 |
4 files changed, 244 insertions, 0 deletions
diff --git a/src/tests/fuzz/lut.c b/src/tests/fuzz/lut.c new file mode 100644 index 0000000..24e5f89 --- /dev/null +++ b/src/tests/fuzz/lut.c @@ -0,0 +1,24 @@ +#include "../tests.h" + +#include <libplacebo/shaders/lut.h> + +__AFL_FUZZ_INIT(); + +#pragma clang optimize off + +int main() +{ + struct pl_custom_lut *lut; + +#ifdef __AFL_HAVE_MANUAL_CONTROL + __AFL_INIT(); +#endif + + unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF; + + while (__AFL_LOOP(100000)) { + size_t len = __AFL_FUZZ_TESTCASE_LEN; + lut = pl_lut_parse_cube(NULL, (char *) buf, len); + pl_lut_free(&lut); + } +} diff --git a/src/tests/fuzz/options.c b/src/tests/fuzz/options.c new file mode 100644 index 0000000..c88e462 --- /dev/null +++ b/src/tests/fuzz/options.c @@ -0,0 +1,26 @@ +#include "../tests.h" + +#include <libplacebo/options.h> + +__AFL_FUZZ_INIT(); + +#pragma clang optimize off + +int main() +{ + pl_options opts = pl_options_alloc(NULL); + +#ifdef __AFL_HAVE_MANUAL_CONTROL + __AFL_INIT(); +#endif + + unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF; + + while (__AFL_LOOP(100000)) { + size_t len = __AFL_FUZZ_TESTCASE_LEN; + buf[len - 1] = '\0'; // ensure proper null termination + pl_options_load(opts, (const char *) buf); + pl_options_save(opts); + pl_options_reset(opts, NULL); + } +} diff --git a/src/tests/fuzz/shaders.c b/src/tests/fuzz/shaders.c new file mode 100644 index 0000000..2e3e92c --- /dev/null +++ b/src/tests/fuzz/shaders.c @@ -0,0 +1,166 @@ +#include "../tests.h" +#include "shaders.h" + +#include <libplacebo/dummy.h> +#include <libplacebo/shaders/colorspace.h> +#include <libplacebo/shaders/custom.h> +#include <libplacebo/shaders/sampling.h> + +__AFL_FUZZ_INIT(); + +#pragma clang optimize off + +int main() +{ + pl_gpu gpu = pl_gpu_dummy_create(NULL, NULL); + +#define WIDTH 64 +#define HEIGHT 64 +#define COMPS 4 + + static const float empty[HEIGHT][WIDTH][COMPS] = {0}; + + struct pl_sample_src src = { + .tex = pl_tex_create(gpu, pl_tex_params( + .format = pl_find_fmt(gpu, PL_FMT_FLOAT, COMPS, 0, 32, PL_FMT_CAP_SAMPLEABLE), + .initial_data = empty, + .sampleable = true, + .w = WIDTH, + .h = HEIGHT, + )), + .new_w = WIDTH * 2, + .new_h = HEIGHT * 2, + }; + + if (!src.tex) + return 1; + +#ifdef __AFL_HAVE_MANUAL_CONTROL + __AFL_INIT(); +#endif + + unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF; + while (__AFL_LOOP(10000)) { + +#define STACK_SIZE 16 + pl_shader stack[STACK_SIZE] = {0}; + int idx = 0; + + stack[0] = pl_shader_alloc(NULL, pl_shader_params( + .gpu = gpu, + )); + + pl_shader sh = stack[idx]; + pl_shader_obj polar = NULL, ortho = NULL, peak = NULL, dither = NULL; + + size_t len = __AFL_FUZZ_TESTCASE_LEN; + for (size_t pos = 0; pos < len; pos++) { + switch (buf[pos]) { + // Sampling steps + case 'S': + pl_shader_sample_direct(sh, &src); + break; + case 'D': + pl_shader_deband(sh, &src, NULL); + break; + case 'P': + pl_shader_sample_polar(sh, &src, pl_sample_filter_params( + .filter = pl_filter_ewa_lanczos, + .lut = &polar, + )); + break; + case 'O': ; + struct pl_sample_src srcfix = src; + srcfix.new_w = WIDTH; + pl_shader_sample_ortho2(sh, &srcfix, pl_sample_filter_params( + .filter = pl_filter_spline36, + .lut = &ortho, + )); + break; + case 'X': + pl_shader_custom(sh, &(struct pl_custom_shader) { + .input = PL_SHADER_SIG_NONE, + .output = PL_SHADER_SIG_COLOR, + .body = "// merge subpasses", + }); + break; + + // Colorspace transformation steps + case 'y': { + struct pl_color_repr repr = pl_color_repr_jpeg; + pl_shader_decode_color(sh, &repr, NULL); + break; + } + case 'p': + pl_shader_detect_peak(sh, pl_color_space_hdr10, &peak, NULL); + break; + case 'm': + pl_shader_color_map(sh, NULL, pl_color_space_bt709, + pl_color_space_monitor, NULL, false); + break; + case 't': + pl_shader_color_map(sh, NULL, pl_color_space_hdr10, + pl_color_space_monitor, &peak, false); + break; + case 'd': + pl_shader_dither(sh, 8, &dither, pl_dither_params( + // Picked to speed up calculation + .method = PL_DITHER_ORDERED_LUT, + .lut_size = 2, + )); + break; + + // Push and pop subshader commands + case '(': + if (idx+1 == STACK_SIZE) + goto invalid; + + idx++; + if (!stack[idx]) { + stack[idx] = pl_shader_alloc(NULL, pl_shader_params( + .gpu = gpu, + .id = idx, + )); + } + sh = stack[idx]; + break; + + case ')': + if (idx == 0) + goto invalid; + + idx--; + sh_subpass(stack[idx], stack[idx + 1]); + pl_shader_reset(stack[idx + 1], pl_shader_params( + .gpu = gpu, + .id = idx + 1, + )); + sh = stack[idx]; + break; + + default: + goto invalid; + } + } + + // Merge remaining shaders + while (idx > 0) { + sh_subpass(stack[idx - 1], stack[idx]); + idx--; + } + + pl_shader_finalize(stack[0]); + +invalid: + for (int i = 0; i < STACK_SIZE; i++) + pl_shader_free(&stack[i]); + + pl_shader_obj_destroy(&polar); + pl_shader_obj_destroy(&ortho); + pl_shader_obj_destroy(&peak); + pl_shader_obj_destroy(&dither); + } + + pl_tex_destroy(gpu, &src.tex); + pl_gpu_dummy_destroy(&gpu); +} diff --git a/src/tests/fuzz/user_shaders.c b/src/tests/fuzz/user_shaders.c new file mode 100644 index 0000000..bbb98c8 --- /dev/null +++ b/src/tests/fuzz/user_shaders.c @@ -0,0 +1,28 @@ +#include "../tests.h" + +#include <libplacebo/dummy.h> +#include <libplacebo/shaders/custom.h> + +__AFL_FUZZ_INIT(); + +#pragma clang optimize off + +int main() +{ + pl_gpu gpu = pl_gpu_dummy_create(NULL, NULL); + const struct pl_hook *hook; + +#ifdef __AFL_HAVE_MANUAL_CONTROL + __AFL_INIT(); +#endif + + unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF; + + while (__AFL_LOOP(100000)) { + size_t len = __AFL_FUZZ_TESTCASE_LEN; + hook = pl_mpv_user_shader_parse(gpu, (char *) buf, len); + pl_mpv_user_shader_destroy(&hook); + } + + pl_gpu_dummy_destroy(&gpu); +} |