Line data Source code
1 : // Copyright (c) 2010 The Chromium 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_type2_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 kMaxArgumentStack = 48;
26 : const size_t kMaxNumberOfStemHints = 96;
27 : const size_t kMaxSubrNesting = 10;
28 :
29 : // |dummy_result| should be a huge positive integer so callsubr and callgsubr
30 : // will fail with the dummy value.
31 : const int32_t dummy_result = INT_MAX;
32 :
33 : bool ExecuteType2CharString(ots::Font *font,
34 : size_t call_depth,
35 : const ots::CFFIndex& global_subrs_index,
36 : const ots::CFFIndex& local_subrs_index,
37 : ots::Buffer *cff_table,
38 : ots::Buffer *char_string,
39 : std::stack<int32_t> *argument_stack,
40 : bool *out_found_endchar,
41 : bool *out_found_width,
42 : size_t *in_out_num_stems);
43 :
44 : #ifdef DUMP_T2CHARSTRING
45 : // Converts |op| to a string and returns it.
46 : const char *Type2CharStringOperatorToString(ots::Type2CharStringOperator op) {
47 : switch (op) {
48 : case ots::kHStem:
49 : return "HStem";
50 : case ots::kVStem:
51 : return "VStem";
52 : case ots::kVMoveTo:
53 : return "VMoveTo";
54 : case ots::kRLineTo:
55 : return "RLineTo";
56 : case ots::kHLineTo:
57 : return "HLineTo";
58 : case ots::kVLineTo:
59 : return "VLineTo";
60 : case ots::kRRCurveTo:
61 : return "RRCurveTo";
62 : case ots::kCallSubr:
63 : return "CallSubr";
64 : case ots::kReturn:
65 : return "Return";
66 : case ots::kEndChar:
67 : return "EndChar";
68 : case ots::kHStemHm:
69 : return "HStemHm";
70 : case ots::kHintMask:
71 : return "HintMask";
72 : case ots::kCntrMask:
73 : return "CntrMask";
74 : case ots::kRMoveTo:
75 : return "RMoveTo";
76 : case ots::kHMoveTo:
77 : return "HMoveTo";
78 : case ots::kVStemHm:
79 : return "VStemHm";
80 : case ots::kRCurveLine:
81 : return "RCurveLine";
82 : case ots::kRLineCurve:
83 : return "RLineCurve";
84 : case ots::kVVCurveTo:
85 : return "VVCurveTo";
86 : case ots::kHHCurveTo:
87 : return "HHCurveTo";
88 : case ots::kCallGSubr:
89 : return "CallGSubr";
90 : case ots::kVHCurveTo:
91 : return "VHCurveTo";
92 : case ots::kHVCurveTo:
93 : return "HVCurveTo";
94 : case ots::kDotSection:
95 : return "DotSection";
96 : case ots::kAnd:
97 : return "And";
98 : case ots::kOr:
99 : return "Or";
100 : case ots::kNot:
101 : return "Not";
102 : case ots::kAbs:
103 : return "Abs";
104 : case ots::kAdd:
105 : return "Add";
106 : case ots::kSub:
107 : return "Sub";
108 : case ots::kDiv:
109 : return "Div";
110 : case ots::kNeg:
111 : return "Neg";
112 : case ots::kEq:
113 : return "Eq";
114 : case ots::kDrop:
115 : return "Drop";
116 : case ots::kPut:
117 : return "Put";
118 : case ots::kGet:
119 : return "Get";
120 : case ots::kIfElse:
121 : return "IfElse";
122 : case ots::kRandom:
123 : return "Random";
124 : case ots::kMul:
125 : return "Mul";
126 : case ots::kSqrt:
127 : return "Sqrt";
128 : case ots::kDup:
129 : return "Dup";
130 : case ots::kExch:
131 : return "Exch";
132 : case ots::kIndex:
133 : return "Index";
134 : case ots::kRoll:
135 : return "Roll";
136 : case ots::kHFlex:
137 : return "HFlex";
138 : case ots::kFlex:
139 : return "Flex";
140 : case ots::kHFlex1:
141 : return "HFlex1";
142 : case ots::kFlex1:
143 : return "Flex1";
144 : }
145 :
146 : return "UNKNOWN";
147 : }
148 : #endif
149 :
150 : // Read one or more bytes from the |char_string| buffer and stores the number
151 : // read on |out_number|. If the number read is an operator (ex 'vstem'), sets
152 : // true on |out_is_operator|. Returns true if the function read a number.
153 0 : bool ReadNextNumberFromType2CharString(ots::Buffer *char_string,
154 : int32_t *out_number,
155 : bool *out_is_operator) {
156 0 : uint8_t v = 0;
157 0 : if (!char_string->ReadU8(&v)) {
158 0 : return OTS_FAILURE();
159 : }
160 0 : *out_is_operator = false;
161 :
162 : // The conversion algorithm is described in Adobe Technical Note #5177, page
163 : // 13, Table 1.
164 0 : if (v <= 11) {
165 0 : *out_number = v;
166 0 : *out_is_operator = true;
167 0 : } else if (v == 12) {
168 0 : uint16_t result = (v << 8);
169 0 : if (!char_string->ReadU8(&v)) {
170 0 : return OTS_FAILURE();
171 : }
172 0 : result += v;
173 0 : *out_number = result;
174 0 : *out_is_operator = true;
175 0 : } else if (v <= 27) {
176 : // Special handling for v==19 and v==20 are implemented in
177 : // ExecuteType2CharStringOperator().
178 0 : *out_number = v;
179 0 : *out_is_operator = true;
180 0 : } else if (v == 28) {
181 0 : if (!char_string->ReadU8(&v)) {
182 0 : return OTS_FAILURE();
183 : }
184 0 : uint16_t result = (v << 8);
185 0 : if (!char_string->ReadU8(&v)) {
186 0 : return OTS_FAILURE();
187 : }
188 0 : result += v;
189 0 : *out_number = result;
190 0 : } else if (v <= 31) {
191 0 : *out_number = v;
192 0 : *out_is_operator = true;
193 0 : } else if (v <= 246) {
194 0 : *out_number = static_cast<int32_t>(v) - 139;
195 0 : } else if (v <= 250) {
196 0 : uint8_t w = 0;
197 0 : if (!char_string->ReadU8(&w)) {
198 0 : return OTS_FAILURE();
199 : }
200 0 : *out_number = ((static_cast<int32_t>(v) - 247) * 256) +
201 0 : static_cast<int32_t>(w) + 108;
202 0 : } else if (v <= 254) {
203 0 : uint8_t w = 0;
204 0 : if (!char_string->ReadU8(&w)) {
205 0 : return OTS_FAILURE();
206 : }
207 0 : *out_number = -((static_cast<int32_t>(v) - 251) * 256) -
208 0 : static_cast<int32_t>(w) - 108;
209 0 : } else if (v == 255) {
210 : // TODO(yusukes): We should not skip the 4 bytes. Note that when v is 255,
211 : // we should treat the following 4-bytes as a 16.16 fixed-point number
212 : // rather than 32bit signed int.
213 0 : if (!char_string->Skip(4)) {
214 0 : return OTS_FAILURE();
215 : }
216 0 : *out_number = dummy_result;
217 : } else {
218 0 : return OTS_FAILURE();
219 : }
220 :
221 0 : return true;
222 : }
223 :
224 : // Executes |op| and updates |argument_stack|. Returns true if the execution
225 : // succeeds. If the |op| is kCallSubr or kCallGSubr, the function recursively
226 : // calls ExecuteType2CharString() function. The arguments other than |op| and
227 : // |argument_stack| are passed for that reason.
228 0 : bool ExecuteType2CharStringOperator(ots::Font *font,
229 : int32_t op,
230 : size_t call_depth,
231 : const ots::CFFIndex& global_subrs_index,
232 : const ots::CFFIndex& local_subrs_index,
233 : ots::Buffer *cff_table,
234 : ots::Buffer *char_string,
235 : std::stack<int32_t> *argument_stack,
236 : bool *out_found_endchar,
237 : bool *in_out_found_width,
238 : size_t *in_out_num_stems) {
239 0 : const size_t stack_size = argument_stack->size();
240 :
241 0 : switch (op) {
242 : case ots::kCallSubr:
243 : case ots::kCallGSubr: {
244 : const ots::CFFIndex& subrs_index =
245 0 : (op == ots::kCallSubr ? local_subrs_index : global_subrs_index);
246 :
247 0 : if (stack_size < 1) {
248 0 : return OTS_FAILURE();
249 : }
250 0 : int32_t subr_number = argument_stack->top();
251 0 : argument_stack->pop();
252 0 : if (subr_number == dummy_result) {
253 : // For safety, we allow subr calls only with immediate subr numbers for
254 : // now. For example, we allow "123 callgsubr", but does not allow "100 12
255 : // add callgsubr". Please note that arithmetic and conditional operators
256 : // always push the |dummy_result| in this implementation.
257 0 : return OTS_FAILURE();
258 : }
259 :
260 : // See Adobe Technical Note #5176 (CFF), "16. Local/GlobalSubrs INDEXes."
261 0 : int32_t bias = 32768;
262 0 : if (subrs_index.count < 1240) {
263 0 : bias = 107;
264 0 : } else if (subrs_index.count < 33900) {
265 0 : bias = 1131;
266 : }
267 0 : subr_number += bias;
268 :
269 : // Sanity checks of |subr_number|.
270 0 : if (subr_number < 0) {
271 0 : return OTS_FAILURE();
272 : }
273 0 : if (subr_number >= kMaxSubrsCount) {
274 0 : return OTS_FAILURE();
275 : }
276 0 : if (subrs_index.offsets.size() <= static_cast<size_t>(subr_number + 1)) {
277 0 : return OTS_FAILURE(); // The number is out-of-bounds.
278 : }
279 :
280 : // Prepare ots::Buffer where we're going to jump.
281 : const size_t length =
282 0 : subrs_index.offsets[subr_number + 1] - subrs_index.offsets[subr_number];
283 0 : if (length > kMaxCharStringLength) {
284 0 : return OTS_FAILURE();
285 : }
286 0 : const size_t offset = subrs_index.offsets[subr_number];
287 0 : cff_table->set_offset(offset);
288 0 : if (!cff_table->Skip(length)) {
289 0 : return OTS_FAILURE();
290 : }
291 0 : ots::Buffer char_string_to_jump(cff_table->buffer() + offset, length);
292 :
293 0 : return ExecuteType2CharString(font,
294 : call_depth + 1,
295 : global_subrs_index,
296 : local_subrs_index,
297 : cff_table,
298 : &char_string_to_jump,
299 : argument_stack,
300 : out_found_endchar,
301 : in_out_found_width,
302 0 : in_out_num_stems);
303 : }
304 :
305 : case ots::kReturn:
306 0 : return true;
307 :
308 : case ots::kEndChar:
309 0 : *out_found_endchar = true;
310 0 : *in_out_found_width = true; // just in case.
311 0 : return true;
312 :
313 : case ots::kHStem:
314 : case ots::kVStem:
315 : case ots::kHStemHm:
316 : case ots::kVStemHm: {
317 0 : bool successful = false;
318 0 : if (stack_size < 2) {
319 0 : return OTS_FAILURE();
320 : }
321 0 : if ((stack_size % 2) == 0) {
322 0 : successful = true;
323 0 : } else if ((!(*in_out_found_width)) && (((stack_size - 1) % 2) == 0)) {
324 : // The -1 is for "width" argument. For details, see Adobe Technical Note
325 : // #5177, page 16, note 4.
326 0 : successful = true;
327 : }
328 0 : (*in_out_num_stems) += (stack_size / 2);
329 0 : if ((*in_out_num_stems) > kMaxNumberOfStemHints) {
330 0 : return OTS_FAILURE();
331 : }
332 0 : while (!argument_stack->empty())
333 0 : argument_stack->pop();
334 0 : *in_out_found_width = true; // always set true since "w" might be 0 byte.
335 0 : return successful ? true : OTS_FAILURE();
336 : }
337 :
338 : case ots::kRMoveTo: {
339 0 : bool successful = false;
340 0 : if (stack_size == 2) {
341 0 : successful = true;
342 0 : } else if ((!(*in_out_found_width)) && (stack_size - 1 == 2)) {
343 0 : successful = true;
344 : }
345 0 : while (!argument_stack->empty())
346 0 : argument_stack->pop();
347 0 : *in_out_found_width = true;
348 0 : return successful ? true : OTS_FAILURE();
349 : }
350 :
351 : case ots::kVMoveTo:
352 : case ots::kHMoveTo: {
353 0 : bool successful = false;
354 0 : if (stack_size == 1) {
355 0 : successful = true;
356 0 : } else if ((!(*in_out_found_width)) && (stack_size - 1 == 1)) {
357 0 : successful = true;
358 : }
359 0 : while (!argument_stack->empty())
360 0 : argument_stack->pop();
361 0 : *in_out_found_width = true;
362 0 : return successful ? true : OTS_FAILURE();
363 : }
364 :
365 : case ots::kHintMask:
366 : case ots::kCntrMask: {
367 0 : bool successful = false;
368 0 : if (stack_size == 0) {
369 0 : successful = true;
370 0 : } else if ((!(*in_out_found_width)) && (stack_size == 1)) {
371 : // A number for "width" is found.
372 0 : successful = true;
373 0 : } else if ((!(*in_out_found_width)) || // in this case, any sizes are ok.
374 0 : ((stack_size % 2) == 0)) {
375 : // The numbers are vstem definition.
376 : // See Adobe Technical Note #5177, page 24, hintmask.
377 0 : (*in_out_num_stems) += (stack_size / 2);
378 0 : if ((*in_out_num_stems) > kMaxNumberOfStemHints) {
379 0 : return OTS_FAILURE();
380 : }
381 0 : successful = true;
382 : }
383 0 : if (!successful) {
384 0 : return OTS_FAILURE();
385 : }
386 :
387 0 : if ((*in_out_num_stems) == 0) {
388 0 : return OTS_FAILURE();
389 : }
390 0 : const size_t mask_bytes = (*in_out_num_stems + 7) / 8;
391 0 : if (!char_string->Skip(mask_bytes)) {
392 0 : return OTS_FAILURE();
393 : }
394 0 : while (!argument_stack->empty())
395 0 : argument_stack->pop();
396 0 : *in_out_found_width = true;
397 0 : return true;
398 : }
399 :
400 : case ots::kRLineTo:
401 0 : if (!(*in_out_found_width)) {
402 : // The first stack-clearing operator should be one of hstem, hstemhm,
403 : // vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto, rmoveto, or
404 : // endchar. For details, see Adobe Technical Note #5177, page 16, note 4.
405 0 : return OTS_FAILURE();
406 : }
407 0 : if (stack_size < 2) {
408 0 : return OTS_FAILURE();
409 : }
410 0 : if ((stack_size % 2) != 0) {
411 0 : return OTS_FAILURE();
412 : }
413 0 : while (!argument_stack->empty())
414 0 : argument_stack->pop();
415 0 : return true;
416 :
417 : case ots::kHLineTo:
418 : case ots::kVLineTo:
419 0 : if (!(*in_out_found_width)) {
420 0 : return OTS_FAILURE();
421 : }
422 0 : if (stack_size < 1) {
423 0 : return OTS_FAILURE();
424 : }
425 0 : while (!argument_stack->empty())
426 0 : argument_stack->pop();
427 0 : return true;
428 :
429 : case ots::kRRCurveTo:
430 0 : if (!(*in_out_found_width)) {
431 0 : return OTS_FAILURE();
432 : }
433 0 : if (stack_size < 6) {
434 0 : return OTS_FAILURE();
435 : }
436 0 : if ((stack_size % 6) != 0) {
437 0 : return OTS_FAILURE();
438 : }
439 0 : while (!argument_stack->empty())
440 0 : argument_stack->pop();
441 0 : return true;
442 :
443 : case ots::kRCurveLine:
444 0 : if (!(*in_out_found_width)) {
445 0 : return OTS_FAILURE();
446 : }
447 0 : if (stack_size < 8) {
448 0 : return OTS_FAILURE();
449 : }
450 0 : if (((stack_size - 2) % 6) != 0) {
451 0 : return OTS_FAILURE();
452 : }
453 0 : while (!argument_stack->empty())
454 0 : argument_stack->pop();
455 0 : return true;
456 :
457 : case ots::kRLineCurve:
458 0 : if (!(*in_out_found_width)) {
459 0 : return OTS_FAILURE();
460 : }
461 0 : if (stack_size < 8) {
462 0 : return OTS_FAILURE();
463 : }
464 0 : if (((stack_size - 6) % 2) != 0) {
465 0 : return OTS_FAILURE();
466 : }
467 0 : while (!argument_stack->empty())
468 0 : argument_stack->pop();
469 0 : return true;
470 :
471 : case ots::kVVCurveTo:
472 0 : if (!(*in_out_found_width)) {
473 0 : return OTS_FAILURE();
474 : }
475 0 : if (stack_size < 4) {
476 0 : return OTS_FAILURE();
477 : }
478 0 : if (((stack_size % 4) != 0) &&
479 0 : (((stack_size - 1) % 4) != 0)) {
480 0 : return OTS_FAILURE();
481 : }
482 0 : while (!argument_stack->empty())
483 0 : argument_stack->pop();
484 0 : return true;
485 :
486 : case ots::kHHCurveTo: {
487 0 : bool successful = false;
488 0 : if (!(*in_out_found_width)) {
489 0 : return OTS_FAILURE();
490 : }
491 0 : if (stack_size < 4) {
492 0 : return OTS_FAILURE();
493 : }
494 0 : if ((stack_size % 4) == 0) {
495 : // {dxa dxb dyb dxc}+
496 0 : successful = true;
497 0 : } else if (((stack_size - 1) % 4) == 0) {
498 : // dy1? {dxa dxb dyb dxc}+
499 0 : successful = true;
500 : }
501 0 : while (!argument_stack->empty())
502 0 : argument_stack->pop();
503 0 : return successful ? true : OTS_FAILURE();
504 : }
505 :
506 : case ots::kVHCurveTo:
507 : case ots::kHVCurveTo: {
508 0 : bool successful = false;
509 0 : if (!(*in_out_found_width)) {
510 0 : return OTS_FAILURE();
511 : }
512 0 : if (stack_size < 4) {
513 0 : return OTS_FAILURE();
514 : }
515 0 : if (((stack_size - 4) % 8) == 0) {
516 : // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}*
517 0 : successful = true;
518 0 : } else if ((stack_size >= 5) &&
519 0 : ((stack_size - 5) % 8) == 0) {
520 : // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf
521 0 : successful = true;
522 0 : } else if ((stack_size >= 8) &&
523 0 : ((stack_size - 8) % 8) == 0) {
524 : // {dxa dxb dyb dyc dyd dxe dye dxf}+
525 0 : successful = true;
526 0 : } else if ((stack_size >= 9) &&
527 0 : ((stack_size - 9) % 8) == 0) {
528 : // {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf?
529 0 : successful = true;
530 : }
531 0 : while (!argument_stack->empty())
532 0 : argument_stack->pop();
533 0 : return successful ? true : OTS_FAILURE();
534 : }
535 :
536 : case ots::kDotSection:
537 : // Deprecated operator but harmless, we probably should drop it some how.
538 0 : if (stack_size != 0) {
539 0 : return OTS_FAILURE();
540 : }
541 0 : return true;
542 :
543 : case ots::kAnd:
544 : case ots::kOr:
545 : case ots::kEq:
546 : case ots::kAdd:
547 : case ots::kSub:
548 0 : if (stack_size < 2) {
549 0 : return OTS_FAILURE();
550 : }
551 0 : argument_stack->pop();
552 0 : argument_stack->pop();
553 0 : argument_stack->push(dummy_result);
554 : // TODO(yusukes): Implement this. We should push a real value for all
555 : // arithmetic and conditional operations.
556 0 : return true;
557 :
558 : case ots::kNot:
559 : case ots::kAbs:
560 : case ots::kNeg:
561 0 : if (stack_size < 1) {
562 0 : return OTS_FAILURE();
563 : }
564 0 : argument_stack->pop();
565 0 : argument_stack->push(dummy_result);
566 : // TODO(yusukes): Implement this. We should push a real value for all
567 : // arithmetic and conditional operations.
568 0 : return true;
569 :
570 : case ots::kDiv:
571 : // TODO(yusukes): Should detect div-by-zero errors.
572 0 : if (stack_size < 2) {
573 0 : return OTS_FAILURE();
574 : }
575 0 : argument_stack->pop();
576 0 : argument_stack->pop();
577 0 : argument_stack->push(dummy_result);
578 : // TODO(yusukes): Implement this. We should push a real value for all
579 : // arithmetic and conditional operations.
580 0 : return true;
581 :
582 : case ots::kDrop:
583 0 : if (stack_size < 1) {
584 0 : return OTS_FAILURE();
585 : }
586 0 : argument_stack->pop();
587 0 : return true;
588 :
589 : case ots::kPut:
590 : case ots::kGet:
591 : case ots::kIndex:
592 : // For now, just call OTS_FAILURE since there is no way to check whether the
593 : // index argument, |i|, is out-of-bounds or not. Fortunately, no OpenType
594 : // fonts I have (except malicious ones!) use the operators.
595 : // TODO(yusukes): Implement them in a secure way.
596 0 : return OTS_FAILURE();
597 :
598 : case ots::kRoll:
599 : // Likewise, just call OTS_FAILURE for kRoll since there is no way to check
600 : // whether |N| is smaller than the current stack depth or not.
601 : // TODO(yusukes): Implement them in a secure way.
602 0 : return OTS_FAILURE();
603 :
604 : case ots::kRandom:
605 : // For now, we don't handle the 'random' operator since the operator makes
606 : // it hard to analyze hinting code statically.
607 0 : return OTS_FAILURE();
608 :
609 : case ots::kIfElse:
610 0 : if (stack_size < 4) {
611 0 : return OTS_FAILURE();
612 : }
613 0 : argument_stack->pop();
614 0 : argument_stack->pop();
615 0 : argument_stack->pop();
616 0 : argument_stack->pop();
617 0 : argument_stack->push(dummy_result);
618 : // TODO(yusukes): Implement this. We should push a real value for all
619 : // arithmetic and conditional operations.
620 0 : return true;
621 :
622 : case ots::kMul:
623 : // TODO(yusukes): Should detect overflows.
624 0 : if (stack_size < 2) {
625 0 : return OTS_FAILURE();
626 : }
627 0 : argument_stack->pop();
628 0 : argument_stack->pop();
629 0 : argument_stack->push(dummy_result);
630 : // TODO(yusukes): Implement this. We should push a real value for all
631 : // arithmetic and conditional operations.
632 0 : return true;
633 :
634 : case ots::kSqrt:
635 : // TODO(yusukes): Should check if the argument is negative.
636 0 : if (stack_size < 1) {
637 0 : return OTS_FAILURE();
638 : }
639 0 : argument_stack->pop();
640 0 : argument_stack->push(dummy_result);
641 : // TODO(yusukes): Implement this. We should push a real value for all
642 : // arithmetic and conditional operations.
643 0 : return true;
644 :
645 : case ots::kDup:
646 0 : if (stack_size < 1) {
647 0 : return OTS_FAILURE();
648 : }
649 0 : argument_stack->pop();
650 0 : argument_stack->push(dummy_result);
651 0 : argument_stack->push(dummy_result);
652 0 : if (argument_stack->size() > kMaxArgumentStack) {
653 0 : return OTS_FAILURE();
654 : }
655 : // TODO(yusukes): Implement this. We should push a real value for all
656 : // arithmetic and conditional operations.
657 0 : return true;
658 :
659 : case ots::kExch:
660 0 : if (stack_size < 2) {
661 0 : return OTS_FAILURE();
662 : }
663 0 : argument_stack->pop();
664 0 : argument_stack->pop();
665 0 : argument_stack->push(dummy_result);
666 0 : argument_stack->push(dummy_result);
667 : // TODO(yusukes): Implement this. We should push a real value for all
668 : // arithmetic and conditional operations.
669 0 : return true;
670 :
671 : case ots::kHFlex:
672 0 : if (!(*in_out_found_width)) {
673 0 : return OTS_FAILURE();
674 : }
675 0 : if (stack_size != 7) {
676 0 : return OTS_FAILURE();
677 : }
678 0 : while (!argument_stack->empty())
679 0 : argument_stack->pop();
680 0 : return true;
681 :
682 : case ots::kFlex:
683 0 : if (!(*in_out_found_width)) {
684 0 : return OTS_FAILURE();
685 : }
686 0 : if (stack_size != 13) {
687 0 : return OTS_FAILURE();
688 : }
689 0 : while (!argument_stack->empty())
690 0 : argument_stack->pop();
691 0 : return true;
692 :
693 : case ots::kHFlex1:
694 0 : if (!(*in_out_found_width)) {
695 0 : return OTS_FAILURE();
696 : }
697 0 : if (stack_size != 9) {
698 0 : return OTS_FAILURE();
699 : }
700 0 : while (!argument_stack->empty())
701 0 : argument_stack->pop();
702 0 : return true;
703 :
704 : case ots::kFlex1:
705 0 : if (!(*in_out_found_width)) {
706 0 : return OTS_FAILURE();
707 : }
708 0 : if (stack_size != 11) {
709 0 : return OTS_FAILURE();
710 : }
711 0 : while (!argument_stack->empty())
712 0 : argument_stack->pop();
713 0 : return true;
714 : }
715 :
716 0 : return OTS_FAILURE_MSG("Undefined operator: %d (0x%x)", op, op);
717 : }
718 :
719 : // Executes |char_string| and updates |argument_stack|.
720 : //
721 : // call_depth: The current call depth. Initial value is zero.
722 : // global_subrs_index: Global subroutines.
723 : // local_subrs_index: Local subroutines for the current glyph.
724 : // cff_table: A whole CFF table which contains all global and local subroutines.
725 : // char_string: A charstring we'll execute. |char_string| can be a main routine
726 : // in CharString INDEX, or a subroutine in GlobalSubr/LocalSubr.
727 : // argument_stack: The stack which an operator in |char_string| operates.
728 : // out_found_endchar: true is set if |char_string| contains 'endchar'.
729 : // in_out_found_width: true is set if |char_string| contains 'width' byte (which
730 : // is 0 or 1 byte.)
731 : // in_out_num_stems: total number of hstems and vstems processed so far.
732 0 : bool ExecuteType2CharString(ots::Font *font,
733 : size_t call_depth,
734 : const ots::CFFIndex& global_subrs_index,
735 : const ots::CFFIndex& local_subrs_index,
736 : ots::Buffer *cff_table,
737 : ots::Buffer *char_string,
738 : std::stack<int32_t> *argument_stack,
739 : bool *out_found_endchar,
740 : bool *in_out_found_width,
741 : size_t *in_out_num_stems) {
742 0 : if (call_depth > kMaxSubrNesting) {
743 0 : return OTS_FAILURE();
744 : }
745 0 : *out_found_endchar = false;
746 :
747 0 : const size_t length = char_string->length();
748 0 : while (char_string->offset() < length) {
749 0 : int32_t operator_or_operand = 0;
750 0 : bool is_operator = false;
751 0 : if (!ReadNextNumberFromType2CharString(char_string,
752 : &operator_or_operand,
753 : &is_operator)) {
754 0 : return OTS_FAILURE();
755 : }
756 :
757 : #ifdef DUMP_T2CHARSTRING
758 : /*
759 : You can dump all operators and operands (except mask bytes for hintmask
760 : and cntrmask) by the following code:
761 : */
762 :
763 : if (!is_operator) {
764 : std::fprintf(stderr, "#%d# ", operator_or_operand);
765 : } else {
766 : std::fprintf(stderr, "#%s#\n",
767 : Type2CharStringOperatorToString(
768 : ots::Type2CharStringOperator(operator_or_operand))
769 : );
770 : }
771 : #endif
772 :
773 0 : if (!is_operator) {
774 0 : argument_stack->push(operator_or_operand);
775 0 : if (argument_stack->size() > kMaxArgumentStack) {
776 0 : return OTS_FAILURE();
777 : }
778 0 : continue;
779 : }
780 :
781 : // An operator is found. Execute it.
782 0 : if (!ExecuteType2CharStringOperator(font,
783 : operator_or_operand,
784 : call_depth,
785 : global_subrs_index,
786 : local_subrs_index,
787 : cff_table,
788 : char_string,
789 : argument_stack,
790 : out_found_endchar,
791 : in_out_found_width,
792 : in_out_num_stems)) {
793 0 : return OTS_FAILURE();
794 : }
795 0 : if (*out_found_endchar) {
796 0 : return true;
797 : }
798 0 : if (operator_or_operand == ots::kReturn) {
799 0 : return true;
800 : }
801 : }
802 :
803 : // No endchar operator is found.
804 0 : return OTS_FAILURE();
805 : }
806 :
807 : // Selects a set of subroutings for |glyph_index| from |cff| and sets it on
808 : // |out_local_subrs_to_use|. Returns true on success.
809 0 : bool SelectLocalSubr(const std::map<uint16_t, uint8_t> &fd_select,
810 : const std::vector<ots::CFFIndex *> &local_subrs_per_font,
811 : const ots::CFFIndex *local_subrs,
812 : uint16_t glyph_index, // 0-origin
813 : const ots::CFFIndex **out_local_subrs_to_use) {
814 0 : *out_local_subrs_to_use = NULL;
815 :
816 : // First, find local subrs from |local_subrs_per_font|.
817 0 : if ((fd_select.size() > 0) &&
818 0 : (!local_subrs_per_font.empty())) {
819 : // Look up FDArray index for the glyph.
820 : std::map<uint16_t, uint8_t>::const_iterator iter =
821 0 : fd_select.find(glyph_index);
822 0 : if (iter == fd_select.end()) {
823 0 : return OTS_FAILURE();
824 : }
825 0 : const uint8_t fd_index = iter->second;
826 0 : if (fd_index >= local_subrs_per_font.size()) {
827 0 : return OTS_FAILURE();
828 : }
829 0 : *out_local_subrs_to_use = local_subrs_per_font.at(fd_index);
830 0 : } else if (local_subrs) {
831 : // Second, try to use |local_subrs|. Most Latin fonts don't have FDSelect
832 : // entries. If The font has a local subrs index associated with the Top
833 : // DICT (not FDArrays), use it.
834 0 : *out_local_subrs_to_use = local_subrs;
835 : } else {
836 : // Just return NULL.
837 0 : *out_local_subrs_to_use = NULL;
838 : }
839 :
840 0 : return true;
841 : }
842 :
843 : } // namespace
844 :
845 : namespace ots {
846 :
847 0 : bool ValidateType2CharStringIndex(
848 : ots::Font *font,
849 : const CFFIndex& char_strings_index,
850 : const CFFIndex& global_subrs_index,
851 : const std::map<uint16_t, uint8_t> &fd_select,
852 : const std::vector<CFFIndex *> &local_subrs_per_font,
853 : const CFFIndex *local_subrs,
854 : Buffer* cff_table) {
855 0 : if (char_strings_index.offsets.size() == 0) {
856 0 : return OTS_FAILURE(); // no charstring.
857 : }
858 :
859 : // For each glyph, validate the corresponding charstring.
860 0 : for (unsigned i = 1; i < char_strings_index.offsets.size(); ++i) {
861 : // Prepare a Buffer object, |char_string|, which contains the charstring
862 : // for the |i|-th glyph.
863 : const size_t length =
864 0 : char_strings_index.offsets[i] - char_strings_index.offsets[i - 1];
865 0 : if (length > kMaxCharStringLength) {
866 0 : return OTS_FAILURE();
867 : }
868 0 : const size_t offset = char_strings_index.offsets[i - 1];
869 0 : cff_table->set_offset(offset);
870 0 : if (!cff_table->Skip(length)) {
871 0 : return OTS_FAILURE();
872 : }
873 0 : Buffer char_string(cff_table->buffer() + offset, length);
874 :
875 : // Get a local subrs for the glyph.
876 0 : const unsigned glyph_index = i - 1; // index in the map is 0-origin.
877 0 : const CFFIndex *local_subrs_to_use = NULL;
878 0 : if (!SelectLocalSubr(fd_select,
879 : local_subrs_per_font,
880 : local_subrs,
881 : glyph_index,
882 : &local_subrs_to_use)) {
883 0 : return OTS_FAILURE();
884 : }
885 : // If |local_subrs_to_use| is still NULL, use an empty one.
886 0 : CFFIndex default_empty_subrs;
887 0 : if (!local_subrs_to_use){
888 0 : local_subrs_to_use = &default_empty_subrs;
889 : }
890 :
891 : // Check a charstring for the |i|-th glyph.
892 0 : std::stack<int32_t> argument_stack;
893 0 : bool found_endchar = false;
894 0 : bool found_width = false;
895 0 : size_t num_stems = 0;
896 0 : if (!ExecuteType2CharString(font,
897 : 0 /* initial call_depth is zero */,
898 : global_subrs_index, *local_subrs_to_use,
899 : cff_table, &char_string, &argument_stack,
900 : &found_endchar, &found_width, &num_stems)) {
901 0 : return OTS_FAILURE();
902 : }
903 0 : if (!found_endchar) {
904 0 : return OTS_FAILURE();
905 : }
906 : }
907 0 : return true;
908 : }
909 :
910 : } // namespace ots
911 :
912 : #undef TABLE_NAME
|