mirror of
https://github.com/Tencent/ncnn.git
synced 2026-10-18 21:54:39 +08:00
4366038c23
* fix spirv compile failure diagnostics read past shader buffer (#6881) the shader source slice passed to glslang (comp_datas[3]) is not null-terminated, since the .comp_data arrays generated by ncnn_generate_shader_comp_header.cmake are hex-encoded without a trailing 0x00. the error-printing path in compile_spirv_module() scanned it with strchr() and checked *p != '\0', causing an out-of-bounds read and garbled diagnostics whenever a shader fails to compile. bound the scan with memchr() using the known source length and print the trailing partial line with %.*s instead of relying on null-termination. verified with asan: before, a broken non-null- terminated shader source reports a stack-buffer-overflow in compile_spirv_module(); after, the error path prints correctly with no overrun. * fix bounded shader version parsing and add regression tests --------- Signed-off-by: lazypool <lazypool@proton.me> Co-authored-by: Marcin Sochacki <136440930+marcin-sochacki@users.noreply.github.com> Co-authored-by: nihui <nihuini@tencent.com>
75 lines
2.5 KiB
C++
75 lines
2.5 KiB
C++
// Copyright 2026 Tencent
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
#include "gpu.h"
|
|
#include "testutil.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
static int test_compile_spirv_module(const char* source, int expected, int comp_data_size = -1)
|
|
{
|
|
const int source_size = strlen(source);
|
|
char* comp_data = new char[source_size];
|
|
memcpy(comp_data, source, source_size);
|
|
|
|
if (comp_data_size == -1)
|
|
comp_data_size = source_size;
|
|
|
|
ncnn::Option opt;
|
|
opt.use_fp16_packed = false;
|
|
opt.use_fp16_storage = false;
|
|
opt.use_fp16_arithmetic = false;
|
|
|
|
std::vector<uint32_t> spirv;
|
|
int ret = ncnn::compile_spirv_module(comp_data, comp_data_size, opt, spirv);
|
|
delete[] comp_data;
|
|
|
|
if (ret != expected)
|
|
{
|
|
fprintf(stderr, "test_compile_spirv_module failed ret=%d expected=%d comp_data_size=%d source=%s\n", ret, expected, comp_data_size, source);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test_compile_spirv_module_0()
|
|
{
|
|
return 0
|
|
|| test_compile_spirv_module("#version 450\nlayout(local_size_x = 1) in;\nvoid main() {}", 0)
|
|
|| test_compile_spirv_module("#version 450\nlayout(local_size_x = 1) in;\nvoid main() {}\n", 0)
|
|
|| test_compile_spirv_module("#version 450\r\nlayout(local_size_x = 1) in;\r\nvoid main() {}", 0)
|
|
|| test_compile_spirv_module("#version 450\rlayout(local_size_x = 1) in;\rvoid main() {}", 0)
|
|
|| test_compile_spirv_module("// leading comment\n#version\t450\n \t\r\nlayout(local_size_x = 1) in;\nvoid main() {}", 0)
|
|
|| test_compile_spirv_module("#version 450\n", 0)
|
|
|| test_compile_spirv_module("#version 450\n \t\r\n", 0)
|
|
|| test_compile_spirv_module("#version 450\n #error outside source", 0, 13);
|
|
}
|
|
|
|
static int test_compile_spirv_module_1()
|
|
{
|
|
return 0
|
|
|| test_compile_spirv_module("", -1)
|
|
|| test_compile_spirv_module("#version", -1)
|
|
|| test_compile_spirv_module("#version \t", -1)
|
|
|| test_compile_spirv_module("#version +", -1)
|
|
|| test_compile_spirv_module("#version nope\n", -1)
|
|
|| test_compile_spirv_module("void main() {}", -1)
|
|
|| test_compile_spirv_module("x#version 450\n", -1)
|
|
|| test_compile_spirv_module("#version 450\n#error test", -1)
|
|
|| test_compile_spirv_module("#version 450\n#error test\n", -1);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
SRAND(7767517);
|
|
|
|
if (ncnn::get_gpu_count() == 0)
|
|
return 0;
|
|
|
|
return 0
|
|
|| test_compile_spirv_module_0()
|
|
|| test_compile_spirv_module_1();
|
|
}
|