/src/shaderc_fdp_fuzzer.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2024 Google LLC |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include <cstring> |
16 | | #include <iostream> |
17 | | #include <string> |
18 | | #include <vector> |
19 | | |
20 | | #include <fuzzer/FuzzedDataProvider.h> |
21 | | |
22 | | #include <shaderc/shaderc.h> |
23 | | #include <shaderc/shaderc.hpp> |
24 | | |
25 | | const std::array<shaderc_optimization_level, 3> OptArray = { |
26 | | shaderc_optimization_level_zero, |
27 | | shaderc_optimization_level_size, |
28 | | shaderc_optimization_level_performance, |
29 | | }; |
30 | | |
31 | | const std::array<shaderc_shader_kind, 44> KindArray = { |
32 | | shaderc_vertex_shader, |
33 | | shaderc_fragment_shader, |
34 | | shaderc_compute_shader, |
35 | | shaderc_geometry_shader, |
36 | | shaderc_tess_control_shader, |
37 | | shaderc_tess_evaluation_shader, |
38 | | |
39 | | shaderc_glsl_vertex_shader, |
40 | | shaderc_glsl_fragment_shader, |
41 | | shaderc_glsl_compute_shader, |
42 | | shaderc_glsl_geometry_shader, |
43 | | shaderc_glsl_tess_control_shader, |
44 | | shaderc_glsl_tess_evaluation_shader, |
45 | | |
46 | | shaderc_glsl_infer_from_source, |
47 | | shaderc_glsl_default_vertex_shader, |
48 | | shaderc_glsl_default_fragment_shader, |
49 | | shaderc_glsl_default_compute_shader, |
50 | | shaderc_glsl_default_geometry_shader, |
51 | | shaderc_glsl_default_tess_control_shader, |
52 | | shaderc_glsl_default_tess_evaluation_shader, |
53 | | shaderc_spirv_assembly, |
54 | | shaderc_raygen_shader, |
55 | | shaderc_anyhit_shader, |
56 | | shaderc_closesthit_shader, |
57 | | shaderc_miss_shader, |
58 | | shaderc_intersection_shader, |
59 | | shaderc_callable_shader, |
60 | | |
61 | | shaderc_glsl_raygen_shader, |
62 | | shaderc_glsl_anyhit_shader, |
63 | | shaderc_glsl_closesthit_shader, |
64 | | shaderc_glsl_miss_shader, |
65 | | |
66 | | shaderc_glsl_intersection_shader, |
67 | | shaderc_glsl_callable_shader, |
68 | | shaderc_glsl_default_raygen_shader, |
69 | | shaderc_glsl_default_anyhit_shader, |
70 | | shaderc_glsl_default_closesthit_shader, |
71 | | shaderc_glsl_default_miss_shader, |
72 | | shaderc_glsl_default_intersection_shader, |
73 | | shaderc_glsl_default_callable_shader, |
74 | | shaderc_task_shader, |
75 | | shaderc_mesh_shader, |
76 | | shaderc_glsl_task_shader, |
77 | | shaderc_glsl_mesh_shader, |
78 | | shaderc_glsl_default_task_shader, |
79 | | shaderc_glsl_default_mesh_shader, |
80 | | }; |
81 | | |
82 | | const std::array<shaderc_source_language, 2> LangArray = { |
83 | | shaderc_source_language_glsl, |
84 | | shaderc_source_language_hlsl, |
85 | | }; |
86 | | |
87 | 5.12k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
88 | 5.12k | FuzzedDataProvider fdp(data, size); |
89 | | |
90 | | // Prepare GLSL shader content with valid version |
91 | 5.12k | shaderc_shader_kind kind = fdp.PickValueInArray(KindArray); |
92 | | |
93 | | // Prepare Compiler and options |
94 | 5.12k | shaderc::Compiler compiler; |
95 | 5.12k | shaderc::CompileOptions options; |
96 | 5.12k | options.SetOptimizationLevel(fdp.PickValueInArray(OptArray)); |
97 | | |
98 | 5.12k | options.SetHlslFunctionality1(fdp.ConsumeBool()); |
99 | 5.12k | options.SetHlsl16BitTypes(fdp.ConsumeBool()); |
100 | 5.12k | options.SetInvertY(fdp.ConsumeBool()); |
101 | 5.12k | options.SetNanClamp(fdp.ConsumeBool()); |
102 | 5.12k | options.SetPreserveBindings(fdp.ConsumeBool()); |
103 | 5.12k | options.SetAutoMapLocations(fdp.ConsumeBool()); |
104 | 5.12k | options.SetHlslOffsets(fdp.ConsumeBool()); |
105 | 5.12k | options.SetAutoBindUniforms(fdp.ConsumeBool()); |
106 | 5.12k | options.SetSourceLanguage(fdp.PickValueInArray(LangArray)); |
107 | | |
108 | | // Get the actual content |
109 | 5.12k | std::string shader_content = fdp.ConsumeRandomLengthString(); |
110 | | |
111 | | // Preprocessing |
112 | 5.12k | shaderc::PreprocessedSourceCompilationResult preprocess_result = |
113 | 5.12k | compiler.PreprocessGlsl(shader_content, kind, "input.glsl", options); |
114 | 5.12k | if (preprocess_result.GetCompilationStatus() == |
115 | 5.12k | shaderc_compilation_status_success) { |
116 | 3.31k | std::string preprocessed_code(preprocess_result.cbegin(), |
117 | 3.31k | preprocess_result.cend()); |
118 | 3.31k | } else { |
119 | 1.80k | return 0; |
120 | 1.80k | } |
121 | | |
122 | | // Compile to SPIR-V binary |
123 | 3.31k | shaderc::SpvCompilationResult binary_result = |
124 | 3.31k | compiler.CompileGlslToSpv(shader_content, kind, "input.glsl", options); |
125 | 3.31k | if (binary_result.GetCompilationStatus() == |
126 | 3.31k | shaderc_compilation_status_success) { |
127 | 233 | std::vector<uint32_t> spirv_binary(binary_result.cbegin(), |
128 | 233 | binary_result.cend()); |
129 | 233 | } |
130 | | |
131 | | // Compile to SPIR-V assembly |
132 | 3.31k | shaderc::AssemblyCompilationResult assembly_result = |
133 | 3.31k | compiler.CompileGlslToSpvAssembly(shader_content, kind, "input.glsl", |
134 | 3.31k | options); |
135 | 3.31k | if (assembly_result.GetCompilationStatus() == |
136 | 3.31k | shaderc_compilation_status_success) { |
137 | 233 | std::string spirv_assembly(assembly_result.cbegin(), |
138 | 233 | assembly_result.cend()); |
139 | 233 | } |
140 | | |
141 | | // Compile with C API |
142 | 3.31k | shaderc_compiler_t c_compiler = shaderc_compiler_initialize(); |
143 | 3.31k | shaderc_compilation_result_t c_result = shaderc_compile_into_spv( |
144 | 3.31k | c_compiler, shader_content.c_str(), shader_content.size(), kind, |
145 | 3.31k | "main.vert", "main", nullptr); |
146 | | |
147 | 3.31k | if (shaderc_result_get_compilation_status(c_result) == |
148 | 3.31k | shaderc_compilation_status_success) { |
149 | 0 | std::vector<uint32_t> spirv_c_binary(shaderc_result_get_length(c_result) / |
150 | 0 | sizeof(uint32_t)); |
151 | 0 | std::memcpy(spirv_c_binary.data(), shaderc_result_get_bytes(c_result), |
152 | 0 | shaderc_result_get_length(c_result)); |
153 | 0 | } |
154 | 3.31k | shaderc_result_release(c_result); |
155 | 3.31k | shaderc_compiler_release(c_compiler); |
156 | | |
157 | 3.31k | return 0; |
158 | 5.12k | } |