summaryrefslogtreecommitdiffstats
path: root/src/tests/fuzz
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/fuzz')
-rw-r--r--src/tests/fuzz/lut.c24
-rw-r--r--src/tests/fuzz/options.c26
-rw-r--r--src/tests/fuzz/shaders.c166
-rw-r--r--src/tests/fuzz/user_shaders.c28
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);
+}