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
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ include(CMakePackageConfigHelpers)

# Build options
option(BUILD_SHARED_LIBS "Build shared library" OFF)

# Optional Clang -fbounds-safety. Default OFF: OGG_*COUNTED_BY* macros in
# ogg_bounds_safety.h are inert and the ABI/build is unchanged. When ON,
# requires a Clang that provides -fbounds-safety / <ptrcheck.h>.
option(OGG_ENABLE_FBOUNDS_SAFETY
"Enable Clang -fbounds-safety annotations (experimental toolchain)" OFF)
if(OGG_ENABLE_FBOUNDS_SAFETY)
add_definitions(-DOGG_SUPPORT_FBOUNDS_SAFETY)
add_compile_options(-fbounds-safety)
endif()
if(APPLE)
option(BUILD_FRAMEWORK "Build Framework bundle for OSX" OFF)
endif()
Expand Down Expand Up @@ -69,6 +79,7 @@ configure_file(include/ogg/config_types.h.in include/ogg/config_types.h @ONLY)
set(OGG_HEADERS
${CMAKE_CURRENT_BINARY_DIR}/include/ogg/config_types.h
include/ogg/ogg.h
include/ogg/ogg_bounds_safety.h
include/ogg/os_types.h
)

Expand Down
2 changes: 1 addition & 1 deletion include/ogg/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

oggincludedir = $(includedir)/ogg

ogginclude_HEADERS = ogg.h os_types.h
ogginclude_HEADERS = ogg.h ogg_bounds_safety.h os_types.h
nodist_ogginclude_HEADERS = config_types.h
8 changes: 7 additions & 1 deletion include/ogg/ogg.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ extern "C" {

#include <stddef.h>
#include <ogg/os_types.h>
#include <ogg/ogg_bounds_safety.h>

typedef struct {
void *iov_base;
Expand Down Expand Up @@ -50,7 +51,12 @@ typedef struct {
Ogg bitstream **********************************************************/

typedef struct {
unsigned char *body_data; /* bytes from packet bodies */
/* body_storage is the capacity companion for body_data.
* Field order is preserved (pointer before size) for public ABI;
* update sites assign capacity before the pointer so counted-by
* invariants hold under optional -fbounds-safety builds.
*/
unsigned char * OGG_COUNTED_BY_OR_NULL(body_storage) body_data; /* bytes from packet bodies */
long body_storage; /* storage elements allocated */
long body_fill; /* elements stored; fill mark */
long body_returned; /* elements of fill returned */
Expand Down
39 changes: 39 additions & 0 deletions include/ogg/ogg_bounds_safety.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* ogg_bounds_safety.h - portability macros for optional -fbounds-safety
*
* Copyright (c) 2026 Jeff Bindel
*
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.
*
* When OGG_SUPPORT_FBOUNDS_SAFETY is defined (typically via
* -DOGG_SUPPORT_FBOUNDS_SAFETY and a Clang toolchain that implements
* -fbounds-safety), these macros expand to Clang bounds annotations.
* Otherwise they expand to nothing so default builds are unchanged.
*
* Pattern matches libwebp / libpng / giflib inert-macro
* -fbounds-safety adoption: annotations are inert unless explicitly enabled.
*/

#ifndef OGG_BOUNDS_SAFETY_H
#define OGG_BOUNDS_SAFETY_H

#ifdef OGG_SUPPORT_FBOUNDS_SAFETY

# include <ptrcheck.h>
/* Non-ABI-breaking counted-by annotations for struct pointer members.
* Prefer OGG_COUNTED_BY_OR_NULL for pointers that may be NULL while the
* companion size field is zero (ogg_stream_state.body_data pattern).
*/
# define OGG_COUNTED_BY(n) __counted_by(n)
# define OGG_COUNTED_BY_OR_NULL(n) __counted_by_or_null(n)

#else /* !OGG_SUPPORT_FBOUNDS_SAFETY */

# define OGG_COUNTED_BY(n)
# define OGG_COUNTED_BY_OR_NULL(n)

#endif /* OGG_SUPPORT_FBOUNDS_SAFETY */

#endif /* OGG_BOUNDS_SAFETY_H */
5 changes: 5 additions & 0 deletions src/framing.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ static void _ogg_crc_init(){
int ogg_stream_init(ogg_stream_state *os,int serialno){
if(os){
memset(os,0,sizeof(*os));
/* counted_by: set capacity before pointer */
os->body_storage=16*1024;
os->lacing_storage=1024;

Expand Down Expand Up @@ -162,6 +163,9 @@ int ogg_stream_check(ogg_stream_state *os){
int ogg_stream_clear(ogg_stream_state *os){
if(os){
if(os->body_data)_ogg_free(os->body_data);
/* counted_by clear order: drop pointer then capacity */
os->body_data=NULL;
os->body_storage=0;
if(os->lacing_vals)_ogg_free(os->lacing_vals);
if(os->granule_vals)_ogg_free(os->granule_vals);

Expand Down Expand Up @@ -196,6 +200,7 @@ static int _os_body_expand(ogg_stream_state *os,long needed){
ogg_stream_clear(os);
return -1;
}
/* counted_by: set capacity before pointer */
os->body_storage=body_storage;
os->body_data=ret;
}
Expand Down