mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-15 20:24:07 +00:00
fix build, add initial fuzzing processing
This commit is contained in:
parent
9e12b6cb4e
commit
c7f662dc98
@ -3,6 +3,7 @@
|
||||
#include <IO/ReadBufferFromMemory.h>
|
||||
#include <IO/ReadHelpers.h>
|
||||
|
||||
#include <DataTypes/IDataType.h>
|
||||
#include <DataTypes/DataTypeFactory.h>
|
||||
|
||||
#include <Common/MemoryTracker.h>
|
||||
|
@ -2,10 +2,10 @@ clickhouse_add_executable(lexer_fuzzer lexer_fuzzer.cpp ${SRCS})
|
||||
target_link_libraries(lexer_fuzzer PRIVATE clickhouse_parsers)
|
||||
|
||||
clickhouse_add_executable(select_parser_fuzzer select_parser_fuzzer.cpp ${SRCS})
|
||||
target_link_libraries(select_parser_fuzzer PRIVATE clickhouse_parsers dbms)
|
||||
target_link_libraries(select_parser_fuzzer PRIVATE clickhouse_parsers clickhouse_functions dbms)
|
||||
|
||||
clickhouse_add_executable(create_parser_fuzzer create_parser_fuzzer.cpp ${SRCS})
|
||||
target_link_libraries(create_parser_fuzzer PRIVATE clickhouse_parsers dbms)
|
||||
target_link_libraries(create_parser_fuzzer PRIVATE clickhouse_parsers clickhouse_functions dbms)
|
||||
|
||||
add_subdirectory(codegen_fuzzer)
|
||||
|
||||
|
@ -47,4 +47,4 @@ target_compile_options (codegen_select_fuzzer PRIVATE -Wno-newline-eof)
|
||||
target_link_libraries(protoc ch_contrib::fuzzer)
|
||||
|
||||
target_include_directories(codegen_select_fuzzer SYSTEM BEFORE PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
target_link_libraries(codegen_select_fuzzer PRIVATE ch_contrib::protobuf_mutator ch_contrib::protoc dbms)
|
||||
target_link_libraries(codegen_select_fuzzer PRIVATE ch_contrib::protobuf_mutator ch_contrib::protoc clickhouse_functions dbms)
|
||||
|
@ -4,19 +4,70 @@ import configparser
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
DEBUGGER = os.getenv("DEBUGGER", "")
|
||||
FUZZER_ARGS = os.getenv("FUZZER_ARGS", "")
|
||||
|
||||
def report(source: str, reason: str, call_stack: list, test_unit: str):
|
||||
print(f"########### REPORT: {source} {reason} {test_unit}")
|
||||
for line in call_stack:
|
||||
print(f" {line}")
|
||||
print("########### END OF REPORT ###########")
|
||||
|
||||
def process_fuzzer_output(output: str):
|
||||
pass
|
||||
|
||||
def process_error(error: str):
|
||||
ERROR = r'^==\d+== ERROR: (\S+): (.*)'
|
||||
error_source = ''
|
||||
error_reason = ''
|
||||
SUMMARY = r'^SUMMARY: '
|
||||
TEST_UNIT_LINE = r"artifact_prefix='.*/'; Test unit written to (.*)"
|
||||
test_unit = ''
|
||||
CALL_STACK_LINE = r'^\s+(#\d+.*)'
|
||||
call_stack = []
|
||||
is_call_stack = False
|
||||
|
||||
for line_num, line in enumerate(error.splitlines(), 1):
|
||||
|
||||
if is_call_stack:
|
||||
match = re.search(CALL_STACK_LINE, line)
|
||||
if match:
|
||||
call_stack.append(match.group(1))
|
||||
continue
|
||||
else:
|
||||
if re.search(SUMMARY, line):
|
||||
is_call_stack = False
|
||||
continue
|
||||
|
||||
if not call_stack and not is_call_stack:
|
||||
match = re.search(ERROR, line)
|
||||
if match:
|
||||
error_source = match.group(1)
|
||||
error_reason = match.group(2)
|
||||
is_call_stack = True
|
||||
continue
|
||||
|
||||
match = re.search(TEST_UNIT_LINE, line)
|
||||
if match:
|
||||
test_unit = match.group(1)
|
||||
|
||||
report(error_source, error_reason, call_stack, test_unit)
|
||||
|
||||
def run_fuzzer(fuzzer: str):
|
||||
logging.info("Running fuzzer %s...", fuzzer)
|
||||
|
||||
corpus_dir = f"{fuzzer}.in"
|
||||
with Path(corpus_dir) as path:
|
||||
seed_corpus_dir = f"{fuzzer}.in"
|
||||
with Path(seed_corpus_dir) as path:
|
||||
if not path.exists() or not path.is_dir():
|
||||
corpus_dir = ""
|
||||
seed_corpus_dir = ""
|
||||
|
||||
active_corpus_dir = f"{fuzzer}.corpus"
|
||||
if not os.path.exists(active_corpus_dir):
|
||||
os.makedirs(active_corpus_dir)
|
||||
|
||||
|
||||
options_file = f"{fuzzer}.options"
|
||||
custom_libfuzzer_options = ""
|
||||
@ -53,7 +104,7 @@ def run_fuzzer(fuzzer: str):
|
||||
for key, value in parser["fuzzer_arguments"].items()
|
||||
)
|
||||
|
||||
cmd_line = f"{DEBUGGER} ./{fuzzer} {FUZZER_ARGS} {corpus_dir}"
|
||||
cmd_line = f"{DEBUGGER} ./{fuzzer} {FUZZER_ARGS} {active_corpus_dir} {seed_corpus_dir}"
|
||||
if custom_libfuzzer_options:
|
||||
cmd_line += f" {custom_libfuzzer_options}"
|
||||
if fuzzer_arguments:
|
||||
@ -65,8 +116,23 @@ def run_fuzzer(fuzzer: str):
|
||||
cmd_line += " < /dev/null"
|
||||
|
||||
logging.info("...will execute: %s", cmd_line)
|
||||
subprocess.check_call(cmd_line, shell=True)
|
||||
#subprocess.check_call(cmd_line, shell=True)
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
cmd_line,
|
||||
stderr=subprocess.PIPE,
|
||||
stdout=subprocess.DEVNULL,
|
||||
text=True,
|
||||
check=True,
|
||||
shell=True
|
||||
)
|
||||
except subprocess.CalledProcessError as e:
|
||||
# print("Command failed with error:", e)
|
||||
print("Stderr output:", e.stderr)
|
||||
process_error(e.stderr)
|
||||
else:
|
||||
process_fuzzer_output(result.stderr)
|
||||
|
||||
def main():
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
Loading…
Reference in New Issue
Block a user