gnu: icecat: Update bundled graphite2 to 1.3.6 [unspecified security fixes].
* gnu/packages/patches/icecat-update-graphite2-pt2.patch: New file. * gnu-system.am (dist_patch_DATA): Add it. * gnu/packages/gnuzilla.scm (icecat)[source]: Add patch.
This commit is contained in:
		
							parent
							
								
									bd009cd95d
								
							
						
					
					
						commit
						b134a80c36
					
				
					 3 changed files with 864 additions and 1 deletions
				
			
		|  | @ -525,6 +525,7 @@ dist_patch_DATA =						\ | ||||||
|   gnu/packages/patches/hydra-disable-darcs-test.patch		\ |   gnu/packages/patches/hydra-disable-darcs-test.patch		\ | ||||||
|   gnu/packages/patches/icecat-avoid-bundled-includes.patch	\ |   gnu/packages/patches/icecat-avoid-bundled-includes.patch	\ | ||||||
|   gnu/packages/patches/icecat-update-graphite2.patch		\ |   gnu/packages/patches/icecat-update-graphite2.patch		\ | ||||||
|  |   gnu/packages/patches/icecat-update-graphite2-pt2.patch	\ | ||||||
|   gnu/packages/patches/icecat-re-enable-DHE-cipher-suites.patch	\ |   gnu/packages/patches/icecat-re-enable-DHE-cipher-suites.patch	\ | ||||||
|   gnu/packages/patches/icu4c-CVE-2014-6585.patch		\ |   gnu/packages/patches/icu4c-CVE-2014-6585.patch		\ | ||||||
|   gnu/packages/patches/icu4c-CVE-2015-1270.patch		\ |   gnu/packages/patches/icu4c-CVE-2015-1270.patch		\ | ||||||
|  |  | ||||||
|  | @ -290,7 +290,8 @@ standards.") | ||||||
|       (patches (map search-patch |       (patches (map search-patch | ||||||
|                     '("icecat-avoid-bundled-includes.patch" |                     '("icecat-avoid-bundled-includes.patch" | ||||||
|                       "icecat-re-enable-DHE-cipher-suites.patch" |                       "icecat-re-enable-DHE-cipher-suites.patch" | ||||||
|                       "icecat-update-graphite2.patch"))) |                       "icecat-update-graphite2.patch" | ||||||
|  |                       "icecat-update-graphite2-pt2.patch"))) | ||||||
|       (modules '((guix build utils))) |       (modules '((guix build utils))) | ||||||
|       (snippet |       (snippet | ||||||
|        '(begin |        '(begin | ||||||
|  |  | ||||||
							
								
								
									
										861
									
								
								gnu/packages/patches/icecat-update-graphite2-pt2.patch
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										861
									
								
								gnu/packages/patches/icecat-update-graphite2-pt2.patch
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,861 @@ | ||||||
|  | Copied from upstream: | ||||||
|  | https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/ec9cff7bb543 | ||||||
|  | 
 | ||||||
|  | # HG changeset patch | ||||||
|  | # User Jonathan Kew <jkew@mozilla.com> | ||||||
|  | # Date 1456760339 0 | ||||||
|  | # Node ID ec9cff7bb5439b2b4c1249ff9376d07a80172c27 | ||||||
|  | # Parent  6f4d5130238790fa5810c76ffeb9eccc65efa8c9 | ||||||
|  | Bug 1248876 - Update graphite2 to upstream release 1.3.6. r=jrmuizel a=sledru | ||||||
|  | 
 | ||||||
|  | diff --git a/gfx/graphite2/README.mozilla b/gfx/graphite2/README.mozilla
 | ||||||
|  | --- a/gfx/graphite2/README.mozilla
 | ||||||
|  | +++ b/gfx/graphite2/README.mozilla
 | ||||||
|  | @@ -1,7 +1,3 @@
 | ||||||
|  | -This directory contains the Graphite2 library release 1.3.5 from
 | ||||||
|  | -https://github.com/silnrsi/graphite/releases/download/1.3.5/graphite2-minimal-1.3.5.tgz
 | ||||||
|  | +This directory contains the Graphite2 library release 1.3.6 from
 | ||||||
|  | +https://github.com/silnrsi/graphite/releases/download/1.3.6/graphite-minimal-1.3.6.tgz
 | ||||||
|  |  See gfx/graphite2/moz-gr-update.sh for update procedure. | ||||||
|  | -
 | ||||||
|  | -Also includes two post-1.3.5 fixes:
 | ||||||
|  | -a8b3ac2aed0eb132cd80efe7de88f8153e73c829
 | ||||||
|  | -e569e28d83491fedb31b9220493f3c07f6ec6d80
 | ||||||
|  | diff --git a/gfx/graphite2/include/graphite2/Font.h b/gfx/graphite2/include/graphite2/Font.h
 | ||||||
|  | --- a/gfx/graphite2/include/graphite2/Font.h
 | ||||||
|  | +++ b/gfx/graphite2/include/graphite2/Font.h
 | ||||||
|  | @@ -25,17 +25,17 @@
 | ||||||
|  |      either version 2 of the License or (at your option) any later version. | ||||||
|  |  */ | ||||||
|  |  #pragma once | ||||||
|  |   | ||||||
|  |  #include "graphite2/Types.h" | ||||||
|  |   | ||||||
|  |  #define GR2_VERSION_MAJOR   1 | ||||||
|  |  #define GR2_VERSION_MINOR   3 | ||||||
|  | -#define GR2_VERSION_BUGFIX  5
 | ||||||
|  | +#define GR2_VERSION_BUGFIX  6
 | ||||||
|  |   | ||||||
|  |  #ifdef __cplusplus | ||||||
|  |  extern "C" | ||||||
|  |  { | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |  typedef struct gr_face          gr_face; | ||||||
|  |  typedef struct gr_font          gr_font; | ||||||
|  | diff --git a/gfx/graphite2/moz-gr-update.sh b/gfx/graphite2/moz-gr-update.sh
 | ||||||
|  | --- a/gfx/graphite2/moz-gr-update.sh
 | ||||||
|  | +++ b/gfx/graphite2/moz-gr-update.sh
 | ||||||
|  | @@ -14,17 +14,17 @@
 | ||||||
|  |  RELEASE=$1 | ||||||
|  |   | ||||||
|  |  if [ "x$RELEASE" == "x" ] | ||||||
|  |  then | ||||||
|  |      echo "Must provide the version number to be used." | ||||||
|  |      exit 1 | ||||||
|  |  fi | ||||||
|  |   | ||||||
|  | -TARBALL="https://github.com/silnrsi/graphite/releases/download/$RELEASE/graphite2-minimal-$RELEASE.tgz"
 | ||||||
|  | +TARBALL="https://github.com/silnrsi/graphite/releases/download/$RELEASE/graphite-minimal-$RELEASE.tgz"
 | ||||||
|  |   | ||||||
|  |  foo=`basename $0` | ||||||
|  |  TMPFILE=`mktemp -t ${foo}` || exit 1 | ||||||
|  |   | ||||||
|  |  curl -L "$TARBALL" -o "$TMPFILE" | ||||||
|  |  tar -x -z -C gfx/graphite2/ --strip-components 1 -f "$TMPFILE" || exit 1 | ||||||
|  |  rm "$TMPFILE" | ||||||
|  |   | ||||||
|  | diff --git a/gfx/graphite2/src/CmapCache.cpp b/gfx/graphite2/src/CmapCache.cpp
 | ||||||
|  | --- a/gfx/graphite2/src/CmapCache.cpp
 | ||||||
|  | +++ b/gfx/graphite2/src/CmapCache.cpp
 | ||||||
|  | @@ -33,43 +33,43 @@ of the License or (at your option) any l
 | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  using namespace graphite2; | ||||||
|  |   | ||||||
|  |  const void * bmp_subtable(const Face::Table & cmap) | ||||||
|  |  { | ||||||
|  |      const void * stbl; | ||||||
|  |      if (!cmap.size()) return 0; | ||||||
|  | -    if (TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 1, cmap.size()), cmap.size())
 | ||||||
|  | -     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 3, cmap.size()), cmap.size())
 | ||||||
|  | -     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 2, cmap.size()), cmap.size())
 | ||||||
|  | -     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 1, cmap.size()), cmap.size())
 | ||||||
|  | -     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 0, cmap.size()), cmap.size()))
 | ||||||
|  | +    if (TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 1, cmap.size()), cmap + cmap.size())
 | ||||||
|  | +     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 3, cmap.size()), cmap + cmap.size())
 | ||||||
|  | +     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 2, cmap.size()), cmap + cmap.size())
 | ||||||
|  | +     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 1, cmap.size()), cmap + cmap.size())
 | ||||||
|  | +     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 0, cmap.size()), cmap + cmap.size()))
 | ||||||
|  |          return stbl; | ||||||
|  |      return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  const void * smp_subtable(const Face::Table & cmap) | ||||||
|  |  { | ||||||
|  |      const void * stbl; | ||||||
|  |      if (!cmap.size()) return 0; | ||||||
|  | -    if (TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 10, cmap.size()), cmap.size())
 | ||||||
|  | -     || TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 4, cmap.size()), cmap.size()))
 | ||||||
|  | +    if (TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 10, cmap.size()), cmap + cmap.size())
 | ||||||
|  | +     || TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 4, cmap.size()), cmap + cmap.size()))
 | ||||||
|  |          return stbl; | ||||||
|  |      return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  template <unsigned int (*NextCodePoint)(const void *, unsigned int, int *), | ||||||
|  |            uint16 (*LookupCodePoint)(const void *, unsigned int, int)> | ||||||
|  |  bool cache_subtable(uint16 * blocks[], const void * cst, const unsigned int limit) | ||||||
|  |  { | ||||||
|  |      int rangeKey = 0; | ||||||
|  |      uint32          codePoint = NextCodePoint(cst, 0, &rangeKey), | ||||||
|  |                      prevCodePoint = 0; | ||||||
|  | -    while (codePoint != limit)
 | ||||||
|  | +    while (codePoint < limit)
 | ||||||
|  |      { | ||||||
|  |          unsigned int block = codePoint >> 8; | ||||||
|  |          if (!blocks[block]) | ||||||
|  |          { | ||||||
|  |              blocks[block] = grzeroalloc<uint16>(0x100); | ||||||
|  |              if (!blocks[block]) | ||||||
|  |                  return false; | ||||||
|  |          } | ||||||
|  | diff --git a/gfx/graphite2/src/Code.cpp b/gfx/graphite2/src/Code.cpp
 | ||||||
|  | --- a/gfx/graphite2/src/Code.cpp
 | ||||||
|  | +++ b/gfx/graphite2/src/Code.cpp
 | ||||||
|  | @@ -79,18 +79,19 @@ struct context
 | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  class Machine::Code::decoder | ||||||
|  |  { | ||||||
|  |  public: | ||||||
|  |      struct limits; | ||||||
|  |      struct analysis | ||||||
|  |      { | ||||||
|  | +        static const int NUMCONTEXTS = 256;
 | ||||||
|  |          uint8     slotref; | ||||||
|  | -        context   contexts[256];
 | ||||||
|  | +        context   contexts[NUMCONTEXTS];
 | ||||||
|  |          byte      max_ref; | ||||||
|  |           | ||||||
|  |          analysis() : slotref(0), max_ref(0) {}; | ||||||
|  |          void set_ref(int index, bool incinsert=false) throw(); | ||||||
|  |          void set_noref(int index) throw(); | ||||||
|  |          void set_changed(int index) throw(); | ||||||
|  |   | ||||||
|  |      }; | ||||||
|  | @@ -363,29 +364,33 @@ opcode Machine::Code::decoder::fetch_opc
 | ||||||
|  |              break; | ||||||
|  |          case ATTR_SET : | ||||||
|  |          case ATTR_ADD : | ||||||
|  |          case ATTR_SUB : | ||||||
|  |          case ATTR_SET_SLOT : | ||||||
|  |              if (--_stack_depth < 0) | ||||||
|  |                  failure(underfull_stack); | ||||||
|  |              valid_upto(gr_slatMax, bc[0]); | ||||||
|  | +            if (attrCode(bc[0]) == gr_slatUserDefn)     // use IATTR for user attributes
 | ||||||
|  | +                failure(out_of_range_data);
 | ||||||
|  |              test_context(); | ||||||
|  |              break; | ||||||
|  |          case IATTR_SET_SLOT : | ||||||
|  |              if (--_stack_depth < 0) | ||||||
|  |                  failure(underfull_stack); | ||||||
|  |              if (valid_upto(gr_slatMax, bc[0])) | ||||||
|  |                  valid_upto(_max.attrid[bc[0]], bc[1]); | ||||||
|  |              test_context(); | ||||||
|  |              break; | ||||||
|  |          case PUSH_SLOT_ATTR : | ||||||
|  |              ++_stack_depth; | ||||||
|  |              valid_upto(gr_slatMax, bc[0]); | ||||||
|  |              valid_upto(_rule_length, _pre_context + int8(bc[1])); | ||||||
|  | +            if (attrCode(bc[0]) == gr_slatUserDefn)     // use IATTR for user attributes
 | ||||||
|  | +                failure(out_of_range_data);
 | ||||||
|  |              break; | ||||||
|  |          case PUSH_GLYPH_ATTR_OBS : | ||||||
|  |              ++_stack_depth; | ||||||
|  |              valid_upto(_max.glyf_attrs, bc[0]); | ||||||
|  |              valid_upto(_rule_length, _pre_context + int8(bc[1])); | ||||||
|  |              break; | ||||||
|  |          case PUSH_GLYPH_METRIC : | ||||||
|  |              ++_stack_depth; | ||||||
|  | @@ -656,24 +661,24 @@ bool Machine::Code::decoder::validate_op
 | ||||||
|  |          return false; | ||||||
|  |      } | ||||||
|  |      return true; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  bool Machine::Code::decoder::valid_upto(const uint16 limit, const uint16 x) const throw() | ||||||
|  |  { | ||||||
|  | -    const bool t = x < limit;
 | ||||||
|  | +    const bool t = (limit != 0) && (x < limit);
 | ||||||
|  |      if (!t) failure(out_of_range_data); | ||||||
|  |      return t; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  bool Machine::Code::decoder::test_context() const throw() | ||||||
|  |  { | ||||||
|  | -    if (_pre_context >= _rule_length)
 | ||||||
|  | +    if (_pre_context >= _rule_length || _analysis.slotref >= analysis::NUMCONTEXTS - 1)
 | ||||||
|  |      { | ||||||
|  |          failure(out_of_range_data); | ||||||
|  |          return false; | ||||||
|  |      } | ||||||
|  |      return true; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  inline  | ||||||
|  | @@ -681,34 +686,34 @@ void Machine::Code::failure(const status
 | ||||||
|  |      release_buffers(); | ||||||
|  |      _status = s; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  inline | ||||||
|  |  void Machine::Code::decoder::analysis::set_ref(int index, bool incinsert) throw() { | ||||||
|  |      if (incinsert && contexts[slotref].flags.inserted) --index; | ||||||
|  | -    if (index + slotref < 0) return;
 | ||||||
|  | +    if (index + slotref < 0 || index + slotref >= NUMCONTEXTS) return;
 | ||||||
|  |      contexts[index + slotref].flags.referenced = true; | ||||||
|  |      if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  inline | ||||||
|  |  void Machine::Code::decoder::analysis::set_noref(int index) throw() { | ||||||
|  |      if (contexts[slotref].flags.inserted) --index; | ||||||
|  | -    if (index + slotref < 0) return;
 | ||||||
|  | +    if (index + slotref < 0 || index + slotref >= NUMCONTEXTS) return;
 | ||||||
|  |      if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  inline | ||||||
|  |  void Machine::Code::decoder::analysis::set_changed(int index) throw() { | ||||||
|  |      if (contexts[slotref].flags.inserted) --index; | ||||||
|  | -    if (index + slotref < 0) return;
 | ||||||
|  | +    if (index + slotref < 0 || index + slotref >= NUMCONTEXTS) return;
 | ||||||
|  |      contexts[index + slotref].flags.changed = true; | ||||||
|  |      if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  void Machine::Code::release_buffers() throw() | ||||||
|  |  { | ||||||
|  |      if (_own) | ||||||
|  | diff --git a/gfx/graphite2/src/GlyphCache.cpp b/gfx/graphite2/src/GlyphCache.cpp
 | ||||||
|  | --- a/gfx/graphite2/src/GlyphCache.cpp
 | ||||||
|  | +++ b/gfx/graphite2/src/GlyphCache.cpp
 | ||||||
|  | @@ -260,17 +260,17 @@ GlyphCache::Loader::Loader(const Face & 
 | ||||||
|  |          _head = Face::Table(); | ||||||
|  |          return; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      if (!dumb_font) | ||||||
|  |      { | ||||||
|  |          if ((m_pGlat = Face::Table(face, Tag::Glat, 0x00030000)) == NULL | ||||||
|  |              || (m_pGloc = Face::Table(face, Tag::Gloc)) == NULL | ||||||
|  | -            || m_pGloc.size() < 6)
 | ||||||
|  | +            || m_pGloc.size() < 8)
 | ||||||
|  |          { | ||||||
|  |              _head = Face::Table(); | ||||||
|  |              return; | ||||||
|  |          } | ||||||
|  |          const byte    * p = m_pGloc; | ||||||
|  |          int       version = be::read<uint32>(p); | ||||||
|  |          const uint16    flags = be::read<uint16>(p); | ||||||
|  |          _num_attrs = be::read<uint16>(p); | ||||||
|  | diff --git a/gfx/graphite2/src/Pass.cpp b/gfx/graphite2/src/Pass.cpp
 | ||||||
|  | --- a/gfx/graphite2/src/Pass.cpp
 | ||||||
|  | +++ b/gfx/graphite2/src/Pass.cpp
 | ||||||
|  | @@ -233,17 +233,17 @@ bool Pass::readRules(const byte * rule_m
 | ||||||
|  |      m_codes = new Code [m_numRules*2]; | ||||||
|  |      const size_t prog_pool_sz = vm::Machine::Code::estimateCodeDataOut(ac_end - ac_data + rc_end - rc_data); | ||||||
|  |      m_progs = gralloc<byte>(prog_pool_sz); | ||||||
|  |      byte * prog_pool_free = m_progs, | ||||||
|  |           * prog_pool_end  = m_progs + prog_pool_sz; | ||||||
|  |      if (e.test(!(m_rules && m_codes && m_progs), E_OUTOFMEM)) return face.error(e); | ||||||
|  |   | ||||||
|  |      Rule * r = m_rules + m_numRules - 1; | ||||||
|  | -    for (size_t n = m_numRules; n; --n, --r, ac_end = ac_begin, rc_end = rc_begin)
 | ||||||
|  | +    for (size_t n = m_numRules; r >= m_rules; --n, --r, ac_end = ac_begin, rc_end = rc_begin)
 | ||||||
|  |      { | ||||||
|  |          face.error_context((face.error_context() & 0xFFFF00) + EC_ARULE + ((n - 1) << 24)); | ||||||
|  |          r->preContext = *--precontext; | ||||||
|  |          r->sort       = be::peek<uint16>(--sort_key); | ||||||
|  |  #ifndef NDEBUG | ||||||
|  |          r->rule_idx   = n - 1; | ||||||
|  |  #endif | ||||||
|  |          if (r->sort > 63 || r->preContext >= r->sort || r->preContext > m_maxPreCtxt || r->preContext < m_minPreCtxt) | ||||||
|  | @@ -405,16 +405,17 @@ bool Pass::runGraphite(vm::Machine & m, 
 | ||||||
|  |          json::closer rules_array_closer(fsm.dbgout); | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |          m.slotMap().highwater(currHigh); | ||||||
|  |          int lc = m_iMaxLoop; | ||||||
|  |          do | ||||||
|  |          { | ||||||
|  |              findNDoRule(s, m, fsm); | ||||||
|  | +            if (m.status() != Machine::finished) return false;
 | ||||||
|  |              if (s && (s == m.slotMap().highwater() || m.slotMap().highpassed() || --lc == 0)) { | ||||||
|  |                  if (!lc) | ||||||
|  |                      s = m.slotMap().highwater(); | ||||||
|  |                  lc = m_iMaxLoop; | ||||||
|  |                  if (s) | ||||||
|  |                      m.slotMap().highwater(s->next()); | ||||||
|  |              } | ||||||
|  |          } while (s); | ||||||
|  | @@ -495,17 +496,22 @@ void Pass::findNDoRule(Slot * & slot, Ma
 | ||||||
|  |  { | ||||||
|  |      assert(slot); | ||||||
|  |   | ||||||
|  |      if (runFSM(fsm, slot)) | ||||||
|  |      { | ||||||
|  |          // Search for the first rule which passes the constraint | ||||||
|  |          const RuleEntry *        r = fsm.rules.begin(), | ||||||
|  |                          * const re = fsm.rules.end(); | ||||||
|  | -        while (r != re && !testConstraint(*r->rule, m)) ++r;
 | ||||||
|  | +        while (r != re && !testConstraint(*r->rule, m))
 | ||||||
|  | +        {
 | ||||||
|  | +            ++r;
 | ||||||
|  | +            if (m.status() != Machine::finished)
 | ||||||
|  | +                return;
 | ||||||
|  | +        }
 | ||||||
|  |   | ||||||
|  |  #if !defined GRAPHITE2_NTRACING | ||||||
|  |          if (fsm.dbgout) | ||||||
|  |          { | ||||||
|  |              if (fsm.rules.size() != 0) | ||||||
|  |              { | ||||||
|  |                  *fsm.dbgout << json::item << json::object; | ||||||
|  |                  dumpRuleEventConsidered(fsm, *r); | ||||||
|  | @@ -530,16 +536,17 @@ void Pass::findNDoRule(Slot * & slot, Ma
 | ||||||
|  |              } | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |  #endif | ||||||
|  |          { | ||||||
|  |              if (r != re) | ||||||
|  |              { | ||||||
|  |                  const int adv = doAction(r->rule->action, slot, m); | ||||||
|  | +                if (m.status() != Machine::finished) return;
 | ||||||
|  |                  if (r->rule->action->deletes()) fsm.slots.collectGarbage(slot); | ||||||
|  |                  adjustSlot(adv, slot, fsm.slots); | ||||||
|  |                  return; | ||||||
|  |              } | ||||||
|  |          } | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      slot = slot->next(); | ||||||
|  | diff --git a/gfx/graphite2/src/Segment.cpp b/gfx/graphite2/src/Segment.cpp
 | ||||||
|  | --- a/gfx/graphite2/src/Segment.cpp
 | ||||||
|  | +++ b/gfx/graphite2/src/Segment.cpp
 | ||||||
|  | @@ -205,18 +205,23 @@ Slot *Segment::newSlot()
 | ||||||
|  |  void Segment::freeSlot(Slot *aSlot) | ||||||
|  |  { | ||||||
|  |      if (m_last == aSlot) m_last = aSlot->prev(); | ||||||
|  |      if (m_first == aSlot) m_first = aSlot->next(); | ||||||
|  |      if (aSlot->attachedTo()) | ||||||
|  |          aSlot->attachedTo()->removeChild(aSlot); | ||||||
|  |      while (aSlot->firstChild()) | ||||||
|  |      { | ||||||
|  | -        aSlot->firstChild()->attachTo(NULL);
 | ||||||
|  | -        aSlot->removeChild(aSlot->firstChild());
 | ||||||
|  | +        if (aSlot->firstChild()->attachedTo() == aSlot)
 | ||||||
|  | +        {
 | ||||||
|  | +            aSlot->firstChild()->attachTo(NULL);
 | ||||||
|  | +            aSlot->removeChild(aSlot->firstChild());
 | ||||||
|  | +        }
 | ||||||
|  | +        else
 | ||||||
|  | +            aSlot->firstChild(NULL);
 | ||||||
|  |      } | ||||||
|  |      // reset the slot incase it is reused | ||||||
|  |      ::new (aSlot) Slot(aSlot->userAttrs()); | ||||||
|  |      memset(aSlot->userAttrs(), 0, m_silf->numUser() * sizeof(int16)); | ||||||
|  |      // Update generation counter for debug | ||||||
|  |  #if !defined GRAPHITE2_NTRACING | ||||||
|  |      if (m_face->logger()) | ||||||
|  |          ++aSlot->userAttrs()[m_silf->numUser()]; | ||||||
|  | diff --git a/gfx/graphite2/src/Slot.cpp b/gfx/graphite2/src/Slot.cpp
 | ||||||
|  | --- a/gfx/graphite2/src/Slot.cpp
 | ||||||
|  | +++ b/gfx/graphite2/src/Slot.cpp
 | ||||||
|  | @@ -192,16 +192,18 @@ int32 Slot::clusterMetric(const Segment 
 | ||||||
|  |  #define SLOTGETCOLATTR(x) { SlotCollision *c = seg->collisionInfo(this); return c ? int(c-> x) : 0; } | ||||||
|  |   | ||||||
|  |  int Slot::getAttr(const Segment *seg, attrCode ind, uint8 subindex) const | ||||||
|  |  { | ||||||
|  |      if (ind == gr_slatUserDefnV1) | ||||||
|  |      { | ||||||
|  |          ind = gr_slatUserDefn; | ||||||
|  |          subindex = 0; | ||||||
|  | +        if (seg->numAttrs() == 0)
 | ||||||
|  | +            return 0;
 | ||||||
|  |      } | ||||||
|  |      else if (ind >= gr_slatJStretch && ind < gr_slatJStretch + 20 && ind != gr_slatJWidth) | ||||||
|  |      { | ||||||
|  |          int indx = ind - gr_slatJStretch; | ||||||
|  |          return getJustify(seg, indx / 5, indx % 5); | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      switch (ind) | ||||||
|  | @@ -269,16 +271,18 @@ int Slot::getAttr(const Segment *seg, at
 | ||||||
|  |          break; } | ||||||
|  |   | ||||||
|  |  void Slot::setAttr(Segment *seg, attrCode ind, uint8 subindex, int16 value, const SlotMap & map) | ||||||
|  |  { | ||||||
|  |      if (ind == gr_slatUserDefnV1) | ||||||
|  |      { | ||||||
|  |          ind = gr_slatUserDefn; | ||||||
|  |          subindex = 0; | ||||||
|  | +        if (seg->numAttrs() == 0)
 | ||||||
|  | +            return;
 | ||||||
|  |      } | ||||||
|  |      else if (ind >= gr_slatJStretch && ind < gr_slatJStretch + 20 && ind != gr_slatJWidth) | ||||||
|  |      { | ||||||
|  |          int indx = ind - gr_slatJStretch; | ||||||
|  |          return setJustify(seg, indx / 5, indx % 5, value); | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      switch (ind) | ||||||
|  | @@ -416,32 +420,32 @@ bool Slot::sibling(Slot *ap)
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  bool Slot::removeChild(Slot *ap) | ||||||
|  |  { | ||||||
|  |      if (this == ap || !m_child) return false; | ||||||
|  |      else if (ap == m_child) | ||||||
|  |      { | ||||||
|  |          Slot *nSibling = m_child->nextSibling(); | ||||||
|  | -        m_child->sibling(NULL);
 | ||||||
|  | +        m_child->removeSibling(nSibling);
 | ||||||
|  |          m_child = nSibling; | ||||||
|  |          return true; | ||||||
|  |      } | ||||||
|  |      else | ||||||
|  |          return m_child->removeSibling(ap); | ||||||
|  |      return true; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  bool Slot::removeSibling(Slot *ap) | ||||||
|  |  { | ||||||
|  |      if (this == ap || !m_sibling) return false; | ||||||
|  |      else if (ap == m_sibling) | ||||||
|  |      { | ||||||
|  |          m_sibling = m_sibling->nextSibling(); | ||||||
|  | -        ap->sibling(NULL);
 | ||||||
|  | +        if (m_sibling) ap->removeSibling(m_sibling);
 | ||||||
|  |          return true; | ||||||
|  |      } | ||||||
|  |      else | ||||||
|  |          return m_sibling->removeSibling(ap); | ||||||
|  |      return true; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph) | ||||||
|  | diff --git a/gfx/graphite2/src/TtfUtil.cpp b/gfx/graphite2/src/TtfUtil.cpp
 | ||||||
|  | --- a/gfx/graphite2/src/TtfUtil.cpp
 | ||||||
|  | +++ b/gfx/graphite2/src/TtfUtil.cpp
 | ||||||
|  | @@ -884,18 +884,19 @@ const void * FindCmapSubtable(const void
 | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /*---------------------------------------------------------------------------------------------- | ||||||
|  |      Check the Microsoft Unicode subtable for expected values | ||||||
|  |  ----------------------------------------------------------------------------------------------*/ | ||||||
|  | -bool CheckCmapSubtable4(const void * pCmapSubtable4, size_t table_len /*, unsigned int maxgid*/)
 | ||||||
|  | +bool CheckCmapSubtable4(const void * pCmapSubtable4, const void * pCmapEnd /*, unsigned int maxgid*/)
 | ||||||
|  |  { | ||||||
|  | +    size_t table_len = (const byte *)pCmapEnd - (const byte *)pCmapSubtable4;
 | ||||||
|  |      if (!pCmapSubtable4) return false; | ||||||
|  |      const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmapSubtable4); | ||||||
|  |      // Bob H say some freeware TT fonts have version 1 (eg, CALIGULA.TTF)  | ||||||
|  |      // so don't check subtable version. 21 Mar 2002 spec changes version to language. | ||||||
|  |      if (be::swap(pTable->format) != 4) return false; | ||||||
|  |      const Sfnt::CmapSubTableFormat4 * pTable4 = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmapSubtable4); | ||||||
|  |      uint16 length = be::swap(pTable4->length); | ||||||
|  |      if (length > table_len) | ||||||
|  | @@ -1044,17 +1045,17 @@ unsigned int CmapSubtable4NextCodepoint(
 | ||||||
|  |              *pRangeKey = nRange - 1; | ||||||
|  |          return 0xFFFF; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      int iRange = (pRangeKey) ? *pRangeKey : 0; | ||||||
|  |      // Just in case we have a bad key: | ||||||
|  |      while (iRange > 0 && be::peek<uint16>(pStartCode + iRange) > nUnicodePrev) | ||||||
|  |          iRange--; | ||||||
|  | -    while (be::peek<uint16>(pTable->end_code + iRange) < nUnicodePrev)
 | ||||||
|  | +    while (iRange < nRange - 1 && be::peek<uint16>(pTable->end_code + iRange) < nUnicodePrev)
 | ||||||
|  |          iRange++; | ||||||
|  |   | ||||||
|  |      // Now iRange is the range containing nUnicodePrev. | ||||||
|  |      unsigned int nStartCode = be::peek<uint16>(pStartCode + iRange); | ||||||
|  |      unsigned int nEndCode = be::peek<uint16>(pTable->end_code + iRange); | ||||||
|  |   | ||||||
|  |      if (nStartCode > nUnicodePrev) | ||||||
|  |          // Oops, nUnicodePrev is not in the cmap! Adjust so we get a reasonable | ||||||
|  | @@ -1069,36 +1070,37 @@ unsigned int CmapSubtable4NextCodepoint(
 | ||||||
|  |          return nUnicodePrev + 1; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      // Otherwise the next codepoint is the first one in the next range. | ||||||
|  |      // There is guaranteed to be a next range because there must be one that | ||||||
|  |      // ends with 0xFFFF. | ||||||
|  |      if (pRangeKey) | ||||||
|  |          *pRangeKey = iRange + 1; | ||||||
|  | -    return be::peek<uint16>(pStartCode + iRange + 1);
 | ||||||
|  | +    return (iRange + 1 >= nRange) ? 0xFFFF : be::peek<uint16>(pStartCode + iRange + 1);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /*---------------------------------------------------------------------------------------------- | ||||||
|  |      Check the Microsoft UCS-4 subtable for expected values. | ||||||
|  |  ----------------------------------------------------------------------------------------------*/ | ||||||
|  | -bool CheckCmapSubtable12(const void *pCmapSubtable12, size_t table_len /*, unsigned int maxgid*/)
 | ||||||
|  | +bool CheckCmapSubtable12(const void *pCmapSubtable12, const void *pCmapEnd /*, unsigned int maxgid*/)
 | ||||||
|  |  { | ||||||
|  | +    size_t table_len = (const byte *)pCmapEnd - (const byte *)pCmapSubtable12;
 | ||||||
|  |      if (!pCmapSubtable12)  return false; | ||||||
|  |      const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmapSubtable12); | ||||||
|  |      if (be::swap(pTable->format) != 12) | ||||||
|  |          return false; | ||||||
|  |      const Sfnt::CmapSubTableFormat12 * pTable12 = reinterpret_cast<const Sfnt::CmapSubTableFormat12 *>(pCmapSubtable12); | ||||||
|  |      uint32 length = be::swap(pTable12->length); | ||||||
|  |      if (length > table_len) | ||||||
|  |          return false; | ||||||
|  |      if (length < sizeof(Sfnt::CmapSubTableFormat12)) | ||||||
|  |          return false; | ||||||
|  |      uint32 num_groups = be::swap(pTable12->num_groups); | ||||||
|  | -    if (length != (sizeof(Sfnt::CmapSubTableFormat12) + (num_groups - 1) * sizeof(uint32) * 3))
 | ||||||
|  | +    if (num_groups > 0x10000000 || length != (sizeof(Sfnt::CmapSubTableFormat12) + (num_groups - 1) * sizeof(uint32) * 3))
 | ||||||
|  |          return false; | ||||||
|  |  #if 0 | ||||||
|  |      for (unsigned int i = 0; i < num_groups; ++i) | ||||||
|  |      { | ||||||
|  |          if (be::swap(pTable12->group[i].end_char_code)  - be::swap(pTable12->group[i].start_char_code) + be::swap(pTable12->group[i].start_glyph_id) > maxgid) | ||||||
|  |              return false; | ||||||
|  |          if (i > 0 && be::swap(pTable12->group[i].start_char_code) <= be::swap(pTable12->group[i-1].end_char_code)) | ||||||
|  |              return false; | ||||||
|  | @@ -1161,17 +1163,17 @@ unsigned int CmapSubtable12NextCodepoint
 | ||||||
|  |              *pRangeKey = nRange; | ||||||
|  |          return 0x10FFFF; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      int iRange = (pRangeKey) ? *pRangeKey : 0; | ||||||
|  |      // Just in case we have a bad key: | ||||||
|  |      while (iRange > 0 && be::swap(pTable->group[iRange].start_char_code) > nUnicodePrev) | ||||||
|  |          iRange--; | ||||||
|  | -    while (be::swap(pTable->group[iRange].end_char_code) < nUnicodePrev)
 | ||||||
|  | +    while (iRange < nRange - 1 && be::swap(pTable->group[iRange].end_char_code) < nUnicodePrev)
 | ||||||
|  |          iRange++; | ||||||
|  |   | ||||||
|  |      // Now iRange is the range containing nUnicodePrev. | ||||||
|  |   | ||||||
|  |      unsigned int nStartCode = be::swap(pTable->group[iRange].start_char_code); | ||||||
|  |      unsigned int nEndCode = be::swap(pTable->group[iRange].end_char_code); | ||||||
|  |   | ||||||
|  |      if (nStartCode > nUnicodePrev) | ||||||
|  | diff --git a/gfx/graphite2/src/call_machine.cpp b/gfx/graphite2/src/call_machine.cpp
 | ||||||
|  | --- a/gfx/graphite2/src/call_machine.cpp
 | ||||||
|  | +++ b/gfx/graphite2/src/call_machine.cpp
 | ||||||
|  | @@ -67,32 +67,34 @@ using namespace vm;
 | ||||||
|  |  struct regbank  { | ||||||
|  |      slotref         is; | ||||||
|  |      slotref *       map; | ||||||
|  |      SlotMap       & smap; | ||||||
|  |      slotref * const map_base; | ||||||
|  |      const instr * & ip; | ||||||
|  |      uint8           direction; | ||||||
|  |      int8            flags; | ||||||
|  | +    Machine::status_t & status;
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  typedef bool        (* ip_t)(registers); | ||||||
|  |   | ||||||
|  |  // Pull in the opcode definitions | ||||||
|  |  // We pull these into a private namespace so these otherwise common names dont | ||||||
|  |  // pollute the toplevel namespace. | ||||||
|  |  namespace { | ||||||
|  |  #define smap    reg.smap | ||||||
|  |  #define seg     smap.segment | ||||||
|  |  #define is      reg.is | ||||||
|  |  #define ip      reg.ip | ||||||
|  |  #define map     reg.map | ||||||
|  |  #define mapb    reg.map_base | ||||||
|  |  #define flags   reg.flags | ||||||
|  |  #define dir     reg.direction | ||||||
|  | +#define status  reg.status
 | ||||||
|  |   | ||||||
|  |  #include "inc/opcodes.h" | ||||||
|  |   | ||||||
|  |  #undef smap | ||||||
|  |  #undef seg | ||||||
|  |  #undef is | ||||||
|  |  #undef ip | ||||||
|  |  #undef map | ||||||
|  | @@ -108,17 +110,17 @@ Machine::stack_t  Machine::run(const ins
 | ||||||
|  |  { | ||||||
|  |      assert(program != 0); | ||||||
|  |   | ||||||
|  |      // Declare virtual machine registers | ||||||
|  |      const instr   * ip = program-1; | ||||||
|  |      const byte    * dp = data; | ||||||
|  |      stack_t       * sp = _stack + Machine::STACK_GUARD, | ||||||
|  |              * const sb = sp; | ||||||
|  | -    regbank         reg = {*map, map, _map, _map.begin()+_map.context(), ip, _map.dir(), 0};
 | ||||||
|  | +    regbank         reg = {*map, map, _map, _map.begin()+_map.context(), ip, _map.dir(), 0, _status};
 | ||||||
|  |   | ||||||
|  |      // Run the program         | ||||||
|  |      while ((reinterpret_cast<ip_t>(*++ip))(dp, sp, sb, reg)) {} | ||||||
|  |      const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0; | ||||||
|  |   | ||||||
|  |      check_final_stack(sp); | ||||||
|  |      map = reg.map; | ||||||
|  |      *map = reg.is; | ||||||
|  | diff --git a/gfx/graphite2/src/direct_machine.cpp b/gfx/graphite2/src/direct_machine.cpp
 | ||||||
|  | --- a/gfx/graphite2/src/direct_machine.cpp
 | ||||||
|  | +++ b/gfx/graphite2/src/direct_machine.cpp
 | ||||||
|  | @@ -57,36 +57,37 @@ using namespace vm;
 | ||||||
|  |  namespace { | ||||||
|  |   | ||||||
|  |  const void * direct_run(const bool          get_table_mode, | ||||||
|  |                          const instr       * program, | ||||||
|  |                          const byte        * data, | ||||||
|  |                          Machine::stack_t  * stack, | ||||||
|  |                          slotref         * & __map, | ||||||
|  |                          uint8                _dir, | ||||||
|  | +                        Machine::status_t & status,
 | ||||||
|  |                          SlotMap           * __smap=0) | ||||||
|  |  { | ||||||
|  |      // We need to define and return to opcode table from within this function  | ||||||
|  |      // other inorder to take the addresses of the instruction bodies. | ||||||
|  |      #include "inc/opcode_table.h" | ||||||
|  |      if (get_table_mode) | ||||||
|  |          return opcode_table; | ||||||
|  |   | ||||||
|  |      // Declare virtual machine registers | ||||||
|  | -    const instr       * ip = program;
 | ||||||
|  | -    const byte        * dp = data;
 | ||||||
|  | -    Machine::stack_t  * sp = stack + Machine::STACK_GUARD,
 | ||||||
|  | -                * const sb = sp;
 | ||||||
|  | -    SlotMap         & smap = *__smap;
 | ||||||
|  | -    Segment          & seg = smap.segment;
 | ||||||
|  | -    slotref             is = *__map,
 | ||||||
|  | -                     * map = __map,
 | ||||||
|  | -              * const mapb = smap.begin()+smap.context();
 | ||||||
|  | -    uint8            dir = _dir;
 | ||||||
|  | -    int8             flags = 0;
 | ||||||
|  | +    const instr           * ip = program;
 | ||||||
|  | +    const byte            * dp = data;
 | ||||||
|  | +    Machine::stack_t      * sp = stack + Machine::STACK_GUARD,
 | ||||||
|  | +                    * const sb = sp;
 | ||||||
|  | +    SlotMap             & smap = *__smap;
 | ||||||
|  | +    Segment              & seg = smap.segment;
 | ||||||
|  | +    slotref                 is = *__map,
 | ||||||
|  | +                         * map = __map,
 | ||||||
|  | +                  * const mapb = smap.begin()+smap.context();
 | ||||||
|  | +    uint8                  dir = _dir;
 | ||||||
|  | +    int8                 flags = 0;
 | ||||||
|  |       | ||||||
|  |      // start the program | ||||||
|  |      goto **ip; | ||||||
|  |   | ||||||
|  |      // Pull in the opcode definitions | ||||||
|  |      #include "inc/opcodes.h" | ||||||
|  |       | ||||||
|  |      end: | ||||||
|  | @@ -95,25 +96,26 @@ const void * direct_run(const bool      
 | ||||||
|  |      return sp; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  const opcode_t * Machine::getOpcodeTable() throw() | ||||||
|  |  { | ||||||
|  |      slotref * dummy; | ||||||
|  | -    return static_cast<const opcode_t *>(direct_run(true, 0, 0, 0, dummy, 0));
 | ||||||
|  | +    Machine::status_t dumstat = Machine::finished;
 | ||||||
|  | +    return static_cast<const opcode_t *>(direct_run(true, 0, 0, 0, dummy, 0, dumstat));
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  Machine::stack_t  Machine::run(const instr   * program, | ||||||
|  |                                 const byte    * data, | ||||||
|  |                                 slotref     * & is) | ||||||
|  |  { | ||||||
|  |      assert(program != 0); | ||||||
|  |       | ||||||
|  |      const stack_t *sp = static_cast<const stack_t *>( | ||||||
|  | -                direct_run(false, program, data, _stack, is, _map.dir(), &_map));
 | ||||||
|  | +                direct_run(false, program, data, _stack, is, _map.dir(), _status, &_map));
 | ||||||
|  |      const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0; | ||||||
|  |      check_final_stack(sp); | ||||||
|  |      return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | diff --git a/gfx/graphite2/src/inc/Code.h b/gfx/graphite2/src/inc/Code.h
 | ||||||
|  | --- a/gfx/graphite2/src/inc/Code.h
 | ||||||
|  | +++ b/gfx/graphite2/src/inc/Code.h
 | ||||||
|  | @@ -109,17 +109,17 @@ public:
 | ||||||
|  |      int32 run(Machine &m, slotref * & map) const; | ||||||
|  |       | ||||||
|  |      CLASS_NEW_DELETE; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  inline | ||||||
|  |  size_t  Machine::Code::estimateCodeDataOut(size_t n_bc) | ||||||
|  |  { | ||||||
|  | -    return n_bc * (sizeof(instr)+sizeof(byte));
 | ||||||
|  | +    return (n_bc + 1) * (sizeof(instr)+sizeof(byte));
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  inline Machine::Code::Code() throw() | ||||||
|  |  : _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0), | ||||||
|  |    _status(loaded), _constraint(false), _modify(false), _delete(false), | ||||||
|  |    _own(false) | ||||||
|  |  { | ||||||
|  | diff --git a/gfx/graphite2/src/inc/Machine.h b/gfx/graphite2/src/inc/Machine.h
 | ||||||
|  | --- a/gfx/graphite2/src/inc/Machine.h
 | ||||||
|  | +++ b/gfx/graphite2/src/inc/Machine.h
 | ||||||
|  | @@ -135,17 +135,18 @@ public:
 | ||||||
|  |   | ||||||
|  |      class Code; | ||||||
|  |   | ||||||
|  |      enum status_t { | ||||||
|  |          finished = 0, | ||||||
|  |          stack_underflow, | ||||||
|  |          stack_not_empty, | ||||||
|  |          stack_overflow, | ||||||
|  | -        slot_offset_out_bounds
 | ||||||
|  | +        slot_offset_out_bounds,
 | ||||||
|  | +        died_early
 | ||||||
|  |      }; | ||||||
|  |   | ||||||
|  |      Machine(SlotMap &) throw(); | ||||||
|  |      static const opcode_t *   getOpcodeTable() throw(); | ||||||
|  |   | ||||||
|  |      CLASS_NEW_DELETE; | ||||||
|  |   | ||||||
|  |      SlotMap   & slotMap() const throw(); | ||||||
|  | diff --git a/gfx/graphite2/src/inc/TtfUtil.h b/gfx/graphite2/src/inc/TtfUtil.h
 | ||||||
|  | --- a/gfx/graphite2/src/inc/TtfUtil.h
 | ||||||
|  | +++ b/gfx/graphite2/src/inc/TtfUtil.h
 | ||||||
|  | @@ -132,21 +132,21 @@ public:
 | ||||||
|  |      int GetLangsForNames(const void * pName, int nPlatformId, int nEncodingId, | ||||||
|  |          int *nameIdList, int cNameIds, short *langIdList); | ||||||
|  |      void SwapWString(void * pWStr, size_t nSize = 0); // throw (std::invalid_argument); | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |      ////////////////////////////////// cmap lookup tools  | ||||||
|  |      const void * FindCmapSubtable(const void * pCmap, int nPlatformId = 3,  | ||||||
|  |          int nEncodingId = 1, size_t length = 0); | ||||||
|  | -    bool CheckCmapSubtable4(const void * pCmap31, size_t table_len /*, unsigned int maxgid*/);
 | ||||||
|  | +    bool CheckCmapSubtable4(const void * pCmap31, const void * pCmapEnd /*, unsigned int maxgid*/);
 | ||||||
|  |      gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId, int rangeKey = 0); | ||||||
|  |      unsigned int CmapSubtable4NextCodepoint(const void *pCmap31, unsigned int nUnicodeId, | ||||||
|  |          int * pRangeKey = 0); | ||||||
|  | -    bool CheckCmapSubtable12(const void *pCmap310, size_t table_len /*, unsigned int maxgid*/);
 | ||||||
|  | +    bool CheckCmapSubtable12(const void *pCmap310, const void * pCmapEnd /*, unsigned int maxgid*/);
 | ||||||
|  |      gid16 CmapSubtable12Lookup(const void * pCmap310, unsigned int uUnicodeId, int rangeKey = 0); | ||||||
|  |      unsigned int CmapSubtable12NextCodepoint(const void *pCmap310, unsigned int nUnicodeId, | ||||||
|  |          int * pRangeKey = 0); | ||||||
|  |   | ||||||
|  |      ///////////////////////////////// horizontal metric data for a glyph | ||||||
|  |      bool HorMetrics(gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize,  | ||||||
|  |          const void * pHhea, int & nLsb, unsigned int & nAdvWid); | ||||||
|  |   | ||||||
|  | diff --git a/gfx/graphite2/src/inc/opcodes.h b/gfx/graphite2/src/inc/opcodes.h
 | ||||||
|  | --- a/gfx/graphite2/src/inc/opcodes.h
 | ||||||
|  | +++ b/gfx/graphite2/src/inc/opcodes.h
 | ||||||
|  | @@ -71,17 +71,17 @@ of the License or (at your option) any l
 | ||||||
|  |  #define use_params(n)       dp += n | ||||||
|  |   | ||||||
|  |  #define declare_params(n)   const byte * param = dp; \ | ||||||
|  |                              use_params(n); | ||||||
|  |   | ||||||
|  |  #define push(n)             { *++sp = n; } | ||||||
|  |  #define pop()               (*sp--) | ||||||
|  |  #define slotat(x)           (map[(x)]) | ||||||
|  | -#define DIE                 { is=seg.last(); EXIT(1); }
 | ||||||
|  | +#define DIE                 { is=seg.last(); status = Machine::died_early; EXIT(1); }
 | ||||||
|  |  #define POSITIONED          1 | ||||||
|  |   | ||||||
|  |  STARTOP(nop) | ||||||
|  |      do {} while (0); | ||||||
|  |  ENDOP | ||||||
|  |   | ||||||
|  |  STARTOP(push_byte) | ||||||
|  |      declare_params(1); | ||||||
|  | @@ -387,30 +387,30 @@ STARTOP(attr_set)
 | ||||||
|  |  ENDOP | ||||||
|  |   | ||||||
|  |  STARTOP(attr_add) | ||||||
|  |      declare_params(1); | ||||||
|  |      const attrCode      slat = attrCode(uint8(*param)); | ||||||
|  |      const          int  val  = int(pop()); | ||||||
|  |      if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0) | ||||||
|  |      { | ||||||
|  | -        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
 | ||||||
|  | +        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
 | ||||||
|  |          flags |= POSITIONED; | ||||||
|  |      } | ||||||
|  |      int res = is->getAttr(&seg, slat, 0); | ||||||
|  |      is->setAttr(&seg, slat, 0, val + res, smap); | ||||||
|  |  ENDOP | ||||||
|  |   | ||||||
|  |  STARTOP(attr_sub) | ||||||
|  |      declare_params(1); | ||||||
|  |      const attrCode      slat = attrCode(uint8(*param)); | ||||||
|  |      const          int  val  = int(pop()); | ||||||
|  |      if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0) | ||||||
|  |      { | ||||||
|  | -        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
 | ||||||
|  | +        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
 | ||||||
|  |          flags |= POSITIONED; | ||||||
|  |      } | ||||||
|  |      int res = is->getAttr(&seg, slat, 0); | ||||||
|  |      is->setAttr(&seg, slat, 0, res - val, smap); | ||||||
|  |  ENDOP | ||||||
|  |   | ||||||
|  |  STARTOP(attr_set_slot) | ||||||
|  |      declare_params(1); | ||||||
|  | @@ -429,17 +429,17 @@ STARTOP(iattr_set_slot)
 | ||||||
|  |  ENDOP | ||||||
|  |   | ||||||
|  |  STARTOP(push_slot_attr) | ||||||
|  |      declare_params(2); | ||||||
|  |      const attrCode      slat     = attrCode(uint8(param[0])); | ||||||
|  |      const int           slot_ref = int8(param[1]); | ||||||
|  |      if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0) | ||||||
|  |      { | ||||||
|  | -        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
 | ||||||
|  | +        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
 | ||||||
|  |          flags |= POSITIONED; | ||||||
|  |      } | ||||||
|  |      slotref slot = slotat(slot_ref); | ||||||
|  |      if (slot) | ||||||
|  |      { | ||||||
|  |          int res = slot->getAttr(&seg, slat, 0); | ||||||
|  |          push(res); | ||||||
|  |      } | ||||||
|  | @@ -505,17 +505,17 @@ ENDOP
 | ||||||
|  |   | ||||||
|  |  STARTOP(push_islot_attr) | ||||||
|  |      declare_params(3); | ||||||
|  |      const attrCode  slat     = attrCode(uint8(param[0])); | ||||||
|  |      const int           slot_ref = int8(param[1]), | ||||||
|  |                          idx      = uint8(param[2]); | ||||||
|  |      if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0) | ||||||
|  |      { | ||||||
|  | -        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
 | ||||||
|  | +        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
 | ||||||
|  |          flags |= POSITIONED; | ||||||
|  |      } | ||||||
|  |      slotref slot = slotat(slot_ref); | ||||||
|  |      if (slot) | ||||||
|  |      { | ||||||
|  |          int res = slot->getAttr(&seg, slat, idx); | ||||||
|  |          push(res); | ||||||
|  |      } | ||||||
|  | 
 | ||||||
		Reference in a new issue