]> git.pld-linux.org Git - packages/qt4.git/blob - Better-handling-of-invalid-font-tables.patch
- exceptions are used in some parts, rel 44
[packages/qt4.git] / Better-handling-of-invalid-font-tables.patch
1 From 0a2f2382541424726168804be2c90b91381608c6 Mon Sep 17 00:00:00 2001
2 From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
3 Date: Fri, 10 Jul 2015 13:22:32 +0200
4 Subject: [PATCH] Better handling of invalid font tables
5
6 Specifically when reading files with broken cmap tables, we could
7 get some undeterministic results. We handle this more gracefully
8 by verifying that the offsets are sane and bailing out early if not.
9 This replaces the current pattern throughout the font engine for
10 consistency.
11
12 This is a back-port of 4a1e5dbade4bab55f39bd368480dcca9a11e4b38
13 from Qt 5.
14
15 Change-Id: If4172b9ef0808801c8e27ffaad962535afe572ed
16 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
17 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
18 ---
19  src/gui/text/qfontengine.cpp     | 212 +++++++++++++++++++++++++++++----------
20  src/gui/text/qfontengine_mac.mm  |  11 +-
21  src/gui/text/qfontengine_mac_p.h |   1 +
22  src/gui/text/qfontengine_p.h     |   2 +-
23  src/gui/text/qfontengine_qpa.cpp |  12 +--
24  src/gui/text/qfontengine_qpf.cpp |  12 +--
25  src/gui/text/qfontengine_s60.cpp |   9 +-
26  src/gui/text/qfontengine_s60_p.h |   1 +
27  src/gui/text/qfontengine_win.cpp |  22 ++--
28  src/gui/text/qfontengine_win_p.h |   1 +
29  10 files changed, 198 insertions(+), 85 deletions(-)
30
31 diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
32 index 67b8798..3f7d831 100644
33 --- a/src/gui/text/qfontengine.cpp
34 +++ b/src/gui/text/qfontengine.cpp
35 @@ -69,6 +69,16 @@ static inline bool qtransform_equals_no_translate(const QTransform &a, const QTr
36      }
37  }
38  
39 +template<typename T>
40 +static inline bool qSafeFromBigEndian(const uchar *source, const uchar *end, T *output)
41 +{
42 +    if (source + sizeof(T) > end)
43 +        return false;
44 +
45 +    *output = qFromBigEndian<T>(source);
46 +    return true;
47 +}
48 +
49  // Harfbuzz helper functions
50  
51  static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool rightToLeft)
52 @@ -808,26 +818,38 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor)
53          return;
54  
55      const uchar *table = reinterpret_cast<const uchar *>(tab.constData());
56 +    const uchar *end = table + tab.size();
57 +
58 +    quint16 version;
59 +    if (!qSafeFromBigEndian(table, end, &version))
60 +        return;
61  
62 -    unsigned short version = qFromBigEndian<quint16>(table);
63      if (version != 0) {
64  //        qDebug("wrong version");
65         return;
66      }
67  
68 -    unsigned short numTables = qFromBigEndian<quint16>(table + 2);
69 +    quint16 numTables;
70 +    if (!qSafeFromBigEndian(table + 2, end, &numTables))
71 +        return;
72 +
73      {
74          int offset = 4;
75          for(int i = 0; i < numTables; ++i) {
76 -            if (offset + 6 > tab.size()) {
77 -//                qDebug("offset out of bounds");
78 -                goto end;
79 -            }
80              const uchar *header = table + offset;
81  
82 -            ushort version = qFromBigEndian<quint16>(header);
83 -            ushort length = qFromBigEndian<quint16>(header+2);
84 -            ushort coverage = qFromBigEndian<quint16>(header+4);
85 +            quint16 version;
86 +            if (!qSafeFromBigEndian(header, end, &version))
87 +                goto end;
88 +
89 +            quint16 length;
90 +            if (!qSafeFromBigEndian(header + 2, end, &length))
91 +                goto end;
92 +
93 +            quint16 coverage;
94 +            if (!qSafeFromBigEndian(header + 4, end, &coverage))
95 +                goto end;
96 +
97  //            qDebug("subtable: version=%d, coverage=%x",version, coverage);
98              if(version == 0 && coverage == 0x0001) {
99                  if (offset + length > tab.size()) {
100 @@ -836,7 +858,10 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor)
101                  }
102                  const uchar *data = table + offset + 6;
103  
104 -                ushort nPairs = qFromBigEndian<quint16>(data);
105 +                quint16 nPairs;
106 +                if (!qSafeFromBigEndian(data, end, &nPairs))
107 +                    goto end;
108 +
109                  if(nPairs * 6 + 8 > length - 6) {
110  //                    qDebug("corrupt table!");
111                      // corrupt table
112 @@ -846,8 +871,21 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor)
113                  int off = 8;
114                  for(int i = 0; i < nPairs; ++i) {
115                      QFontEngine::KernPair p;
116 -                    p.left_right = (((uint)qFromBigEndian<quint16>(data+off)) << 16) + qFromBigEndian<quint16>(data+off+2);
117 -                    p.adjust = QFixed(((int)(short)qFromBigEndian<quint16>(data+off+4))) / scalingFactor;
118 +
119 +                    quint16 tmp;
120 +                    if (!qSafeFromBigEndian(data + off, end, &tmp))
121 +                        goto end;
122 +
123 +                    p.left_right = uint(tmp) << 16;
124 +                    if (!qSafeFromBigEndian(data + off + 2, end, &tmp))
125 +                        goto end;
126 +
127 +                    p.left_right |= tmp;
128 +
129 +                    if (!qSafeFromBigEndian(data + off + 4, end, &tmp))
130 +                        goto end;
131 +
132 +                    p.adjust = QFixed(int(short(tmp))) / scalingFactor;
133                      kerning_pairs.append(p);
134                      off += 6;
135                  }
136 @@ -872,26 +910,31 @@ int QFontEngine::glyphCount() const
137      QByteArray maxpTable = getSfntTable(MAKE_TAG('m', 'a', 'x', 'p'));
138      if (maxpTable.size() < 6)
139          return 0;
140 -    return qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(maxpTable.constData() + 4));
141 +
142 +    const uchar *source = reinterpret_cast<const uchar *>(maxpTable.constData() + 4);
143 +    const uchar *end = source + maxpTable.size();
144 +
145 +    quint16 count = 0;
146 +    qSafeFromBigEndian(source, end, &count);
147 +    return count;
148  }
149  
150  const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize)
151  {
152      const uchar *header = table;
153 -    if (tableSize < 4)
154 -        return 0;
155 -
156      const uchar *endPtr = table + tableSize;
157  
158      // version check
159 -    if (qFromBigEndian<quint16>(header) != 0)
160 +    quint16 version;
161 +    if (!qSafeFromBigEndian(header, endPtr, &version) || version != 0)
162          return 0;
163  
164 -    unsigned short numTables = qFromBigEndian<quint16>(header + 2);
165 -    const uchar *maps = table + 4;
166 -    if (maps + 8 * numTables > endPtr)
167 +    quint16 numTables;
168 +    if (!qSafeFromBigEndian(header + 2, endPtr, &numTables))
169          return 0;
170  
171 +    const uchar *maps = table + 4;
172 +
173      enum {
174          Invalid,
175          AppleRoman,
176 @@ -906,8 +949,14 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy
177      int tableToUse = -1;
178      int score = Invalid;
179      for (int n = 0; n < numTables; ++n) {
180 -        const quint16 platformId = qFromBigEndian<quint16>(maps + 8 * n);
181 -        const quint16 platformSpecificId = qFromBigEndian<quint16>(maps + 8 * n + 2);
182 +        quint16 platformId;
183 +        if (!qSafeFromBigEndian(maps + 8 * n, endPtr, &platformId))
184 +            return 0;
185 +
186 +        quint16 platformSpecificId;
187 +        if (!qSafeFromBigEndian(maps + 8 * n + 2, endPtr, &platformSpecificId))
188 +            return 0;
189 +
190          switch (platformId) {
191          case 0: // Unicode
192              if (score < Unicode &&
193 @@ -961,20 +1010,30 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy
194  resolveTable:
195      *isSymbolFont = (symbolTable > -1);
196  
197 -    unsigned int unicode_table = qFromBigEndian<quint32>(maps + 8*tableToUse + 4);
198 +    quint32 unicode_table;
199 +    if (!qSafeFromBigEndian(maps + 8 * tableToUse + 4, endPtr, &unicode_table))
200 +        return 0;
201  
202 -    if (!unicode_table || unicode_table + 8 > tableSize)
203 +    if (!unicode_table)
204          return 0;
205  
206      // get the header of the unicode table
207      header = table + unicode_table;
208  
209 -    unsigned short format = qFromBigEndian<quint16>(header);
210 -    unsigned int length;
211 -    if(format < 8)
212 -        length = qFromBigEndian<quint16>(header + 2);
213 -    else
214 -        length = qFromBigEndian<quint32>(header + 4);
215 +    quint16 format;
216 +    if (!qSafeFromBigEndian(header, endPtr, &format))
217 +        return 0;
218 +
219 +    quint32 length;
220 +    if (format < 8) {
221 +        quint16 tmp;
222 +        if (!qSafeFromBigEndian(header + 2, endPtr, &tmp))
223 +            return 0;
224 +        length = tmp;
225 +    } else {
226 +        if (!qSafeFromBigEndian(header + 4, endPtr, &length))
227 +            return 0;
228 +    }
229  
230      if (table + unicode_table + length > endPtr)
231          return 0;
232 @@ -989,7 +1048,7 @@ resolveTable:
233          // Check that none of the latin1 range are in the unicode table
234          bool unicodeTableHasLatin1 = false;
235          for (int uc=0x00; uc<0x100; ++uc) {
236 -            if (getTrueTypeGlyphIndex(selectedTable, uc) != 0) {
237 +            if (getTrueTypeGlyphIndex(selectedTable, length, uc) != 0) {
238                  unicodeTableHasLatin1 = true;
239                  break;
240              }
241 @@ -999,7 +1058,7 @@ resolveTable:
242          bool unicodeTableHasSymbols = false;
243          if (!unicodeTableHasLatin1) {
244              for (int uc=0xf000; uc<0xf100; ++uc) {
245 -                if (getTrueTypeGlyphIndex(selectedTable, uc) != 0) {
246 +                if (getTrueTypeGlyphIndex(selectedTable, length, uc) != 0) {
247                      unicodeTableHasSymbols = true;
248                      break;
249                  }
250 @@ -1017,12 +1076,17 @@ resolveTable:
251      return table + unicode_table;
252  }
253  
254 -quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
255 +quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, int cmapSize, uint unicode)
256  {
257 -    unsigned short format = qFromBigEndian<quint16>(cmap);
258 +    const uchar *end = cmap + cmapSize;
259 +    quint16 format;
260 +    if (!qSafeFromBigEndian(cmap, end, &format))
261 +        return 0;
262 +
263      if (format == 0) {
264 -        if (unicode < 256)
265 -            return (int) *(cmap+6+unicode);
266 +        const uchar *ptr = cmap + 6 + unicode;
267 +        if (unicode < 256 && ptr < end)
268 +            return quint32(*ptr);
269      } else if (format == 4) {
270          /* some fonts come with invalid cmap tables, where the last segment
271             specified end = start = rangeoffset = 0xffff, delta = 0x0001
272 @@ -1031,25 +1095,49 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
273          */
274          if(unicode >= 0xffff)
275              return 0;
276 -        quint16 segCountX2 = qFromBigEndian<quint16>(cmap + 6);
277 +
278 +        quint16 segCountX2;
279 +        if (!qSafeFromBigEndian(cmap + 6, end, &segCountX2))
280 +            return 0;
281 +
282          const unsigned char *ends = cmap + 14;
283 +
284          int i = 0;
285 -        for (; i < segCountX2/2 && qFromBigEndian<quint16>(ends + 2*i) < unicode; i++) {}
286 +        for (; i < segCountX2/2; ++i) {
287 +            quint16 codePoint;
288 +            if (!qSafeFromBigEndian(ends + 2 * i, end, &codePoint))
289 +                return 0;
290 +            if (codePoint >= unicode)
291 +                break;
292 +        }
293  
294          const unsigned char *idx = ends + segCountX2 + 2 + 2*i;
295 -        quint16 startIndex = qFromBigEndian<quint16>(idx);
296  
297 +        quint16 startIndex;
298 +        if (!qSafeFromBigEndian(idx, end, &startIndex))
299 +            return 0;
300          if (startIndex > unicode)
301              return 0;
302  
303          idx += segCountX2;
304 -        qint16 idDelta = (qint16)qFromBigEndian<quint16>(idx);
305 +
306 +        quint16 tmp;
307 +        if (!qSafeFromBigEndian(idx, end, &tmp))
308 +            return 0;
309 +        qint16 idDelta = qint16(tmp);
310 +
311          idx += segCountX2;
312 -        quint16 idRangeoffset_t = (quint16)qFromBigEndian<quint16>(idx);
313 +
314 +        quint16 idRangeoffset_t;
315 +        if (!qSafeFromBigEndian(idx, end, &idRangeoffset_t))
316 +            return 0;
317  
318          quint16 glyphIndex;
319          if (idRangeoffset_t) {
320 -            quint16 id = qFromBigEndian<quint16>(idRangeoffset_t + 2*(unicode - startIndex) + idx);
321 +            quint16 id;
322 +            if (!qSafeFromBigEndian(idRangeoffset_t + 2 * (unicode - startIndex) + idx, end, &id))
323 +                return 0;
324 +
325              if (id)
326                  glyphIndex = (idDelta + id) % 0x10000;
327              else
328 @@ -1059,13 +1147,19 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
329          }
330          return glyphIndex;
331      } else if (format == 6) {
332 -        quint16 tableSize = qFromBigEndian<quint16>(cmap + 2);
333 +        quint16 tableSize;
334 +        if (!qSafeFromBigEndian(cmap + 2, end, &tableSize))
335 +            return 0;
336  
337 -        quint16 firstCode6 = qFromBigEndian<quint16>(cmap + 6);
338 +        quint16 firstCode6;
339 +        if (!qSafeFromBigEndian(cmap + 6, end, &firstCode6))
340 +            return 0;
341          if (unicode < firstCode6)
342              return 0;
343  
344 -        quint16 entryCount6 = qFromBigEndian<quint16>(cmap + 8);
345 +        quint16 entryCount6;
346 +        if (!qSafeFromBigEndian(cmap + 8, end, &entryCount6))
347 +            return 0;
348          if (entryCount6 * 2 + 10 > tableSize)
349              return 0;
350  
351 @@ -1074,9 +1168,14 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
352              return 0;
353  
354          quint16 entryIndex6 = unicode - firstCode6;
355 -        return qFromBigEndian<quint16>(cmap + 10 + (entryIndex6 * 2));
356 +
357 +        quint16 index = 0;
358 +        qSafeFromBigEndian(cmap + 10 + (entryIndex6 * 2), end, &index);
359 +        return index;
360      } else if (format == 12) {
361 -        quint32 nGroups = qFromBigEndian<quint32>(cmap + 12);
362 +        quint32 nGroups;
363 +        if (!qSafeFromBigEndian(cmap + 12, end, &nGroups))
364 +            return 0;
365  
366          cmap += 16; // move to start of groups
367  
368 @@ -1084,13 +1183,24 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
369          while (left <= right) {
370              int middle = left + ( ( right - left ) >> 1 );
371  
372 -            quint32 startCharCode = qFromBigEndian<quint32>(cmap + 12*middle);
373 +            quint32 startCharCode;
374 +            if (!qSafeFromBigEndian(cmap + 12 * middle, end, &startCharCode))
375 +                return 0;
376 +
377              if(unicode < startCharCode)
378                  right = middle - 1;
379              else {
380 -                quint32 endCharCode = qFromBigEndian<quint32>(cmap + 12*middle + 4);
381 -                if(unicode <= endCharCode)
382 -                    return qFromBigEndian<quint32>(cmap + 12*middle + 8) + unicode - startCharCode;
383 +                quint32 endCharCode;
384 +                if (!qSafeFromBigEndian(cmap + 12 * middle + 4, end, &endCharCode))
385 +                    return 0;
386 +
387 +                if (unicode <= endCharCode) {
388 +                    quint32 index;
389 +                    if (!qSafeFromBigEndian(cmap + 12 * middle + 8, end, &index))
390 +                        return 0;
391 +
392 +                    return index + unicode - startCharCode;
393 +                }
394                  left = middle + 1;
395              }
396          }
397 diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
398 index ba01f4c..460aa5f 100644
399 --- a/src/gui/text/qfontengine_mac.mm
400 +++ b/src/gui/text/qfontengine_mac.mm
401 @@ -625,7 +625,7 @@ bool QFontEngineMacMulti::canRender(const QChar *string, int len)
402  }
403  
404  QFontEngineMac::QFontEngineMac(ATSUStyle baseStyle, ATSUFontID fontID, const QFontDef &def, QFontEngineMacMulti *multiEngine)
405 -    : fontID(fontID), multiEngine(multiEngine), cmap(0), symbolCMap(false)
406 +    : fontID(fontID), multiEngine(multiEngine), cmap(0), symbolCMap(false), cmapSize(0)
407  {
408      fontDef = def;
409      ATSUCreateAndCopyStyle(baseStyle, &style);
410 @@ -747,22 +747,21 @@ bool QFontEngineMac::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
411  {
412      if (!cmap) {
413          cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
414 -        int size = 0;
415 -        cmap = getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()), cmapTable.size(), &symbolCMap, &size);
416 +        cmap = getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()), cmapTable.size(), &symbolCMap, &cmapSize);
417          if (!cmap)
418              return false;
419      }
420      if (symbolCMap) {
421          for (int i = 0; i < len; ++i) {
422              unsigned int uc = getChar(str, i, len);
423 -            glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc);
424 +            glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
425              if(!glyphs->glyphs[i] && uc < 0x100)
426 -                glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
427 +                glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
428          }
429      } else {
430          for (int i = 0; i < len; ++i) {
431              unsigned int uc = getChar(str, i, len);
432 -            glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc);
433 +            glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
434          }
435      }
436  
437 diff --git a/src/gui/text/qfontengine_mac_p.h b/src/gui/text/qfontengine_mac_p.h
438 index 7d70c24..844d421 100644
439 --- a/src/gui/text/qfontengine_mac_p.h
440 +++ b/src/gui/text/qfontengine_mac_p.h
441 @@ -108,6 +108,7 @@ private:
442      qreal m_maxCharWidth;
443      QFixed m_xHeight;
444      QFixed m_averageCharWidth;
445 +    mutable int cmapSize;
446  };
447  
448  class QFontEngineMacMulti : public QFontEngineMulti
449 diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
450 index f29ac47..9c3435f 100644
451 --- a/src/gui/text/qfontengine_p.h
452 +++ b/src/gui/text/qfontengine_p.h
453 @@ -247,7 +247,7 @@ public:
454      QFontEngineGlyphCache *glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const;
455  
456      static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize);
457 -    static quint32 getTrueTypeGlyphIndex(const uchar *cmap, uint unicode);
458 +    static quint32 getTrueTypeGlyphIndex(const uchar *cmap, int cmapSize, uint unicode);
459  
460      static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily);
461  
462 diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
463 index 04f7b76..011d233 100644
464 --- a/src/gui/text/qfontengine_qpa.cpp
465 +++ b/src/gui/text/qfontengine_qpa.cpp
466 @@ -358,9 +358,9 @@ bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
467              unsigned int uc = getChar(str, i, len);
468              if (mirrored)
469                  uc = QChar::mirroredChar(uc);
470 -            glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
471 +            glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
472              if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
473 -                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
474 +                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
475              ++glyph_pos;
476          }
477      } else {
478 @@ -368,7 +368,7 @@ bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
479              unsigned int uc = getChar(str, i, len);
480              if (mirrored)
481                  uc = QChar::mirroredChar(uc);
482 -            glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
483 +            glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
484  #if 0 && defined(DEBUG_FONTENGINE)
485              QChar c(uc);
486              if (!findGlyph(glyphs[glyph_pos].glyph) && !seenGlyphs.contains(c))
487 @@ -511,16 +511,16 @@ bool QFontEngineQPA::canRender(const QChar *string, int len)
488      if (symbol) {
489          for (int i = 0; i < len; ++i) {
490              unsigned int uc = getChar(string, i, len);
491 -            glyph_t g = getTrueTypeGlyphIndex(cmap, uc);
492 +            glyph_t g = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
493              if(!g && uc < 0x100)
494 -                g = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
495 +                g = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
496              if (!g)
497                  return false;
498          }
499      } else {
500          for (int i = 0; i < len; ++i) {
501              unsigned int uc = getChar(string, i, len);
502 -            if (!getTrueTypeGlyphIndex(cmap, uc))
503 +            if (!getTrueTypeGlyphIndex(cmap, cmapSize, uc))
504                  return false;
505          }
506      }
507 diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp
508 index 8d5e71b..9087cff 100644
509 --- a/src/gui/text/qfontengine_qpf.cpp
510 +++ b/src/gui/text/qfontengine_qpf.cpp
511 @@ -577,9 +577,9 @@ bool QFontEngineQPF::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
512      if (symbol) {
513          for (int i = 0; i < len; ++i) {
514              unsigned int uc = getChar(str, i, len);
515 -            glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
516 +            glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
517              if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
518 -                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
519 +                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
520              ++glyph_pos;
521          }
522      } else {
523 @@ -587,7 +587,7 @@ bool QFontEngineQPF::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
524              unsigned int uc = getChar(str, i, len);
525              if (mirrored)
526                  uc = QChar::mirroredChar(uc);
527 -            glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
528 +            glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
529  #if 0 && defined(DEBUG_FONTENGINE)
530              QChar c(uc);
531              if (!findGlyph(glyphs[glyph_pos].glyph) && !seenGlyphs.contains(c))
532 @@ -786,16 +786,16 @@ bool QFontEngineQPF::canRender(const QChar *string, int len)
533      if (symbol) {
534          for (int i = 0; i < len; ++i) {
535              unsigned int uc = getChar(string, i, len);
536 -            glyph_t g = getTrueTypeGlyphIndex(cmap, uc);
537 +            glyph_t g = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
538              if(!g && uc < 0x100)
539 -                g = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
540 +                g = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
541              if (!g)
542                  return false;
543          }
544      } else {
545          for (int i = 0; i < len; ++i) {
546              unsigned int uc = getChar(string, i, len);
547 -            if (!getTrueTypeGlyphIndex(cmap, uc))
548 +            if (!getTrueTypeGlyphIndex(cmap, cmapSize, uc))
549                  return false;
550          }
551      }
552 diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp
553 index 1da501a..b2bb561 100644
554 --- a/src/gui/text/qfontengine_s60.cpp
555 +++ b/src/gui/text/qfontengine_s60.cpp
556 @@ -77,6 +77,7 @@ QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont
557      : m_cFont(cFont)
558      , m_symbolCMap(false)
559      , m_openFont(openFont)
560 +    , m_cmapSize(0)
561  {
562      if (!symbianFontTableApiAvailable()) {
563          TAny *trueTypeExtension = NULL;
564 @@ -161,10 +162,9 @@ const uchar *QSymbianTypeFaceExtras::cmap() const
565  {
566      if (m_cmapTable.isNull()) {
567          const QByteArray cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
568 -        int size = 0;
569          const uchar *cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>
570 -                (cmapTable.constData()), cmapTable.size(), &m_symbolCMap, &size);
571 -        m_cmapTable = QByteArray(reinterpret_cast<const char *>(cmap), size);
572 +                (cmapTable.constData()), cmapTable.size(), &m_symbolCMap, &m_cmapSize);
573 +        m_cmapTable = QByteArray(reinterpret_cast<const char *>(cmap), m_cmapSize);
574      }
575      return reinterpret_cast<const uchar *>(m_cmapTable.constData());
576  }
577 @@ -324,6 +324,7 @@ bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout
578      for (int i = 0; i < len; ++i) {
579          const unsigned int uc = getChar(characters, i, len);
580          *g++ = QFontEngine::getTrueTypeGlyphIndex(cmap,
581 +                                                  m_cmapSize,
582                          (isRtl && !m_extras->isSymbolCMap()) ? QChar::mirroredChar(uc) : uc);
583      }
584  
585 @@ -463,7 +464,7 @@ bool QFontEngineS60::canRender(const QChar *string, int len)
586      const unsigned char *cmap = m_extras->cmap();
587      for (int i = 0; i < len; ++i) {
588          const unsigned int uc = getChar(string, i, len);
589 -        if (QFontEngine::getTrueTypeGlyphIndex(cmap, uc) == 0)
590 +        if (QFontEngine::getTrueTypeGlyphIndex(cmap, m_cmapSize, uc) == 0)
591              return false;
592      }
593      return true;
594 diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h
595 index 17e2207..9e38570 100644
596 --- a/src/gui/text/qfontengine_s60_p.h
597 +++ b/src/gui/text/qfontengine_s60_p.h
598 @@ -93,6 +93,7 @@ private:
599      // the Font Table API
600      COpenFont *m_openFont;
601      mutable MOpenFontTrueTypeExtension *m_trueTypeExtension;
602 +    mutable int m_cmapSize;
603  };
604  
605  class QFontEngineS60 : public QFontEngine
606 diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp
607 index bd9a437..6ad5eb4 100644
608 --- a/src/gui/text/qfontengine_win.cpp
609 +++ b/src/gui/text/qfontengine_win.cpp
610 @@ -215,9 +215,8 @@ void QFontEngineWin::getCMap()
611      bool symb = false;
612      if (ttf) {
613          cmapTable = getSfntTable(qbswap<quint32>(MAKE_TAG('c', 'm', 'a', 'p')));
614 -        int size = 0;
615          cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()),
616 -                       cmapTable.size(), &symb, &size);
617 +                       cmapTable.size(), &symb, &cmapSize);
618      }
619      if (!cmap) {
620          ttf = false;
621 @@ -263,14 +262,14 @@ int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout
622          if (symbol) {
623              for (; i < numChars; ++i, ++glyph_pos) {
624                  unsigned int uc = getChar(str, i, numChars);
625 -                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
626 +                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
627                  if (!glyphs->glyphs[glyph_pos] && uc < 0x100)
628 -                    glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
629 +                    glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
630              }
631          } else if (ttf) {
632              for (; i < numChars; ++i, ++glyph_pos) {
633                  unsigned int uc = getChar(str, i, numChars);
634 -                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, QChar::mirroredChar(uc));
635 +                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, QChar::mirroredChar(uc));
636              }
637          } else {
638  #endif
639 @@ -296,14 +295,14 @@ int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout
640          if (symbol) {
641              for (; i < numChars; ++i, ++glyph_pos) {
642                  unsigned int uc = getChar(str, i, numChars);
643 -                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
644 +                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
645                  if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
646 -                    glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
647 +                    glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
648              }
649          } else if (ttf) {
650              for (; i < numChars; ++i, ++glyph_pos) {
651                  unsigned int uc = getChar(str, i, numChars);
652 -                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
653 +                glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
654              }
655          } else {
656  #endif
657 @@ -335,6 +334,7 @@ QFontEngineWin::QFontEngineWin(const QString &name, HFONT _hfont, bool stockFont
658      _name = name;
659  
660      cmap = 0;
661 +    cmapSize = 0;
662      hfont = _hfont;
663      logfont = lf;
664      HDC hdc = shared_dc();
665 @@ -811,9 +811,9 @@ bool QFontEngineWin::canRender(const QChar *string,  int len)
666      if (symbol) {
667          for (int i = 0; i < len; ++i) {
668              unsigned int uc = getChar(string, i, len);
669 -            if (getTrueTypeGlyphIndex(cmap, uc) == 0) {
670 +            if (getTrueTypeGlyphIndex(cmap, cmapSize, uc) == 0) {
671                  if (uc < 0x100) {
672 -                    if (getTrueTypeGlyphIndex(cmap, uc + 0xf000) == 0)
673 +                    if (getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000) == 0)
674                          return false;
675                  } else {
676                      return false;
677 @@ -823,7 +823,7 @@ bool QFontEngineWin::canRender(const QChar *string,  int len)
678      } else if (ttf) {
679          for (int i = 0; i < len; ++i) {
680              unsigned int uc = getChar(string, i, len);
681 -            if (getTrueTypeGlyphIndex(cmap, uc) == 0)
682 +            if (getTrueTypeGlyphIndex(cmap, cmapSize, uc) == 0)
683                  return false;
684          }
685      } else {
686 diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h
687 index 0c8df72..27f0355 100644
688 --- a/src/gui/text/qfontengine_win_p.h
689 +++ b/src/gui/text/qfontengine_win_p.h
690 @@ -144,6 +144,7 @@ public:
691      mutable uint widthCacheSize;
692      mutable QFixed *designAdvances;
693      mutable int designAdvancesSize;
694 +    int cmapSize;
695  
696  private:
697      bool hasCFFTable() const;
698 -- 
699 2.8.1
700
This page took 0.113542 seconds and 3 git commands to generate.