[HarfBuzz] harfbuzz: Branch 'master' - 3 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Fri Oct 9 09:34:19 PDT 2015
src/hb-open-type-private.hh | 28 +++++-
src/hb-ot-layout-gpos-table.hh | 15 +--
src/hb-ot-layout-gsub-table.hh | 13 +-
src/hb-ot-layout-gsubgpos-private.hh | 44 +++-------
src/hb-ot-layout.cc | 8 -
test/shaping/Makefile.am | 1
test/shaping/fonts/sha1sum/1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf |binary
test/shaping/fonts/sha1sum/MANIFEST | 1
test/shaping/tests/MANIFEST | 1
test/shaping/tests/fuzzed.tests | 1
10 files changed, 60 insertions(+), 52 deletions(-)
New commits:
commit 34379b49e6922b86c15ee62f7fe3bf016cdc2514
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Oct 9 12:34:02 2015 -0400
Add test for previous fix
diff --git a/test/shaping/Makefile.am b/test/shaping/Makefile.am
index e34d83b..5694572 100644
--- a/test/shaping/Makefile.am
+++ b/test/shaping/Makefile.am
@@ -46,6 +46,7 @@ TESTS = \
tests/context-matching.tests \
tests/cursive-positioning.tests \
tests/default-ignorables.tests \
+ tests/fuzzed.tests \
tests/hangul-jamo.tests \
tests/indic-joiner-candrabindu.tests \
tests/indic-old-spec.tests \
diff --git a/test/shaping/fonts/sha1sum/1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf b/test/shaping/fonts/sha1sum/1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf
new file mode 100644
index 0000000..c71e85a
Binary files /dev/null and b/test/shaping/fonts/sha1sum/1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf differ
diff --git a/test/shaping/fonts/sha1sum/MANIFEST b/test/shaping/fonts/sha1sum/MANIFEST
index 1de86c8..2bb1883 100644
--- a/test/shaping/fonts/sha1sum/MANIFEST
+++ b/test/shaping/fonts/sha1sum/MANIFEST
@@ -1,5 +1,6 @@
051d92f8bc6ff724511b296c27623f824de256e9.ttf
191826b9643e3f124d865d617ae609db6a2ce203.ttf
+1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf
226bc2deab3846f1a682085f70c67d0421014144.ttf
270b89df543a7e48e206a2d830c0e10e5265c630.ttf
298c9e1d955f10f6f72c6915c3c6ff9bf9695cec.ttf
diff --git a/test/shaping/tests/MANIFEST b/test/shaping/tests/MANIFEST
index b4ee18e..6ae62dc 100644
--- a/test/shaping/tests/MANIFEST
+++ b/test/shaping/tests/MANIFEST
@@ -4,6 +4,7 @@ cluster.tests
context-matching.tests
cursive-positioning.tests
default-ignorables.tests
+fuzzed.tests
hangul-jamo.tests
indic-joiner-candrabindu.tests
indic-old-spec.tests
diff --git a/test/shaping/tests/fuzzed.tests b/test/shaping/tests/fuzzed.tests
new file mode 100644
index 0000000..3110d7d
--- /dev/null
+++ b/test/shaping/tests/fuzzed.tests
@@ -0,0 +1 @@
+fonts/sha1sum/1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf::U+0041:[gid0=0+1000]
commit f396fbb000dc1c8acddbf6a16e193b328c5e551e
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Oct 9 12:25:55 2015 -0400
Fix return value of sanitize when subformat is not readable
This is a fix on top of the previous issue fixed in
c917965b9e6fe2b21ed6c51559673288fa3af4b7.
This was caught by "libFuzzer" testing.
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index e5c4c0d..aeb3302 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -165,6 +165,7 @@ struct hb_dispatch_context_t
typedef Return return_t;
template <typename T, typename F>
inline bool may_dispatch (const T *obj, const F *format) { return true; }
+ static return_t no_dispatch_return_value (void) { return Context::default_return_value (); }
};
@@ -203,6 +204,7 @@ struct hb_sanitize_context_t :
template <typename T>
inline return_t dispatch (const T &obj) { return obj.sanitize (this); }
static return_t default_return_value (void) { return true; }
+ static return_t no_dispatch_return_value (void) { return false; }
bool stop_sublookup_iteration (const return_t r) const { return !r; }
inline void init (hb_blob_t *b)
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 286253d..ca98cb7 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -548,7 +548,7 @@ struct SinglePos
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
case 2: return_trace (c->dispatch (u.format2));
@@ -843,7 +843,7 @@ struct PairPos
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
case 2: return_trace (c->dispatch (u.format2));
@@ -1024,7 +1024,7 @@ struct CursivePos
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
default:return_trace (c->default_return_value ());
@@ -1120,7 +1120,7 @@ struct MarkBasePos
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
default:return_trace (c->default_return_value ());
@@ -1238,7 +1238,7 @@ struct MarkLigPos
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
default:return_trace (c->default_return_value ());
@@ -1353,7 +1353,7 @@ struct MarkMarkPos
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
default:return_trace (c->default_return_value ());
@@ -1404,8 +1404,7 @@ struct PosLookupSubTable
inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
{
TRACE_DISPATCH (this, lookup_type);
- /* The sub_format passed to may_dispatch is unnecessary but harmless. */
- if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_dispatch_return_value ());
switch (lookup_type) {
case Single: return_trace (u.single.dispatch (c));
case Pair: return_trace (u.pair.dispatch (c));
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index c578254..eebc87b 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -225,7 +225,7 @@ struct SingleSubst
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
case 2: return_trace (c->dispatch (u.format2));
@@ -418,7 +418,7 @@ struct MultipleSubst
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
default:return_trace (c->default_return_value ());
@@ -562,7 +562,7 @@ struct AlternateSubst
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
default:return_trace (c->default_return_value ());
@@ -878,7 +878,7 @@ struct LigatureSubst
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
default:return_trace (c->default_return_value ());
@@ -1035,7 +1035,7 @@ struct ReverseChainSingleSubst
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
default:return_trace (c->default_return_value ());
@@ -1074,8 +1074,7 @@ struct SubstLookupSubTable
inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
{
TRACE_DISPATCH (this, lookup_type);
- /* The sub_format passed to may_dispatch is unnecessary but harmless. */
- if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_dispatch_return_value ());
switch (lookup_type) {
case Single: return_trace (u.single.dispatch (c));
case Multiple: return_trace (u.multiple.dispatch (c));
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 65e39a6..2a9f444 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -1505,7 +1505,7 @@ struct Context
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
case 2: return_trace (c->dispatch (u.format2));
@@ -2120,7 +2120,7 @@ struct ChainContext
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1));
case 2: return_trace (c->dispatch (u.format2));
@@ -2156,7 +2156,7 @@ struct ExtensionFormat1
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, format);
- if (unlikely (!c->may_dispatch (this, this))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ());
return_trace (get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()));
}
@@ -2201,7 +2201,7 @@ struct Extension
inline typename context_t::return_t dispatch (context_t *c) const
{
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->default_return_value ());
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (u.format1.dispatch (c));
default:return_trace (c->default_return_value ());
commit 77a1a2bc18e7b04d4e352a8777ccce345b2f8659
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Oct 9 12:20:58 2015 -0400
Add hb_dispatch_context_t
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 79e70b8..e5c4c0d 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -154,6 +154,19 @@ ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type))
#define Null(Type) Null<Type>()
+/*
+ * Dispatch
+ */
+
+template <typename Context, typename Return, unsigned int MaxDebugDepth>
+struct hb_dispatch_context_t
+{
+ static const unsigned int max_debug_depth = MaxDebugDepth;
+ typedef Return return_t;
+ template <typename T, typename F>
+ inline bool may_dispatch (const T *obj, const F *format) { return true; }
+};
+
/*
* Sanitize
@@ -174,11 +187,16 @@ ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type))
#define HB_SANITIZE_MAX_EDITS 100
#endif
-struct hb_sanitize_context_t
+struct hb_sanitize_context_t :
+ hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
{
+ inline hb_sanitize_context_t (void) :
+ debug_depth (0),
+ start (NULL), end (NULL),
+ writable (false), edit_count (0),
+ blob (NULL) {}
+
inline const char *get_name (void) { return "SANITIZE"; }
- static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE;
- typedef bool return_t;
template <typename T, typename F>
inline bool may_dispatch (const T *obj, const F *format)
{ return format->sanitize (this); }
@@ -295,7 +313,7 @@ template <typename Type>
struct Sanitizer
{
static hb_blob_t *sanitize (hb_blob_t *blob) {
- hb_sanitize_context_t c[1] = {{0, NULL, NULL, false, 0, NULL}};
+ hb_sanitize_context_t c[1];
bool sane;
/* TODO is_sane() stuff */
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 6cf1ffc..65e39a6 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -46,14 +46,11 @@ namespace OT {
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
"");
-struct hb_closure_context_t
+struct hb_closure_context_t :
+ hb_dispatch_context_t<hb_closure_context_t, hb_void_t, HB_DEBUG_CLOSURE>
{
inline const char *get_name (void) { return "CLOSURE"; }
- static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE;
- typedef hb_void_t return_t;
typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
- template <typename T, typename F>
- inline bool may_dispatch (const T *obj, const F *format) { return true; }
template <typename T>
inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; }
static return_t default_return_value (void) { return HB_VOID; }
@@ -98,13 +95,10 @@ struct hb_closure_context_t
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
"%d glyphs", c->len);
-struct hb_would_apply_context_t
+struct hb_would_apply_context_t :
+ hb_dispatch_context_t<hb_would_apply_context_t, bool, HB_DEBUG_WOULD_APPLY>
{
inline const char *get_name (void) { return "WOULD_APPLY"; }
- static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY;
- typedef bool return_t;
- template <typename T, typename F>
- inline bool may_dispatch (const T *obj, const F *format) { return true; }
template <typename T>
inline return_t dispatch (const T &obj) { return obj.would_apply (this); }
static return_t default_return_value (void) { return false; }
@@ -138,14 +132,11 @@ struct hb_would_apply_context_t
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
"");
-struct hb_collect_glyphs_context_t
+struct hb_collect_glyphs_context_t :
+ hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, HB_DEBUG_COLLECT_GLYPHS>
{
inline const char *get_name (void) { return "COLLECT_GLYPHS"; }
- static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS;
- typedef hb_void_t return_t;
typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
- template <typename T, typename F>
- inline bool may_dispatch (const T *obj, const F *format) { return true; }
template <typename T>
inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; }
static return_t default_return_value (void) { return HB_VOID; }
@@ -232,14 +223,14 @@ struct hb_collect_glyphs_context_t
#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
#endif
+/* XXX Can we remove this? */
+
template <typename set_t>
-struct hb_add_coverage_context_t
+struct hb_add_coverage_context_t :
+ hb_dispatch_context_t<hb_add_coverage_context_t<set_t>, const Coverage &, HB_DEBUG_GET_COVERAGE>
{
inline const char *get_name (void) { return "GET_COVERAGE"; }
- static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE;
typedef const Coverage &return_t;
- template <typename T, typename F>
- inline bool may_dispatch (const T *obj, const F *format) { return true; }
template <typename T>
inline return_t dispatch (const T &obj) { return obj.get_coverage (); }
static return_t default_return_value (void) { return Null(Coverage); }
@@ -269,7 +260,8 @@ struct hb_add_coverage_context_t
"idx %d gid %u lookup %d", \
c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index);
-struct hb_apply_context_t
+struct hb_apply_context_t :
+ hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY>
{
struct matcher_t
{
@@ -449,11 +441,7 @@ struct hb_apply_context_t
inline const char *get_name (void) { return "APPLY"; }
- static const unsigned int max_debug_depth = HB_DEBUG_APPLY;
- typedef bool return_t;
typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
- template <typename T, typename F>
- inline bool may_dispatch (const T *obj, const F *format) { return true; }
template <typename T>
inline return_t dispatch (const T &obj) { return obj.apply (this); }
static return_t default_return_value (void) { return false; }
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 1a6fb15..275a960 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -28,6 +28,7 @@
* Google Author(s): Behdad Esfahbod
*/
+#include "hb-open-type-private.hh"
#include "hb-ot-layout-private.hh"
#include "hb-ot-layout-gdef-table.hh"
@@ -925,13 +926,10 @@ apply_backward (OT::hb_apply_context_t *c,
return ret;
}
-struct hb_apply_forward_context_t
+struct hb_apply_forward_context_t :
+ OT::hb_dispatch_context_t<hb_apply_forward_context_t, bool, HB_DEBUG_APPLY>
{
inline const char *get_name (void) { return "APPLY_FWD"; }
- static const unsigned int max_debug_depth = HB_DEBUG_APPLY;
- typedef bool return_t;
- template <typename T, typename F>
- inline bool may_dispatch (const T *obj, const F *format) { return true; }
template <typename T>
inline return_t dispatch (const T &obj) { return apply_forward (c, obj, accel); }
static return_t default_return_value (void) { return false; }
More information about the HarfBuzz
mailing list