OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gdef.h" | 5 #include "gdef.h" |
6 | 6 |
| 7 #include <limits> |
7 #include <vector> | 8 #include <vector> |
8 | 9 |
9 #include "layout.h" | 10 #include "layout.h" |
10 #include "maxp.h" | 11 #include "maxp.h" |
11 | 12 |
12 // GDEF - The Glyph Definition Table | 13 // GDEF - The Glyph Definition Table |
13 // http://www.microsoft.com/typography/otspec/gdef.htm | 14 // http://www.microsoft.com/typography/otspec/gdef.htm |
14 | 15 |
15 namespace { | 16 namespace { |
16 | 17 |
(...skipping 16 matching lines...) Expand all Loading... |
33 size_t length, const uint16_t num_glyphs) { | 34 size_t length, const uint16_t num_glyphs) { |
34 ots::Buffer subtable(data, length); | 35 ots::Buffer subtable(data, length); |
35 | 36 |
36 uint16_t offset_coverage = 0; | 37 uint16_t offset_coverage = 0; |
37 uint16_t glyph_count = 0; | 38 uint16_t glyph_count = 0; |
38 if (!subtable.ReadU16(&offset_coverage) || | 39 if (!subtable.ReadU16(&offset_coverage) || |
39 !subtable.ReadU16(&glyph_count)) { | 40 !subtable.ReadU16(&glyph_count)) { |
40 return OTS_FAILURE(); | 41 return OTS_FAILURE(); |
41 } | 42 } |
42 const unsigned attach_points_end = static_cast<unsigned>(4) + 2*glyph_count; | 43 const unsigned attach_points_end = static_cast<unsigned>(4) + 2*glyph_count; |
| 44 if (attach_points_end > std::numeric_limits<uint16_t>::max()) { |
| 45 return OTS_FAILURE(); |
| 46 } |
43 if (offset_coverage == 0 || offset_coverage >= length || | 47 if (offset_coverage == 0 || offset_coverage >= length || |
44 offset_coverage < attach_points_end) { | 48 offset_coverage < attach_points_end) { |
45 return OTS_FAILURE(); | 49 return OTS_FAILURE(); |
46 } | 50 } |
47 if (glyph_count > num_glyphs) { | 51 if (glyph_count > num_glyphs) { |
48 OTS_WARNING("bad glyph count: %u", glyph_count); | 52 OTS_WARNING("bad glyph count: %u", glyph_count); |
49 return OTS_FAILURE(); | 53 return OTS_FAILURE(); |
50 } | 54 } |
51 | 55 |
52 std::vector<uint16_t> attach_points; | 56 std::vector<uint16_t> attach_points; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 bool ParseLigCaretListTable(ots::OpenTypeFile *file, const uint8_t *data, | 102 bool ParseLigCaretListTable(ots::OpenTypeFile *file, const uint8_t *data, |
99 size_t length, const uint16_t num_glyphs) { | 103 size_t length, const uint16_t num_glyphs) { |
100 ots::Buffer subtable(data, length); | 104 ots::Buffer subtable(data, length); |
101 uint16_t offset_coverage = 0; | 105 uint16_t offset_coverage = 0; |
102 uint16_t lig_glyph_count = 0; | 106 uint16_t lig_glyph_count = 0; |
103 if (!subtable.ReadU16(&offset_coverage) || | 107 if (!subtable.ReadU16(&offset_coverage) || |
104 !subtable.ReadU16(&lig_glyph_count)) { | 108 !subtable.ReadU16(&lig_glyph_count)) { |
105 return OTS_FAILURE(); | 109 return OTS_FAILURE(); |
106 } | 110 } |
107 const unsigned lig_glyphs_end = static_cast<unsigned>(4) + 2*lig_glyph_count; | 111 const unsigned lig_glyphs_end = static_cast<unsigned>(4) + 2*lig_glyph_count; |
| 112 if (lig_glyphs_end > std::numeric_limits<uint16_t>::max()) { |
| 113 return OTS_FAILURE(); |
| 114 } |
108 if (offset_coverage == 0 || offset_coverage >= length || | 115 if (offset_coverage == 0 || offset_coverage >= length || |
109 offset_coverage < lig_glyphs_end) { | 116 offset_coverage < lig_glyphs_end) { |
110 return OTS_FAILURE(); | 117 return OTS_FAILURE(); |
111 } | 118 } |
112 if (lig_glyph_count > num_glyphs) { | 119 if (lig_glyph_count > num_glyphs) { |
113 OTS_WARNING("bad ligature glyph count: %u", lig_glyph_count); | 120 OTS_WARNING("bad ligature glyph count: %u", lig_glyph_count); |
114 return OTS_FAILURE(); | 121 return OTS_FAILURE(); |
115 } | 122 } |
116 | 123 |
117 std::vector<uint16_t> lig_glyphs; | 124 std::vector<uint16_t> lig_glyphs; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 if (!subtable.ReadU16(&format) || | 207 if (!subtable.ReadU16(&format) || |
201 !subtable.ReadU16(&mark_set_count)) { | 208 !subtable.ReadU16(&mark_set_count)) { |
202 return OTS_FAILURE(); | 209 return OTS_FAILURE(); |
203 } | 210 } |
204 if (format != 1) { | 211 if (format != 1) { |
205 OTS_WARNING("bad mark glyph set table format: %u", format); | 212 OTS_WARNING("bad mark glyph set table format: %u", format); |
206 return OTS_FAILURE(); | 213 return OTS_FAILURE(); |
207 } | 214 } |
208 | 215 |
209 const unsigned mark_sets_end = static_cast<unsigned>(4) + 2*mark_set_count; | 216 const unsigned mark_sets_end = static_cast<unsigned>(4) + 2*mark_set_count; |
| 217 if (mark_sets_end > std::numeric_limits<uint16_t>::max()) { |
| 218 return OTS_FAILURE(); |
| 219 } |
210 for (unsigned i = 0; i < mark_set_count; ++i) { | 220 for (unsigned i = 0; i < mark_set_count; ++i) { |
211 uint32_t offset_coverage = 0; | 221 uint32_t offset_coverage = 0; |
212 if (!subtable.ReadU32(&offset_coverage)) { | 222 if (!subtable.ReadU32(&offset_coverage)) { |
213 return OTS_FAILURE(); | 223 return OTS_FAILURE(); |
214 } | 224 } |
215 if (offset_coverage >= length || | 225 if (offset_coverage >= length || |
216 offset_coverage < mark_sets_end) { | 226 offset_coverage < mark_sets_end) { |
217 return OTS_FAILURE(); | 227 return OTS_FAILURE(); |
218 } | 228 } |
219 if (!ots::ParseCoverageTable(data + offset_coverage, | 229 if (!ots::ParseCoverageTable(data + offset_coverage, |
220 length - offset_coverage, num_glyphs)) { | 230 length - offset_coverage, num_glyphs)) { |
221 return OTS_FAILURE(); | 231 return OTS_FAILURE(); |
222 } | 232 } |
223 } | 233 } |
| 234 file->gdef->num_mark_glyph_sets = mark_set_count; |
224 return true; | 235 return true; |
225 } | 236 } |
226 | 237 |
227 } // namespace | 238 } // namespace |
228 | 239 |
229 #define DROP_THIS_TABLE \ | 240 #define DROP_THIS_TABLE \ |
230 do { delete file->gdef; file->gdef = 0; } while (0) | 241 do { delete file->gdef; file->gdef = 0; } while (0) |
231 | 242 |
232 namespace ots { | 243 namespace ots { |
233 | 244 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 } | 281 } |
271 uint16_t offset_mark_glyph_sets_def = 0; | 282 uint16_t offset_mark_glyph_sets_def = 0; |
272 if (gdef->version_2) { | 283 if (gdef->version_2) { |
273 if (!table.ReadU16(&offset_mark_glyph_sets_def)) { | 284 if (!table.ReadU16(&offset_mark_glyph_sets_def)) { |
274 return OTS_FAILURE(); | 285 return OTS_FAILURE(); |
275 } | 286 } |
276 } | 287 } |
277 | 288 |
278 const unsigned gdef_header_end = static_cast<unsigned>(8) + | 289 const unsigned gdef_header_end = static_cast<unsigned>(8) + |
279 gdef->version_2 ? static_cast<unsigned>(2) : static_cast<unsigned>(0); | 290 gdef->version_2 ? static_cast<unsigned>(2) : static_cast<unsigned>(0); |
| 291 if (gdef_header_end > std::numeric_limits<uint16_t>::max()) { |
| 292 return OTS_FAILURE(); |
| 293 } |
| 294 |
280 // Parse subtables | 295 // Parse subtables |
281 if (offset_glyph_class_def) { | 296 if (offset_glyph_class_def) { |
282 if (offset_glyph_class_def >= length || | 297 if (offset_glyph_class_def >= length || |
283 offset_glyph_class_def < gdef_header_end) { | 298 offset_glyph_class_def < gdef_header_end) { |
284 return OTS_FAILURE(); | 299 return OTS_FAILURE(); |
285 } | 300 } |
286 if (!ParseGlyphClassDefTable(file, data + offset_glyph_class_def, | 301 if (!ParseGlyphClassDefTable(file, data + offset_glyph_class_def, |
287 length - offset_glyph_class_def, | 302 length - offset_glyph_class_def, |
288 num_glyphs)) { | 303 num_glyphs)) { |
289 DROP_THIS_TABLE; | 304 DROP_THIS_TABLE; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 offset_mark_attach_class_def < gdef_header_end) { | 337 offset_mark_attach_class_def < gdef_header_end) { |
323 return OTS_FAILURE(); | 338 return OTS_FAILURE(); |
324 } | 339 } |
325 if (!ParseMarkAttachClassDefTable(file, | 340 if (!ParseMarkAttachClassDefTable(file, |
326 data + offset_mark_attach_class_def, | 341 data + offset_mark_attach_class_def, |
327 length - offset_mark_attach_class_def, | 342 length - offset_mark_attach_class_def, |
328 num_glyphs)) { | 343 num_glyphs)) { |
329 DROP_THIS_TABLE; | 344 DROP_THIS_TABLE; |
330 return true; | 345 return true; |
331 } | 346 } |
| 347 gdef->has_mark_attachment_class_def = true; |
332 } | 348 } |
333 | 349 |
334 if (offset_mark_glyph_sets_def) { | 350 if (offset_mark_glyph_sets_def) { |
335 if (offset_mark_glyph_sets_def >= length || | 351 if (offset_mark_glyph_sets_def >= length || |
336 offset_mark_glyph_sets_def < gdef_header_end) { | 352 offset_mark_glyph_sets_def < gdef_header_end) { |
337 return OTS_FAILURE(); | 353 return OTS_FAILURE(); |
338 } | 354 } |
339 if (!ParseMarkGlyphSetsDefTable(file, | 355 if (!ParseMarkGlyphSetsDefTable(file, |
340 data + offset_mark_glyph_sets_def, | 356 data + offset_mark_glyph_sets_def, |
341 length - offset_mark_glyph_sets_def, | 357 length - offset_mark_glyph_sets_def, |
342 num_glyphs)) { | 358 num_glyphs)) { |
343 DROP_THIS_TABLE; | 359 DROP_THIS_TABLE; |
344 return true; | 360 return true; |
345 } | 361 } |
| 362 gdef->has_mark_glyph_sets_def = true; |
346 } | 363 } |
347 gdef->data = data; | 364 gdef->data = data; |
348 gdef->length = length; | 365 gdef->length = length; |
349 return true; | 366 return true; |
350 } | 367 } |
351 | 368 |
352 bool ots_gdef_should_serialise(OpenTypeFile *file) { | 369 bool ots_gdef_should_serialise(OpenTypeFile *file) { |
353 return file->gdef != NULL; | 370 return file->gdef != NULL; |
354 } | 371 } |
355 | 372 |
356 bool ots_gdef_serialise(OTSStream *out, OpenTypeFile *file) { | 373 bool ots_gdef_serialise(OTSStream *out, OpenTypeFile *file) { |
357 if (!out->Write(file->gdef->data, file->gdef->length)) { | 374 if (!out->Write(file->gdef->data, file->gdef->length)) { |
358 return OTS_FAILURE(); | 375 return OTS_FAILURE(); |
359 } | 376 } |
360 | 377 |
361 return true; | 378 return true; |
362 } | 379 } |
363 | 380 |
364 void ots_gdef_free(OpenTypeFile *file) { | 381 void ots_gdef_free(OpenTypeFile *file) { |
365 delete file->gdef; | 382 delete file->gdef; |
366 } | 383 } |
367 | 384 |
368 } // namespace ots | 385 } // namespace ots |
369 | 386 |
OLD | NEW |