Merge PR #16 (reject composite glyphs w/o bbox), slightly modified to match recent code updates (mostly just adding branch predictions)
This commit is contained in:
+23
-37
@@ -271,39 +271,6 @@ void ComputeBbox(unsigned int n_points, const Point* points, uint8_t* dst) {
|
|||||||
offset = Store16(dst, offset, y_max);
|
offset = Store16(dst, offset, y_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process entire bbox stream. This is done as a separate pass to allow for
|
|
||||||
// composite bbox computations (an optional more aggressive transform).
|
|
||||||
bool ProcessBboxStream(Buffer* bbox_stream, unsigned int n_glyphs,
|
|
||||||
const std::vector<uint32_t>& loca_values, uint8_t* glyf_buf,
|
|
||||||
size_t glyf_buf_length) {
|
|
||||||
const uint8_t* buf = bbox_stream->buffer();
|
|
||||||
if (PREDICT_FALSE(n_glyphs >= 65536 || loca_values.size() != n_glyphs + 1)) {
|
|
||||||
return FONT_COMPRESSION_FAILURE();
|
|
||||||
}
|
|
||||||
// Safe because n_glyphs is bounded
|
|
||||||
unsigned int bitmap_length = ((n_glyphs + 31) >> 5) << 2;
|
|
||||||
if (PREDICT_FALSE(!bbox_stream->Skip(bitmap_length))) {
|
|
||||||
return FONT_COMPRESSION_FAILURE();
|
|
||||||
}
|
|
||||||
for (unsigned int i = 0; i < n_glyphs; ++i) {
|
|
||||||
if (buf[i >> 3] & (0x80 >> (i & 7))) {
|
|
||||||
uint32_t loca_offset = loca_values[i];
|
|
||||||
if (PREDICT_FALSE(
|
|
||||||
loca_values[i + 1] - loca_offset < kEndPtsOfContoursOffset)) {
|
|
||||||
return FONT_COMPRESSION_FAILURE();
|
|
||||||
}
|
|
||||||
if (PREDICT_FALSE(glyf_buf_length < 2 + 10 ||
|
|
||||||
loca_offset > glyf_buf_length - 2 - 10)) {
|
|
||||||
return FONT_COMPRESSION_FAILURE();
|
|
||||||
}
|
|
||||||
if (PREDICT_FALSE(!bbox_stream->Read(glyf_buf + loca_offset + 2, 8))) {
|
|
||||||
return FONT_COMPRESSION_FAILURE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ProcessComposite(Buffer* composite_stream, uint8_t* dst,
|
bool ProcessComposite(Buffer* composite_stream, uint8_t* dst,
|
||||||
size_t dst_size, size_t* glyph_size, bool* have_instructions) {
|
size_t dst_size, size_t* glyph_size, bool* have_instructions) {
|
||||||
size_t start_offset = composite_stream->offset();
|
size_t start_offset = composite_stream->offset();
|
||||||
@@ -416,9 +383,19 @@ bool ReconstructGlyf(const uint8_t* data, size_t data_size,
|
|||||||
std::unique_ptr<Point[]> points;
|
std::unique_ptr<Point[]> points;
|
||||||
size_t points_size = 0;
|
size_t points_size = 0;
|
||||||
uint32_t loca_offset = 0;
|
uint32_t loca_offset = 0;
|
||||||
|
const uint8_t* bbox_bitmap = bbox_stream.buffer();
|
||||||
|
// Safe because num_glyphs is bounded
|
||||||
|
unsigned int bitmap_length = ((num_glyphs + 31) >> 5) << 2;
|
||||||
|
if (!bbox_stream.Skip(bitmap_length)) {
|
||||||
|
return FONT_COMPRESSION_FAILURE();
|
||||||
|
}
|
||||||
for (unsigned int i = 0; i < num_glyphs; ++i) {
|
for (unsigned int i = 0; i < num_glyphs; ++i) {
|
||||||
size_t glyph_size = 0;
|
size_t glyph_size = 0;
|
||||||
uint16_t n_contours = 0;
|
uint16_t n_contours = 0;
|
||||||
|
bool have_bbox = false;
|
||||||
|
if (bbox_bitmap[i >> 3] & (0x80 >> (i & 7))) {
|
||||||
|
have_bbox = true;
|
||||||
|
}
|
||||||
if (PREDICT_FALSE(!n_contour_stream.ReadU16(&n_contours))) {
|
if (PREDICT_FALSE(!n_contour_stream.ReadU16(&n_contours))) {
|
||||||
return FONT_COMPRESSION_FAILURE();
|
return FONT_COMPRESSION_FAILURE();
|
||||||
}
|
}
|
||||||
@@ -428,10 +405,17 @@ bool ReconstructGlyf(const uint8_t* data, size_t data_size,
|
|||||||
// composite glyph
|
// composite glyph
|
||||||
bool have_instructions = false;
|
bool have_instructions = false;
|
||||||
unsigned int instruction_size = 0;
|
unsigned int instruction_size = 0;
|
||||||
|
if (PREDICT_FALSE(!have_bbox)) {
|
||||||
|
// composite glyphs must have an explicit bbox
|
||||||
|
return FONT_COMPRESSION_FAILURE();
|
||||||
|
}
|
||||||
if (PREDICT_FALSE(!ProcessComposite(&composite_stream, glyf_dst,
|
if (PREDICT_FALSE(!ProcessComposite(&composite_stream, glyf_dst,
|
||||||
glyf_dst_size, &glyph_size, &have_instructions))) {
|
glyf_dst_size, &glyph_size, &have_instructions))) {
|
||||||
return FONT_COMPRESSION_FAILURE();
|
return FONT_COMPRESSION_FAILURE();
|
||||||
}
|
}
|
||||||
|
if (PREDICT_FALSE(!bbox_stream.Read(glyf_dst + 2, 8))) {
|
||||||
|
return FONT_COMPRESSION_FAILURE();
|
||||||
|
}
|
||||||
if (have_instructions) {
|
if (have_instructions) {
|
||||||
if (PREDICT_FALSE(!Read255UShort(&glyph_stream, &instruction_size))) {
|
if (PREDICT_FALSE(!Read255UShort(&glyph_stream, &instruction_size))) {
|
||||||
return FONT_COMPRESSION_FAILURE();
|
return FONT_COMPRESSION_FAILURE();
|
||||||
@@ -486,7 +470,13 @@ bool ReconstructGlyf(const uint8_t* data, size_t data_size,
|
|||||||
return FONT_COMPRESSION_FAILURE();
|
return FONT_COMPRESSION_FAILURE();
|
||||||
}
|
}
|
||||||
Store16(glyf_dst, 0, n_contours);
|
Store16(glyf_dst, 0, n_contours);
|
||||||
|
if (have_bbox) {
|
||||||
|
if (PREDICT_FALSE(!bbox_stream.Read(glyf_dst + 2, 8))) {
|
||||||
|
return FONT_COMPRESSION_FAILURE();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
ComputeBbox(total_n_points, points.get(), glyf_dst);
|
ComputeBbox(total_n_points, points.get(), glyf_dst);
|
||||||
|
}
|
||||||
size_t offset = kEndPtsOfContoursOffset;
|
size_t offset = kEndPtsOfContoursOffset;
|
||||||
int end_point = -1;
|
int end_point = -1;
|
||||||
for (unsigned int contour_ix = 0; contour_ix < n_contours; ++contour_ix) {
|
for (unsigned int contour_ix = 0; contour_ix < n_contours; ++contour_ix) {
|
||||||
@@ -536,10 +526,6 @@ bool ReconstructGlyf(const uint8_t* data, size_t data_size,
|
|||||||
loca_offset += glyph_size;
|
loca_offset += glyph_size;
|
||||||
}
|
}
|
||||||
loca_values[num_glyphs] = loca_offset;
|
loca_values[num_glyphs] = loca_offset;
|
||||||
if (PREDICT_FALSE(!ProcessBboxStream(&bbox_stream, num_glyphs, loca_values,
|
|
||||||
dst, dst_size))) {
|
|
||||||
return FONT_COMPRESSION_FAILURE();
|
|
||||||
}
|
|
||||||
return StoreLoca(loca_values, index_format, loca_buf, loca_size);
|
return StoreLoca(loca_values, index_format, loca_buf, loca_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user