Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,31 @@ if(AVIF_LIB_USE_CXX OR AVIF_BUILD_APPS OR (AVIF_BUILD_TESTS AND (AVIF_FUZZTEST O
enable_language(CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-Wunsafe-buffer-usage AVIF_HAVE_WUNSAFE_BUFFER_USAGE)
endif()
endif()

# Opt a list of C++ source files into the -Wunsafe-buffer-usage diagnostic
# (the first step of adopting the Safe Buffers Programming Model). Apply only
# to .cc files that have been audited to be free of raw pointer arithmetic and
# raw-pointer indexing; new code added to those files must keep them clean.
# The libc-call subgroup (Clang 17+) is disabled because it fires on functions
# such as strdup() that are used in third-party headers (e.g. libargparse) we
# do not own; our own code avoids those by convention.
# No-op on toolchains where the flag is not available (Clang < 16, GCC, MSVC).
function(avif_enable_safe_buffers_warning)
if(AVIF_HAVE_WUNSAFE_BUFFER_USAGE)
set_source_files_properties(
${ARGN} PROPERTIES COMPILE_OPTIONS
"-Wunsafe-buffer-usage;-Wno-unsafe-buffer-usage-in-libc-call"
)
endif()
endfunction()

if(AVIF_ENABLE_COMPLIANCE_WARDEN)
avif_enable_safe_buffers_warning(src/compliance.cc)
endif()

set_target_properties(avif_obj PROPERTIES C_VISIBILITY_PRESET hidden)
Expand Down Expand Up @@ -723,6 +748,7 @@ if(AVIF_BUILD_APPS)
apps/avifgainmaputil/program_command.cc
apps/avifgainmaputil/swapbase_command.cc
)
avif_enable_safe_buffers_warning(${AVIFGAINMAPUTIL_SRCS})

add_executable(avifgainmaputil "${AVIFGAINMAPUTIL_SRCS}")
if(WIN32)
Expand Down
14 changes: 14 additions & 0 deletions apps/avifgainmaputil/avifgainmaputil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ int main(int argc, char** argv) {
return 1;
}

// -Wunsafe-buffer-usage doesn't know the raw pointer argv is associated with
// the bound argc, so it cannot prove these accesses safe. They are bounded
// by the argc checks and by the host's contract with main():
// argv[0..argc-1] are valid.
#ifdef __clang__
#if __has_warning("-Wunsafe-buffer-usage")
#pragma clang unsafe_buffer_usage begin
#endif
#endif
const std::string command_name(argv[1]);
if (command_name == "help") {
if (argc >= 3) {
Expand Down Expand Up @@ -129,6 +138,11 @@ int main(int argc, char** argv) {
}
}
}
#ifdef __clang__
#if __has_warning("-Wunsafe-buffer-usage")
#pragma clang unsafe_buffer_usage end
#endif
#endif

std::cerr << "Unknown command " << command_name << "\n";
avif::PrintUsage(commands);
Expand Down
30 changes: 30 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,36 @@ if(AVIF_GTEST)
target_link_libraries(avifincrtest_helpers PRIVATE GTest::GTest avif_enable_warnings)
endif()

# Tests that have been audited for the Safe Buffers Programming Model. Adding
# a new test to this list requires that the file compiles cleanly under
# -Wunsafe-buffer-usage. See avif_enable_safe_buffers_warning() in the root
# CMakeLists.txt.
if(AVIF_GTEST)
avif_enable_safe_buffers_warning(
gtest/avifalphapremtest.cc
gtest/avifbasictest.cc
gtest/avifcicptest.cc
gtest/avifclaptest.cc
gtest/avifcllitest.cc
gtest/avifcodectest.cc
gtest/avifcolrtest.cc
gtest/avifgridapitest.cc
gtest/avifimagetest.cc
gtest/avifopaquetest.cc
gtest/avifpropinternaltest.cc
gtest/avifsampletransformtest.cc
gtest/aviftilingtest.cc
gtest/avifutilstest.cc
gtest/avify4mtest.cc
)
if(AVIF_CODEC_AVM_ENABLED)
avif_enable_safe_buffers_warning(gtest/avifavmtest.cc)
if(AVIF_ENABLE_EXPERIMENTAL_MINI)
avif_enable_safe_buffers_warning(gtest/avifavmminitest.cc)
endif()
endif()
endif()

if(AVIF_GTEST)
add_avif_gtest_with_data(avif16bittest)
add_avif_gtest(avifallocationtest)
Expand Down
Loading