Coverage Report

Created: 2026-10-17 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ots/src/cff_charstring.cc
Line
Count
Source
1
// Copyright (c) 2010-2017 The OTS Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
// A parser for the Type 2 Charstring Format.
6
// http://www.adobe.com/devnet/font/pdfs/5177.Type2.pdf
7
8
#include "cff_charstring.h"
9
10
#include <climits>
11
#include <cstdio>
12
#include <cstring>
13
#include <stack>
14
#include <string>
15
#include <utility>
16
17
#define TABLE_NAME "CFF"
18
19
namespace {
20
21
// Type 2 Charstring Implementation Limits. See Appendix. B in Adobe Technical
22
// Note #5177.
23
const int32_t kMaxSubrsCount = 65536;
24
const size_t kMaxCharStringLength = 65535;
25
const size_t kMaxNumberOfStemHints = 96;
26
const size_t kMaxSubrNesting = 10;
27
28
// We reject the table if any charstring results in executing too many ops.
29
// This should be more than enough for any realistic use case; only a malicious
30
// font would run millions of ops for a single glyph.
31
const uint32_t kMaxCharStringOps = 1024 * 1024 * 64;
32
33
// |dummy_result| should be a huge positive integer so callsubr and callgsubr
34
// will fail with the dummy value.
35
const int32_t dummy_result = INT_MAX;
36
37
bool ExecuteCharString(ots::OpenTypeCFF& cff,
38
                       size_t call_depth,
39
                       const ots::CFFIndex& global_subrs_index,
40
                       const ots::CFFIndex& local_subrs_index,
41
                       ots::Buffer *cff_table,
42
                       ots::Buffer *char_string,
43
                       std::stack<int32_t> *argument_stack,
44
                       ots::CharStringContext& cs_ctx);
45
46
55.2M
bool ArgumentStackOverflows(std::stack<int32_t> *argument_stack, bool cff2) {
47
55.2M
  if ((cff2 && argument_stack->size() > ots::kMaxCFF2ArgumentStack) ||
48
55.2M
      (!cff2 && argument_stack->size() > ots::kMaxCFF1ArgumentStack)) {
49
9
    return true;
50
9
  }
51
55.2M
  return false;
52
55.2M
}
53
54
#ifdef DUMP_T2CHARSTRING
55
// Converts |op| to a string and returns it.
56
const char *CharStringOperatorToString(ots::CharStringOperator op) {
57
  switch (op) {
58
  case ots::kHStem:
59
    return "hstem";
60
  case ots::kVStem:
61
    return "vstem";
62
  case ots::kVMoveTo:
63
    return "vmoveto";
64
  case ots::kRLineTo:
65
    return "rlineto";
66
  case ots::kHLineTo:
67
    return "hlineto";
68
  case ots::kVLineTo:
69
    return "vlineto";
70
  case ots::kRRCurveTo:
71
    return "rrcurveto";
72
  case ots::kCallSubr:
73
    return "callsubr";
74
  case ots::kReturn:
75
    return "return";
76
  case ots::kEndChar:
77
    return "endchar";
78
  case ots::kVSIndex:
79
    return "vsindex";
80
  case ots::kBlend:
81
    return "blend";
82
  case ots::kHStemHm:
83
    return "hstemhm";
84
  case ots::kHintMask:
85
    return "hintmask";
86
  case ots::kCntrMask:
87
    return "cntrmask";
88
  case ots::kRMoveTo:
89
    return "rmoveto";
90
  case ots::kHMoveTo:
91
    return "hmoveto";
92
  case ots::kVStemHm:
93
    return "vstemhm";
94
  case ots::kRCurveLine:
95
    return "rcurveline";
96
  case ots::kRLineCurve:
97
    return "rlinecurve";
98
  case ots::kVVCurveTo:
99
    return "VVCurveTo";
100
  case ots::kHHCurveTo:
101
    return "hhcurveto";
102
  case ots::kCallGSubr:
103
    return "callgsubr";
104
  case ots::kVHCurveTo:
105
    return "vhcurveto";
106
  case ots::kHVCurveTo:
107
    return "HVCurveTo";
108
  case ots::kDotSection:
109
    return "dotsection";
110
  case ots::kAnd:
111
    return "and";
112
  case ots::kOr:
113
    return "or";
114
  case ots::kNot:
115
    return "not";
116
  case ots::kAbs:
117
    return "abs";
118
  case ots::kAdd:
119
    return "add";
120
  case ots::kSub:
121
    return "sub";
122
  case ots::kDiv:
123
    return "div";
124
  case ots::kNeg:
125
    return "neg";
126
  case ots::kEq:
127
    return "eq";
128
  case ots::kDrop:
129
    return "drop";
130
  case ots::kPut:
131
    return "put";
132
  case ots::kGet:
133
    return "get";
134
  case ots::kIfElse:
135
    return "ifelse";
136
  case ots::kRandom:
137
    return "random";
138
  case ots::kMul:
139
    return "mul";
140
  case ots::kSqrt:
141
    return "sqrt";
142
  case ots::kDup:
143
    return "dup";
144
  case ots::kExch:
145
    return "exch";
146
  case ots::kIndex:
147
    return "index";
148
  case ots::kRoll:
149
    return "roll";
150
  case ots::kHFlex:
151
    return "hflex";
152
  case ots::kFlex:
153
    return "flex";
154
  case ots::kHFlex1:
155
    return "hflex1";
156
  case ots::kFlex1:
157
    return "flex1";
158
  }
159
160
  return "UNKNOWN";
161
}
162
#endif
163
164
// Read one or more bytes from the |char_string| buffer and stores the number
165
// read on |out_number|. If the number read is an operator (ex 'vstem'), sets
166
// true on |out_is_operator|. Returns true if the function read a number.
167
bool ReadNextNumberFromCharString(ots::Buffer *char_string,
168
                                  int32_t *out_number,
169
153M
                                  bool *out_is_operator) {
170
153M
  uint8_t v = 0;
171
153M
  if (!char_string->ReadU8(&v)) {
172
0
    return OTS_FAILURE();
173
0
  }
174
153M
  *out_is_operator = false;
175
176
  // The conversion algorithm is described in Adobe Technical Note #5177, page
177
  // 13, Table 1.
178
153M
  if (v <= 11) {
179
97.5M
    *out_number = v;
180
97.5M
    *out_is_operator = true;
181
97.5M
  } else if (v == 12) {
182
3.08k
    uint16_t result = (v << 8);
183
3.08k
    if (!char_string->ReadU8(&v)) {
184
1
      return OTS_FAILURE();
185
1
    }
186
3.08k
    result += v;
187
3.08k
    *out_number = result;
188
3.08k
    *out_is_operator = true;
189
56.0M
  } else if (v <= 27) {
190
    // Special handling for v==19 and v==20 are implemented in
191
    // ExecuteCharStringOperator().
192
566k
    *out_number = v;
193
566k
    *out_is_operator = true;
194
55.5M
  } else if (v == 28) {
195
61.7k
    if (!char_string->ReadU8(&v)) {
196
1
      return OTS_FAILURE();
197
1
    }
198
61.7k
    uint16_t result = (v << 8);
199
61.7k
    if (!char_string->ReadU8(&v)) {
200
2
      return OTS_FAILURE();
201
2
    }
202
61.7k
    result += v;
203
61.7k
    *out_number = static_cast<int16_t>(result);
204
55.4M
  } else if (v <= 31) {
205
251k
    *out_number = v;
206
251k
    *out_is_operator = true;
207
55.1M
  } else if (v <= 246) {
208
53.9M
    *out_number = static_cast<int32_t>(v) - 139;
209
53.9M
  } else if (v <= 250) {
210
653k
    uint8_t w = 0;
211
653k
    if (!char_string->ReadU8(&w)) {
212
1
      return OTS_FAILURE();
213
1
    }
214
653k
    *out_number = ((static_cast<int32_t>(v) - 247) * 256) +
215
653k
        static_cast<int32_t>(w) + 108;
216
653k
  } else if (v <= 254) {
217
535k
    uint8_t w = 0;
218
535k
    if (!char_string->ReadU8(&w)) {
219
4
      return OTS_FAILURE();
220
4
    }
221
535k
    *out_number = -((static_cast<int32_t>(v) - 251) * 256) -
222
535k
        static_cast<int32_t>(w) - 108;
223
535k
  } else if (v == 255) {
224
    // TODO(yusukes): We should not skip the 4 bytes. Note that when v is 255,
225
    // we should treat the following 4-bytes as a 16.16 fixed-point number
226
    // rather than 32bit signed int.
227
2.96k
    if (!char_string->Skip(4)) {
228
4
      return OTS_FAILURE();
229
4
    }
230
2.95k
    *out_number = dummy_result;
231
2.95k
  } else {
232
0
    return OTS_FAILURE();
233
0
  }
234
235
153M
  return true;
236
153M
}
237
238
1.22M
bool ValidCFF2Operator(int32_t op) {
239
1.22M
  switch (op) {
240
2
  case ots::kReturn:
241
3
  case ots::kEndChar:
242
4
  case ots::kAbs:
243
5
  case ots::kAdd:
244
6
  case ots::kSub:
245
7
  case ots::kDiv:
246
8
  case ots::kNeg:
247
9
  case ots::kRandom:
248
10
  case ots::kMul:
249
11
  case ots::kSqrt:
250
12
  case ots::kDrop:
251
13
  case ots::kExch:
252
14
  case ots::kIndex:
253
15
  case ots::kRoll:
254
16
  case ots::kDup:
255
17
  case ots::kPut:
256
18
  case ots::kGet:
257
19
  case ots::kDotSection:
258
20
  case ots::kAnd:
259
21
  case ots::kOr:
260
23
  case ots::kNot:
261
24
  case ots::kEq:
262
25
  case ots::kIfElse:
263
25
    return false;
264
1.22M
  }
265
266
1.22M
  return true;
267
1.22M
}
268
269
// Executes |op| and updates |argument_stack|. Returns true if the execution
270
// succeeds. If the |op| is kCallSubr or kCallGSubr, the function recursively
271
// calls ExecuteCharString() function. The |cs_ctx| argument holds values that
272
// need to persist through these calls (see CharStringContext for details)
273
bool ExecuteCharStringOperator(ots::OpenTypeCFF& cff,
274
                               int32_t op,
275
                               size_t call_depth,
276
                               const ots::CFFIndex& global_subrs_index,
277
                               const ots::CFFIndex& local_subrs_index,
278
                               ots::Buffer *cff_table,
279
                               ots::Buffer *char_string,
280
                               std::stack<int32_t> *argument_stack,
281
98.3M
                               ots::CharStringContext& cs_ctx) {
282
98.3M
  ots::Font* font = cff.GetFont();
283
98.3M
  const size_t stack_size = argument_stack->size();
284
285
98.3M
  if (cs_ctx.cff2 && !ValidCFF2Operator(op)) {
286
25
    return OTS_FAILURE();
287
25
  }
288
289
98.3M
  switch (op) {
290
48.7M
  case ots::kCallSubr:
291
48.7M
  case ots::kCallGSubr: {
292
48.7M
    const ots::CFFIndex& subrs_index =
293
48.7M
        (op == ots::kCallSubr ? local_subrs_index : global_subrs_index);
294
295
48.7M
    if (stack_size < 1) {
296
10
      return OTS_FAILURE();
297
10
    }
298
48.7M
    int32_t subr_number = argument_stack->top();
299
48.7M
    argument_stack->pop();
300
48.7M
    if (subr_number == dummy_result) {
301
      // For safety, we allow subr calls only with immediate subr numbers for
302
      // now. For example, we allow "123 callgsubr", but does not allow "100 12
303
      // add callgsubr". Please note that arithmetic and conditional operators
304
      // always push the |dummy_result| in this implementation.
305
2
      return OTS_FAILURE();
306
2
    }
307
308
    // See Adobe Technical Note #5176 (CFF), "16. Local/GlobalSubrs INDEXes."
309
48.7M
    int32_t bias = 32768;
310
48.7M
    if (subrs_index.count < 1240) {
311
48.5M
      bias = 107;
312
48.5M
    } else if (subrs_index.count < 33900) {
313
161k
      bias = 1131;
314
161k
    }
315
48.7M
    subr_number += bias;
316
317
    // Sanity checks of |subr_number|.
318
48.7M
    if (subr_number < 0) {
319
2
      return OTS_FAILURE();
320
2
    }
321
48.7M
    if (subr_number >= kMaxSubrsCount) {
322
0
      return OTS_FAILURE();
323
0
    }
324
48.7M
    if (subrs_index.offsets.size() <= static_cast<size_t>(subr_number + 1)) {
325
18
      return OTS_FAILURE();  // The number is out-of-bounds.
326
18
    }
327
328
    // Prepare ots::Buffer where we're going to jump.
329
48.7M
    const size_t length =
330
48.7M
      subrs_index.offsets[subr_number + 1] - subrs_index.offsets[subr_number];
331
48.7M
    if (length > kMaxCharStringLength) {
332
0
      return OTS_FAILURE();
333
0
    }
334
48.7M
    const size_t offset = subrs_index.offsets[subr_number];
335
48.7M
    cff_table->set_offset(offset);
336
48.7M
    if (!cff_table->Skip(length)) {
337
0
      return OTS_FAILURE();
338
0
    }
339
48.7M
    ots::Buffer char_string_to_jump(cff_table->buffer() + offset, length);
340
341
48.7M
    return ExecuteCharString(cff,
342
48.7M
                             call_depth + 1,
343
48.7M
                             global_subrs_index,
344
48.7M
                             local_subrs_index,
345
48.7M
                             cff_table,
346
48.7M
                             &char_string_to_jump,
347
48.7M
                             argument_stack,
348
48.7M
                             cs_ctx);
349
48.7M
  }
350
351
48.4M
  case ots::kReturn:
352
48.4M
    return true;
353
354
19.6k
  case ots::kEndChar:
355
19.6k
    cs_ctx.endchar_seen = true;
356
19.6k
    cs_ctx.width_seen = true;  // just in case.
357
19.6k
    return true;
358
359
565
  case ots::kVSIndex: {
360
565
    if (!cs_ctx.cff2) {
361
1
      return OTS_FAILURE();
362
1
    }
363
564
    if (stack_size != 1) {
364
1
      return OTS_FAILURE();
365
1
    }
366
563
    if (cs_ctx.blend_seen || cs_ctx.vsindex_seen) {
367
2
      return OTS_FAILURE();
368
2
    }
369
561
    if (argument_stack->top() < 0 ||
370
558
        argument_stack->top() >= (int32_t)cff.region_index_count.size()) {
371
4
      return OTS_FAILURE();
372
4
    }
373
557
    cs_ctx.vsindex_seen = true;
374
557
    cs_ctx.vsindex = argument_stack->top();
375
1.11k
    while (!argument_stack->empty())
376
557
      argument_stack->pop();
377
557
    return true;
378
561
  }
379
380
180k
  case ots::kBlend: {
381
180k
    if (!cs_ctx.cff2) {
382
4
      return OTS_FAILURE();
383
4
    }
384
180k
    if (stack_size < 1) {
385
1
      return OTS_FAILURE();
386
1
    }
387
180k
    if (cs_ctx.vsindex >= (int32_t)cff.region_index_count.size()) {
388
2
      return OTS_FAILURE();
389
2
    }
390
180k
    uint16_t k = cff.region_index_count.at(cs_ctx.vsindex);
391
180k
    uint16_t n = argument_stack->top();
392
180k
    if (stack_size < n * (k + 1u) + 1u) {
393
10
      return OTS_FAILURE();
394
10
    }
395
396
    // Keep the 1st n operands on the stack for the next operator to use and
397
    // pop the rest. There can be multiple consecutive blend operators, so this
398
    // makes sure the operands of all of them are kept on the stack.
399
1.62M
    while (argument_stack->size() > stack_size - ((n * k) + 1))
400
1.44M
      argument_stack->pop();
401
180k
    cs_ctx.blend_seen = true;
402
180k
    return true;
403
180k
  }
404
405
454
  case ots::kHStem:
406
1.05k
  case ots::kVStem:
407
1.60k
  case ots::kHStemHm:
408
2.19k
  case ots::kVStemHm: {
409
2.19k
    bool successful = false;
410
2.19k
    if (stack_size < 2) {
411
8
      return OTS_FAILURE();
412
8
    }
413
2.18k
    if (op == ots::kHStem || op == ots::kHStemHm) {
414
1.00k
      if (cs_ctx.hint_state > ots::kHs) {
415
5
        return OTS_FAILURE();
416
5
      }
417
1.18k
    } else {
418
1.18k
      if (cs_ctx.hint_state > ots::kVs) {
419
5
        return OTS_FAILURE();
420
5
      }
421
1.17k
      cs_ctx.hint_state = ots::kVs;
422
1.17k
    }
423
2.17k
    if ((stack_size % 2) == 0) {
424
1.50k
      successful = true;
425
1.50k
    } else if ((!(cs_ctx.width_seen)) && (((stack_size - 1) % 2) == 0)) {
426
      // The -1 is for "width" argument. For details, see Adobe Technical Note
427
      // #5177, page 16, note 4.
428
664
      successful = true;
429
664
    }
430
2.17k
    cs_ctx.num_stems += (stack_size / 2);
431
2.17k
    if ((cs_ctx.num_stems) > kMaxNumberOfStemHints) {
432
12
      return OTS_FAILURE();
433
12
    }
434
15.1k
    while (!argument_stack->empty())
435
13.0k
      argument_stack->pop();
436
2.16k
    cs_ctx.width_seen = true;  // always set true since "w" might be 0 byte.
437
2.16k
    return successful ? true : OTS_FAILURE();
438
2.17k
  }
439
440
150k
  case ots::kRMoveTo: {
441
150k
    bool successful = false;
442
150k
    if (stack_size == 2) {
443
135k
      successful = true;
444
135k
    } else if ((!(cs_ctx.width_seen)) && (stack_size - 1 == 2)) {
445
15.1k
      successful = true;
446
15.1k
    }
447
467k
    while (!argument_stack->empty())
448
316k
      argument_stack->pop();
449
150k
    cs_ctx.width_seen = true;
450
150k
    cs_ctx.hint_state = ots::kHm;
451
150k
    return successful ? true : OTS_FAILURE();
452
2.17k
  }
453
454
4.94k
  case ots::kVMoveTo:
455
22.5k
  case ots::kHMoveTo: {
456
22.5k
    bool successful = false;
457
22.5k
    if (stack_size == 1) {
458
19.9k
      successful = true;
459
19.9k
    } else if ((!(cs_ctx.width_seen)) && (stack_size - 1 == 1)) {
460
2.62k
      successful = true;
461
2.62k
    }
462
48.0k
    while (!argument_stack->empty())
463
25.4k
      argument_stack->pop();
464
22.5k
    cs_ctx.width_seen = true;
465
22.5k
    cs_ctx.hint_state = ots::kHm;
466
22.5k
    return successful ? true : OTS_FAILURE();
467
4.94k
  }
468
469
1.45k
  case ots::kHintMask:
470
1.82k
  case ots::kCntrMask: {
471
1.82k
    bool successful = false;
472
1.82k
    if (stack_size == 0) {
473
1.19k
      successful = true;
474
1.19k
    } else if ((!(cs_ctx.width_seen)) && (stack_size == 1)) {
475
      // A number for "width" is found.
476
1
      successful = true;
477
626
    } else if ((!(cs_ctx.width_seen)) ||  // in this case, any sizes are ok.
478
621
               ((stack_size % 2) == 0)) {
479
      // The numbers are vstem definition.
480
      // See Adobe Technical Note #5177, page 24, hintmask.
481
621
      cs_ctx.num_stems += (stack_size / 2);
482
621
      if ((cs_ctx.num_stems) > kMaxNumberOfStemHints) {
483
1
        return OTS_FAILURE();
484
1
      }
485
620
      successful = true;
486
620
    }
487
1.82k
    if (!successful) {
488
5
       return OTS_FAILURE();
489
5
    }
490
1.81k
    if (op == ots::kHintMask) {
491
1.44k
      cs_ctx.hint_state = ots::kHm;
492
1.44k
    } else {
493
366
      if (cs_ctx.hint_state > ots::kCm) {
494
4
        return OTS_FAILURE();
495
4
      }
496
362
      cs_ctx.hint_state = ots::kCm;
497
362
    }
498
1.81k
    if ((cs_ctx.num_stems) == 0) {
499
4
      return OTS_FAILURE();
500
4
    }
501
1.80k
    const size_t mask_bytes = (cs_ctx.num_stems + 7) / 8;
502
1.80k
    if (!char_string->Skip(mask_bytes)) {
503
2
      return OTS_FAILURE();
504
2
    }
505
6.08k
    while (!argument_stack->empty())
506
4.27k
      argument_stack->pop();
507
1.80k
    cs_ctx.width_seen = true;
508
1.80k
    return true;
509
1.80k
  }
510
511
113k
  case ots::kRLineTo:
512
113k
    if (!(cs_ctx.width_seen)) {
513
      // The first stack-clearing operator should be one of hstem, hstemhm,
514
      // vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto, rmoveto, or
515
      // endchar. For details, see Adobe Technical Note #5177, page 16, note 4.
516
1
      return OTS_FAILURE();
517
1
    }
518
113k
    if (stack_size < 2) {
519
4
      return OTS_FAILURE();
520
4
    }
521
113k
    if ((stack_size % 2) != 0) {
522
2
      return OTS_FAILURE();
523
2
    }
524
546k
    while (!argument_stack->empty())
525
433k
      argument_stack->pop();
526
113k
    return true;
527
528
116k
  case ots::kHLineTo:
529
183k
  case ots::kVLineTo:
530
183k
    if (!(cs_ctx.width_seen)) {
531
4
      return OTS_FAILURE();
532
4
    }
533
183k
    if (stack_size < 1) {
534
3
      return OTS_FAILURE();
535
3
    }
536
482k
    while (!argument_stack->empty())
537
298k
      argument_stack->pop();
538
183k
    return true;
539
540
83.2k
  case ots::kRRCurveTo:
541
83.2k
    if (!(cs_ctx.width_seen)) {
542
2
      return OTS_FAILURE();
543
2
    }
544
83.2k
    if (stack_size < 6) {
545
8
      return OTS_FAILURE();
546
8
    }
547
83.1k
    if ((stack_size % 6) != 0) {
548
7
      return OTS_FAILURE();
549
7
    }
550
1.28M
    while (!argument_stack->empty())
551
1.20M
      argument_stack->pop();
552
83.1k
    return true;
553
554
23.4k
  case ots::kRCurveLine:
555
23.4k
    if (!(cs_ctx.width_seen)) {
556
1
      return OTS_FAILURE();
557
1
    }
558
23.4k
    if (stack_size < 8) {
559
1
      return OTS_FAILURE();
560
1
    }
561
23.4k
    if (((stack_size - 2) % 6) != 0) {
562
2
      return OTS_FAILURE();
563
2
    }
564
273k
    while (!argument_stack->empty())
565
250k
      argument_stack->pop();
566
23.4k
    return true;
567
568
19.4k
  case ots::kRLineCurve:
569
19.4k
    if (!(cs_ctx.width_seen)) {
570
2
      return OTS_FAILURE();
571
2
    }
572
19.4k
    if (stack_size < 8) {
573
3
      return OTS_FAILURE();
574
3
    }
575
19.3k
    if (((stack_size - 6) % 2) != 0) {
576
2
      return OTS_FAILURE();
577
2
    }
578
193k
    while (!argument_stack->empty())
579
174k
      argument_stack->pop();
580
19.3k
    return true;
581
582
74.2k
  case ots::kVVCurveTo:
583
74.2k
    if (!(cs_ctx.width_seen)) {
584
1
      return OTS_FAILURE();
585
1
    }
586
74.2k
    if (stack_size < 4) {
587
1
      return OTS_FAILURE();
588
1
    }
589
74.2k
    if (((stack_size % 4) != 0) &&
590
66.2k
        (((stack_size - 1) % 4) != 0)) {
591
3
      return OTS_FAILURE();
592
3
    }
593
446k
    while (!argument_stack->empty())
594
372k
      argument_stack->pop();
595
74.2k
    return true;
596
597
77.5k
  case ots::kHHCurveTo: {
598
77.5k
    bool successful = false;
599
77.5k
    if (!(cs_ctx.width_seen)) {
600
1
      return OTS_FAILURE();
601
1
    }
602
77.5k
    if (stack_size < 4) {
603
2
      return OTS_FAILURE();
604
2
    }
605
77.5k
    if ((stack_size % 4) == 0) {
606
      // {dxa dxb dyb dxc}+
607
7.22k
      successful = true;
608
70.3k
    } else if (((stack_size - 1) % 4) == 0) {
609
      // dy1? {dxa dxb dyb dxc}+
610
70.3k
      successful = true;
611
70.3k
    }
612
478k
    while (!argument_stack->empty())
613
401k
      argument_stack->pop();
614
77.5k
    return successful ? true : OTS_FAILURE();
615
77.5k
  }
616
617
124k
  case ots::kVHCurveTo:
618
238k
  case ots::kHVCurveTo: {
619
238k
    bool successful = false;
620
238k
    if (!(cs_ctx.width_seen)) {
621
2
      return OTS_FAILURE();
622
2
    }
623
238k
    if (stack_size < 4) {
624
3
      return OTS_FAILURE();
625
3
    }
626
238k
    if (((stack_size - 4) % 8) == 0) {
627
      // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}*
628
58.1k
      successful = true;
629
180k
    } else if ((stack_size >= 5) &&
630
180k
               ((stack_size - 5) % 8) == 0) {
631
      // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf
632
118k
      successful = true;
633
118k
    } else if ((stack_size >= 8) &&
634
62.0k
               ((stack_size - 8) % 8) == 0) {
635
      // {dxa dxb dyb dyc dyd dxe dye dxf}+
636
41.2k
      successful = true;
637
41.2k
    } else if ((stack_size >= 9) &&
638
20.7k
               ((stack_size - 9) % 8) == 0) {
639
      // {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf?
640
20.7k
      successful = true;
641
20.7k
    }
642
1.80M
    while (!argument_stack->empty())
643
1.56M
      argument_stack->pop();
644
238k
    return successful ? true : OTS_FAILURE();
645
238k
  }
646
647
22
  case ots::kDotSection:
648
    // Deprecated operator but harmless, we probably should drop it some how.
649
22
    if (stack_size != 0) {
650
1
      return OTS_FAILURE();
651
1
    }
652
21
    return true;
653
654
134
  case ots::kAnd:
655
342
  case ots::kOr:
656
467
  case ots::kEq:
657
597
  case ots::kAdd:
658
700
  case ots::kSub:
659
700
    if (stack_size < 2) {
660
2
      return OTS_FAILURE();
661
2
    }
662
698
    argument_stack->pop();
663
698
    argument_stack->pop();
664
698
    argument_stack->push(dummy_result);
665
    // TODO(yusukes): Implement this. We should push a real value for all
666
    // arithmetic and conditional operations.
667
698
    return true;
668
669
188
  case ots::kNot:
670
349
  case ots::kAbs:
671
608
  case ots::kNeg:
672
608
    if (stack_size < 1) {
673
1
      return OTS_FAILURE();
674
1
    }
675
607
    argument_stack->pop();
676
607
    argument_stack->push(dummy_result);
677
    // TODO(yusukes): Implement this. We should push a real value for all
678
    // arithmetic and conditional operations.
679
607
    return true;
680
681
452
  case ots::kDiv:
682
    // TODO(yusukes): Should detect div-by-zero errors.
683
452
    if (stack_size < 2) {
684
1
      return OTS_FAILURE();
685
1
    }
686
451
    argument_stack->pop();
687
451
    argument_stack->pop();
688
451
    argument_stack->push(dummy_result);
689
    // TODO(yusukes): Implement this. We should push a real value for all
690
    // arithmetic and conditional operations.
691
451
    return true;
692
693
173
  case ots::kDrop:
694
173
    if (stack_size < 1) {
695
1
      return OTS_FAILURE();
696
1
    }
697
172
    argument_stack->pop();
698
172
    return true;
699
700
1
  case ots::kPut:
701
2
  case ots::kGet:
702
3
  case ots::kIndex:
703
    // For now, just call OTS_FAILURE since there is no way to check whether the
704
    // index argument, |i|, is out-of-bounds or not. Fortunately, no OpenType
705
    // fonts I have (except malicious ones!) use the operators.
706
    // TODO(yusukes): Implement them in a secure way.
707
3
    return OTS_FAILURE();
708
709
1
  case ots::kRoll:
710
    // Likewise, just call OTS_FAILURE for kRoll since there is no way to check
711
    // whether |N| is smaller than the current stack depth or not.
712
    // TODO(yusukes): Implement them in a secure way.
713
1
    return OTS_FAILURE();
714
715
2
  case ots::kRandom:
716
    // For now, we don't handle the 'random' operator since the operator makes
717
    // it hard to analyze hinting code statically.
718
2
    return OTS_FAILURE();
719
720
241
  case ots::kIfElse:
721
241
    if (stack_size < 4) {
722
1
      return OTS_FAILURE();
723
1
    }
724
240
    argument_stack->pop();
725
240
    argument_stack->pop();
726
240
    argument_stack->pop();
727
240
    argument_stack->pop();
728
240
    argument_stack->push(dummy_result);
729
    // TODO(yusukes): Implement this. We should push a real value for all
730
    // arithmetic and conditional operations.
731
240
    return true;
732
733
136
  case ots::kMul:
734
    // TODO(yusukes): Should detect overflows.
735
136
    if (stack_size < 2) {
736
1
      return OTS_FAILURE();
737
1
    }
738
135
    argument_stack->pop();
739
135
    argument_stack->pop();
740
135
    argument_stack->push(dummy_result);
741
    // TODO(yusukes): Implement this. We should push a real value for all
742
    // arithmetic and conditional operations.
743
135
    return true;
744
745
231
  case ots::kSqrt:
746
    // TODO(yusukes): Should check if the argument is negative.
747
231
    if (stack_size < 1) {
748
2
      return OTS_FAILURE();
749
2
    }
750
229
    argument_stack->pop();
751
229
    argument_stack->push(dummy_result);
752
    // TODO(yusukes): Implement this. We should push a real value for all
753
    // arithmetic and conditional operations.
754
229
    return true;
755
756
171
  case ots::kDup:
757
171
    if (stack_size < 1) {
758
1
      return OTS_FAILURE();
759
1
    }
760
170
    argument_stack->pop();
761
170
    argument_stack->push(dummy_result);
762
170
    argument_stack->push(dummy_result);
763
170
    if (ArgumentStackOverflows(argument_stack, cs_ctx.cff2)) {
764
1
      return OTS_FAILURE();
765
1
    }
766
    // TODO(yusukes): Implement this. We should push a real value for all
767
    // arithmetic and conditional operations.
768
169
    return true;
769
770
106
  case ots::kExch:
771
106
    if (stack_size < 2) {
772
1
      return OTS_FAILURE();
773
1
    }
774
105
    argument_stack->pop();
775
105
    argument_stack->pop();
776
105
    argument_stack->push(dummy_result);
777
105
    argument_stack->push(dummy_result);
778
    // TODO(yusukes): Implement this. We should push a real value for all
779
    // arithmetic and conditional operations.
780
105
    return true;
781
782
85
  case ots::kHFlex:
783
85
    if (!(cs_ctx.width_seen)) {
784
1
      return OTS_FAILURE();
785
1
    }
786
84
    if (stack_size != 7) {
787
1
      return OTS_FAILURE();
788
1
    }
789
664
    while (!argument_stack->empty())
790
581
      argument_stack->pop();
791
83
    return true;
792
793
43
  case ots::kFlex:
794
43
    if (!(cs_ctx.width_seen)) {
795
1
      return OTS_FAILURE();
796
1
    }
797
42
    if (stack_size != 13) {
798
1
      return OTS_FAILURE();
799
1
    }
800
574
    while (!argument_stack->empty())
801
533
      argument_stack->pop();
802
41
    return true;
803
804
38
  case ots::kHFlex1:
805
38
    if (!(cs_ctx.width_seen)) {
806
1
      return OTS_FAILURE();
807
1
    }
808
37
    if (stack_size != 9) {
809
2
      return OTS_FAILURE();
810
2
    }
811
350
    while (!argument_stack->empty())
812
315
      argument_stack->pop();
813
35
    return true;
814
815
42
  case ots::kFlex1:
816
42
    if (!(cs_ctx.width_seen)) {
817
1
      return OTS_FAILURE();
818
1
    }
819
41
    if (stack_size != 11) {
820
2
      return OTS_FAILURE();
821
2
    }
822
468
    while (!argument_stack->empty())
823
429
      argument_stack->pop();
824
39
    return true;
825
98.3M
  }
826
827
54
  return OTS_FAILURE_MSG("Undefined operator: %d (0x%x)", op, op);
828
98.3M
}
829
830
// Executes |char_string| and updates |argument_stack|.
831
//
832
// cff: parent OpenTypeCFF reference
833
// call_depth: The current call depth. Initial value is zero.
834
// global_subrs_index: Global subroutines.
835
// local_subrs_index: Local subroutines for the current glyph.
836
// cff_table: A whole CFF table which contains all global and local subroutines.
837
// char_string: A charstring we'll execute. |char_string| can be a main routine
838
//              in CharString INDEX, or a subroutine in GlobalSubr/LocalSubr.
839
// argument_stack: The stack which an operator in |char_string| operates.
840
// cs_ctx: a CharStringContext holding values to persist across subrs, etc.
841
//   endchar_seen: true is set if |char_string| contains 'endchar'.
842
//   width_seen: true is set if |char_string| contains 'width' byte (which
843
//               is 0 or 1 byte) or if cff2
844
//   num_stems: total number of hstems and vstems processed so far.
845
//   cff2: true if this is a CFF2 table
846
//   blend_seen: initially false; set to true if 'blend' operator encountered.
847
//   vsindex_seen: initially false; set to true if 'vsindex' encountered.
848
//   vsindex: initially = PrivateDICT's vsindex; may be changed by 'vsindex'
849
//            operator in CharString
850
bool ExecuteCharString(ots::OpenTypeCFF& cff,
851
                       size_t call_depth,
852
                       const ots::CFFIndex& global_subrs_index,
853
                       const ots::CFFIndex& local_subrs_index,
854
                       ots::Buffer *cff_table,
855
                       ots::Buffer *char_string,
856
                       std::stack<int32_t> *argument_stack,
857
48.8M
                       ots::CharStringContext& cs_ctx) {
858
48.8M
  if (call_depth > kMaxSubrNesting) {
859
38
    return OTS_FAILURE();
860
38
  }
861
48.8M
  cs_ctx.endchar_seen = false;
862
863
48.8M
  const size_t length = char_string->length();
864
153M
  while (char_string->offset() < length) {
865
153M
    int32_t operator_or_operand = 0;
866
153M
    bool is_operator = false;
867
153M
    if (!ReadNextNumberFromCharString(char_string,
868
153M
                                           &operator_or_operand,
869
153M
                                           &is_operator)) {
870
13
      return OTS_FAILURE();
871
13
    }
872
873
#ifdef DUMP_T2CHARSTRING
874
    /*
875
      You can dump all operators and operands (except mask bytes for hintmask
876
      and cntrmask) by the following code:
877
    */
878
879
      if (!is_operator) {
880
        std::fprintf(stderr, "%d ", operator_or_operand);
881
      } else {
882
        std::fprintf(stderr, "%s\n",
883
           CharStringOperatorToString(
884
               ots::CharStringOperator(operator_or_operand))
885
           );
886
      }
887
#endif
888
889
153M
    if (!is_operator) {
890
55.2M
      argument_stack->push(operator_or_operand);
891
55.2M
      if (ArgumentStackOverflows(argument_stack, cs_ctx.cff2)) {
892
8
        return OTS_FAILURE();
893
8
      }
894
55.2M
      continue;
895
55.2M
    }
896
897
98.3M
    if (++cs_ctx.num_ops > kMaxCharStringOps) {
898
0
      ots::Font* font = cff.GetFont();
899
0
      return OTS_FAILURE_MSG("charstring executes too many ops");
900
0
    }
901
902
    // An operator is found. Execute it.
903
98.3M
    if (!ExecuteCharStringOperator(cff,
904
98.3M
                                   operator_or_operand,
905
98.3M
                                   call_depth,
906
98.3M
                                   global_subrs_index,
907
98.3M
                                   local_subrs_index,
908
98.3M
                                   cff_table,
909
98.3M
                                   char_string,
910
98.3M
                                   argument_stack,
911
98.3M
                                   cs_ctx)) {
912
1.04k
      return OTS_FAILURE();
913
1.04k
    }
914
98.3M
    if (cs_ctx.endchar_seen) {
915
28.7k
      return true;
916
28.7k
    }
917
98.3M
    if (operator_or_operand == ots::kReturn) {
918
48.4M
      return true;
919
48.4M
    }
920
98.3M
  }
921
922
  // No endchar operator is found (CFF1 only)
923
348k
  if (cs_ctx.cff2)
924
348k
    return true;
925
34
  return OTS_FAILURE();
926
348k
}
927
928
// Selects a set of subroutines for |glyph_index| from |cff| and sets it on
929
// |out_local_subrs_to_use|. Returns true on success.
930
bool SelectLocalSubr(const ots::OpenTypeCFF& cff,
931
                     uint16_t glyph_index,  // 0-origin
932
125k
                     const ots::CFFIndex **out_local_subrs_to_use) {
933
125k
  bool cff2 = (cff.major == 2);
934
125k
  *out_local_subrs_to_use = NULL;
935
936
  // First, find local subrs from |local_subrs_per_font|.
937
125k
  if ((cff.fd_select.size() > 0) &&
938
521
      (!cff.local_subrs_per_font.empty())) {
939
    // Look up FDArray index for the glyph.
940
471
    const auto& iter = cff.fd_select.find(glyph_index);
941
471
    if (iter == cff.fd_select.end()) {
942
2
      return OTS_FAILURE();
943
2
    }
944
469
    const auto fd_index = iter->second;
945
469
    if (fd_index >= cff.local_subrs_per_font.size()) {
946
2
      return OTS_FAILURE();
947
2
    }
948
467
    *out_local_subrs_to_use = cff.local_subrs_per_font.at(fd_index);
949
125k
  } else if (cff.local_subrs) {
950
    // Second, try to use |local_subrs|. Most Latin fonts don't have FDSelect
951
    // entries. If The font has a local subrs index associated with the Top
952
    // DICT (not FDArrays), use it.
953
19.2k
    *out_local_subrs_to_use = cff.local_subrs;
954
106k
  } else if (cff2 && cff.local_subrs_per_font.size() == 1) {
955
105k
    *out_local_subrs_to_use = cff.local_subrs_per_font.at(0);
956
105k
  } else {
957
    // Just return NULL.
958
344
    *out_local_subrs_to_use = NULL;
959
344
  }
960
961
125k
  return true;
962
125k
}
963
964
}  // namespace
965
966
namespace ots {
967
968
bool ValidateCFFCharStrings(
969
    ots::OpenTypeCFF& cff,
970
    const CFFIndex& global_subrs_index,
971
609
    Buffer* cff_table) {
972
609
  const CFFIndex& char_strings_index = *(cff.charstrings_index);
973
609
  if (char_strings_index.offsets.size() == 0) {
974
8
    return OTS_FAILURE();  // no charstring.
975
8
  }
976
977
  // For each glyph, validate the corresponding charstring.
978
126k
  for (unsigned i = 1; i < char_strings_index.offsets.size(); ++i) {
979
    // Prepare a Buffer object, |char_string|, which contains the charstring
980
    // for the |i|-th glyph.
981
125k
    const size_t length =
982
125k
      char_strings_index.offsets[i] - char_strings_index.offsets[i - 1];
983
125k
    if (length > kMaxCharStringLength) {
984
0
      return OTS_FAILURE();
985
0
    }
986
125k
    const size_t offset = char_strings_index.offsets[i - 1];
987
125k
    cff_table->set_offset(offset);
988
125k
    if (!cff_table->Skip(length)) {
989
0
      return OTS_FAILURE();
990
0
    }
991
125k
    Buffer char_string(cff_table->buffer() + offset, length);
992
993
    // Get a local subrs for the glyph.
994
125k
    const unsigned glyph_index = i - 1;  // index in the map is 0-origin.
995
125k
    const CFFIndex *local_subrs_to_use = NULL;
996
125k
    if (!SelectLocalSubr(cff,
997
125k
                         glyph_index,
998
125k
                         &local_subrs_to_use)) {
999
4
      return OTS_FAILURE();
1000
4
    }
1001
    // If |local_subrs_to_use| is still NULL, use an empty one.
1002
125k
    CFFIndex default_empty_subrs;
1003
125k
    if (!local_subrs_to_use){
1004
344
      local_subrs_to_use = &default_empty_subrs;
1005
344
    }
1006
1007
    // Check a charstring for the |i|-th glyph.
1008
125k
    std::stack<int32_t> argument_stack;
1009
    // Context to store values that must persist across subrs, etc.
1010
125k
    CharStringContext cs_ctx;
1011
125k
    cs_ctx.cff2 = (cff.major == 2);
1012
    // CFF2 CharString has no value for width, so we start with true here to
1013
    // error out if width is found.
1014
125k
    cs_ctx.width_seen = cs_ctx.cff2;
1015
    // CFF2 CharStrings' default vsindex comes from the associated PrivateDICT
1016
125k
    if (cs_ctx.cff2) {
1017
105k
      const auto& iter = cff.fd_select.find(glyph_index);
1018
105k
      auto fd_index = 0;
1019
105k
      if (iter != cff.fd_select.end()) {
1020
164
        fd_index = iter->second;
1021
164
      }
1022
105k
      if (fd_index >= (int32_t)cff.vsindex_per_font.size()) {
1023
        // shouldn't get this far with a font in this condition, but just in case
1024
1
        return OTS_FAILURE();  // fd_index out-of-range
1025
1
      }
1026
105k
      cs_ctx.vsindex = cff.vsindex_per_font.at(fd_index);
1027
105k
    }
1028
1029
#ifdef DUMP_T2CHARSTRING
1030
    fprintf(stderr, "\n---- CharString %*d ----\n", 5, glyph_index);
1031
#endif
1032
1033
125k
    if (!ExecuteCharString(cff,
1034
125k
                           0 /* initial call_depth is zero */,
1035
125k
                           global_subrs_index, *local_subrs_to_use,
1036
125k
                           cff_table, &char_string, &argument_stack,
1037
125k
                           cs_ctx)) {
1038
422
      return OTS_FAILURE();
1039
422
    }
1040
125k
    if (!cs_ctx.cff2 && !cs_ctx.endchar_seen) {
1041
3
      return OTS_FAILURE();
1042
3
    }
1043
125k
  }
1044
171
  return true;
1045
601
}
1046
1047
}  // namespace ots
1048
1049
#undef TABLE_NAME