Add simple fuzz-harness #1537
20
.github/workflows/validate-cpp.yml
vendored
20
.github/workflows/validate-cpp.yml
vendored
@@ -31,6 +31,26 @@ jobs:
|
|||||||
- name: Unit tests
|
- name: Unit tests
|
||||||
run: ./unit_tests ${{ matrix.mode }}
|
run: ./unit_tests ${{ matrix.mode }}
|
||||||
|
|
||||||
|
|
||||||
|
build_fuzzers:
|
||||||
|
name: Build fuzzers [${{ matrix.toolchain }}][${{ matrix.mode }}]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
mode: [Debug, Release]
|
||||||
|
toolchain: [Clang]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup
|
||||||
|
uses: ./.github/actions/setup-cpp
|
||||||
|
with:
|
||||||
|
toolchain: ${{ matrix.toolchain }}
|
||||||
|
|
||||||
|
- name: Unit tests
|
||||||
|
run: ./build_fuzz_tests ${{ matrix.mode }}
|
||||||
|
|
||||||
benchmark:
|
benchmark:
|
||||||
name: Benchmark [${{ matrix.toolchain }}]
|
name: Benchmark [${{ matrix.toolchain }}]
|
||||||
runs-on: ${{ (matrix.toolchain == 'MSVC') && 'windows-latest' || 'ubuntu-latest' }}
|
runs-on: ${{ (matrix.toolchain == 'MSVC') && 'windows-latest' || 'ubuntu-latest' }}
|
||||||
|
@@ -12,6 +12,12 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/project-defaults.cmake)
|
|||||||
add_subdirectory(yoga)
|
add_subdirectory(yoga)
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
|
|
||||||
|
option(BUILD_FUZZ_TESTS "Build fuzz tests" OFF)
|
||||||
|
|
||||||
|
if ('${CMAKE_CXX_COMPILER_ID}' MATCHES 'Clang' AND BUILD_FUZZ_TESTS)
|
||||||
|
add_subdirectory(fuzz)
|
||||||
|
endif()
|
||||||
|
|
||||||
# cmake install config
|
# cmake install config
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
28
build_fuzz_tests
Executable file
28
build_fuzz_tests
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
|
#
|
||||||
|
# This source code is licensed under the MIT license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree.
|
||||||
|
|
||||||
|
if [ "$#" -eq 0 ]; then
|
||||||
|
build_type="Debug"
|
||||||
|
else
|
||||||
|
build_type="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export CC=clang
|
||||||
|
export CXX=clang++
|
||||||
|
|
||||||
|
# Make sure libc++ isn't used, as libfuzzer is linked against stdlibc++ which causes conflicts
|
||||||
|
unset CXXFLAGS
|
||||||
|
export LDFLAGS=-lstdc++
|
||||||
|
|
||||||
|
if which ninja; then
|
||||||
|
set -e
|
||||||
|
cmake -B build -S . -D BUILD_FUZZ_TESTS=ON -D CMAKE_BUILD_TYPE="$build_type" -G Ninja
|
||||||
|
else
|
||||||
|
set -e
|
||||||
|
cmake -B build -S . -D BUILD_FUZZ_TESTS=ON -D CMAKE_BUILD_TYPE="$build_type"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cmake --build build --target fuzz_layout
|
16
fuzz/CMakeLists.txt
Normal file
16
fuzz/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# If google/oss-fuzz has set the fuzzing engine
|
||||||
|
if(DEFINED ENV{LIB_FUZZING_ENGINE})
|
||||||
|
set(FUZZING_ENGINE $ENV{LIB_FUZZING_ENGINE})
|
||||||
|
set(FUZZING_COMPILE_FLAGS "")
|
||||||
|
set(FUZZING_LINK_FLAGS "${FUZZING_ENGINE}")
|
||||||
|
else()
|
||||||
|
set(FUZZING_COMPILE_FLAGS "-fsanitize=fuzzer")
|
||||||
|
set(FUZZING_LINK_FLAGS "-fsanitize=fuzzer")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(fuzz_layout fuzz_layout.cpp)
|
||||||
|
set_target_properties(fuzz_layout PROPERTIES
|
||||||
|
COMPILE_FLAGS "${FUZZING_COMPILE_FLAGS}"
|
||||||
|
LINK_FLAGS "${FUZZING_LINK_FLAGS}"
|
||||||
|
)
|
||||||
|
target_link_libraries(fuzz_layout yogacore)
|
50
fuzz/fuzz_layout.cpp
Normal file
50
fuzz/fuzz_layout.cpp
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#include <fuzzer/FuzzedDataProvider.h>
|
||||||
|
#include <yoga/Yoga.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
YGFlexDirection fuzzed_flex_direction(FuzzedDataProvider& fdp) {
|
||||||
|
return fdp.PickValueInArray({
|
||||||
|
YGFlexDirectionColumn,
|
||||||
|
YGFlexDirectionColumnReverse,
|
||||||
|
YGFlexDirectionRow,
|
||||||
|
YGFlexDirectionRowReverse,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillFuzzedTree(
|
||||||
|
FuzzedDataProvider& fdp,
|
||||||
|
const YGConfigRef& config,
|
||||||
|
const YGNodeRef& root,
|
||||||
|
|||||||
|
size_t depth = 0) {
|
||||||
|
constexpr size_t kMaxDepth = 20;
|
||||||
|
constexpr size_t kMaxChildren = 20;
|
||||||
|
|
||||||
|
if (depth > kMaxDepth) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t children = fdp.ConsumeIntegralInRange<size_t>(0, kMaxChildren);
|
||||||
|
for (size_t i = 0; i < children; i++) {
|
||||||
|
const YGNodeRef child = YGNodeNewWithConfig(config);
|
||||||
|
YGNodeStyleSetFlexDirection(root, fuzzed_flex_direction(fdp));
|
||||||
|
YGNodeStyleSetWidth(child, fdp.ConsumeFloatingPoint<float>());
|
||||||
|
YGNodeStyleSetGap(
|
||||||
|
child, YGGutterAll, fdp.ConsumeProbability<float>() * 100);
|
||||||
|
YGNodeStyleSetHeight(child, fdp.ConsumeFloatingPoint<float>());
|
||||||
|
YGNodeInsertChild(root, child, i);
|
||||||
|
FillFuzzedTree(fdp, config, child, depth + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||||
|
FuzzedDataProvider fdp(data, size);
|
||||||
|
const YGConfigRef config = YGConfigNew();
|
||||||
|
const YGNodeRef root = YGNodeNewWithConfig(config);
|
||||||
|
FillFuzzedTree(fdp, config, root);
|
||||||
|
|
||||||
|
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||||
|
|
||||||
|
YGNodeFreeRecursive(root);
|
||||||
|
YGConfigFree(config);
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user
I missed this the first time around, but
YGConfigRef
andYGNodeRef
are themselves just pointers. That also makesconst
apply to the pointer value, instead of the underlying node/config.Needed to fix a quick license header to make internal linter happy, but I'm going to make a quick ninja-edit to make that clearer.
Same for a couple other quick repo conventions around naming
No worries. Let me know if there is anything you'd like me to do here :)