The typed Read methods (ReadU8, ReadU16, ReadU24, ReadU32, ReadTag,
ReadR64) used bounds checks of the form `offset_ + N > length_`. On
32-bit platforms where size_t is 32 bits, if offset_ is close to
SIZE_MAX (e.g. 0xFFFFFFFF), the addition `offset_ + N` wraps around
to a small value, bypassing the bounds check and allowing out-of-bounds
reads from the underlying buffer.
Fix by restructuring the checks to `length_ < N || offset_ > length_ - N`,
which avoids any arithmetic that could overflow. This is consistent with
the existing Read(uint8_t*, size_t) method which already uses the safe
`offset_ > length_ - n_bytes` pattern.
Also add bounds validation to set_offset() (changing return type from
void to bool) to reject offsets beyond the buffer length, and update
the sole caller in font.cc to check the return value. This prevents
TTC font collection offsets from positioning the buffer past its end.
Without the change `woff2` build fails on upcoming `gcc-15` as:
In file included from src/woff2_out.cc:9:
include/woff2/output.h:73:25: error: expected ')' before '*' token
73 | WOFF2MemoryOut(uint8_t* buf, size_t buf_size);
| ~ ^
| )
include/woff2/output.h:79:3: error: 'uint8_t' does not name a type
79 | uint8_t* buf_;
| ^~~~~~~
include/woff2/output.h:16:1: note: 'uint8_t' is defined in header '<cstdint>';
this is probably fixable by adding '#include <cstdint>'
15 | #include <string>
+++ |+#include <cstdint>
16 |
We're experiencing users in Chrome that require larger decode sizes for their woff2 fonts. I suggest to increase this limit. Compare https://crbug.com/40233227
Despite common practice, type-punning integer types out of buffers is
undefined in C and C++. It's both a strict aliasing violation on access,
and if the pointer isn't aligned, an alignment violation on cast. Being
undefined, the compiler is allowed to arbitrarily miscompile the code
when we rely on it.
Instead, the two legal ways to pull a uint32_t out of a buffer are to
either use memcpy, or load byte by byte and use shifts. In both cases,
a good compiler should be smart enough to recognize what we're doing and
generate reasonable code. Since there was already fallback code for the
latter (for a middle-endian architecture?), I went ahead and switched to
that.
This change is needed to fix UBSan violations in Chromium.
overlapSimpleBitmap is a new field in the transformed glyf table (https://www.w3.org/TR/WOFF2/#glyf_table_format). It allows the overlap simple flag set on glyphs in the original font to be saved into the woff2 encoding.
This brings various improvements to the current Makefile and intends to help
people to package WOFF2:
* Build and install static and shared libraries for encoder and decoder
* Install public headers
* Generate and install pc files for PkgConfig
* Build the woff2_* programs
* Build the fuzzer archives
* Specify a release version (0.0.1 is hardcoded for now)
* Build using a Brotli version installed on the system, instead of the git
submodule
* Have some CANONICAL_PREFIXES and NOISY_LOGGING configuration options
This is a first step to make WOFF2 a shared library. Public headers are moved
in their own directory to make the public API clearer. This is similar to
the c/include/brotli/ directory in Brotli. "using" commands are also removed
from the public headers, so that callers won't have unexpected side effect
when including the files.