From 993cf229e63616d2e3f74685185e57521fef3336 Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Sat, 4 Feb 2017 16:31:46 +1100 Subject: [PATCH] font/sfnt: fix proprietary fonts and cmap format 12. Two recent commits ("proprietary fonts" and "cmap format 12") each passed all of its own tests, but the combination wasn't tested until both were submitted. Change-Id: Ic4c2ae8deb1e4623ca5543672dc46d55bfce91a4 Reviewed-on: https://go-review.googlesource.com/36372 Reviewed-by: David Crawshaw --- font/sfnt/cmap.go | 6 +++--- font/sfnt/sfnt.go | 13 +++++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/font/sfnt/cmap.go b/font/sfnt/cmap.go index 3adda03..9db98a8 100644 --- a/font/sfnt/cmap.go +++ b/font/sfnt/cmap.go @@ -206,13 +206,13 @@ func (f *Font) makeCachedGlyphIndexFormat12(buf []byte, offset, _ uint32) ([]byt if err != nil { return nil, err } - offset += headerSize - length := u32(buf[4:]) - numGroups := u32(buf[12:]) if f.cmap.length < offset || length > f.cmap.length-offset { return nil, errInvalidCmapTable } + offset += headerSize + + numGroups := u32(buf[12:]) if numGroups > maxCmapSegments { return nil, errUnsupportedNumberOfCmapSegments } diff --git a/font/sfnt/sfnt.go b/font/sfnt/sfnt.go index 8757d7a..61281e7 100644 --- a/font/sfnt/sfnt.go +++ b/font/sfnt/sfnt.go @@ -30,8 +30,17 @@ import ( const ( // This value is arbitrary, but defends against parsing malicious font // files causing excessive memory allocations. For reference, Adobe's - // SourceHanSansSC-Regular.otf has 65535 glyphs and 1581 cmap segments. - maxCmapSegments = 4096 + // SourceHanSansSC-Regular.otf has 65535 glyphs and: + // - its format-4 cmap table has 1581 segments. + // - its format-12 cmap table has 16498 segments. + // + // TODO: eliminate this constraint? If the cmap table is very large, load + // some or all of it lazily (at the time Font.GlyphIndex is called) instead + // of all of it eagerly (at the time Font.initialize is called), while + // keeping an upper bound on the memory used? This will make the code in + // cmap.go more complicated, considering that all of the Font methods are + // safe to call concurrently, as long as each call has a different *Buffer. + maxCmapSegments = 20000 maxGlyphDataLength = 64 * 1024 maxHintBits = 256