Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Side by Side Diff: src/cff_type2_charstring.cc

Issue 3027049: Addressed Tavis's comments in http://codereview.chromium.org/3023041/.... (Closed) Base URL: http://ots.googlecode.com/svn/trunk/
Patch Set: '' Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/cff_type2_charstring.h ('k') | test/SConstruct » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 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 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 // A parser for the Type 2 Charstring Format. 5 // A parser for the Type 2 Charstring Format.
6 // http://www.adobe.com/devnet/font/pdfs/5177.Type2.pdf 6 // http://www.adobe.com/devnet/font/pdfs/5177.Type2.pdf
7 7
8 #include "cff_type2_charstring.h" 8 #include "cff_type2_charstring.h"
9 9
10 #include <climits>
10 #include <cstdio> 11 #include <cstdio>
11 #include <cstring> 12 #include <cstring>
12 #include <limits>
13 #include <stack> 13 #include <stack>
14 #include <string> 14 #include <string>
15 #include <utility> 15 #include <utility>
16 16
17 namespace { 17 namespace {
18 18
19 // The list of Operators. See Appendix. A in Adobe Technical Note #5177.
20 enum Type2CharStringOperator {
21 kHStem = 1,
22 kVStem = 3,
23 kVMoveTo = 4,
24 kRLineTo = 5,
25 kHLineTo = 6,
26 kVLineTo = 7,
27 kRRCurveTo = 8,
28 kCallSubr = 10,
29 kReturn = 11,
30 kEndChar = 14,
31 kHStemHm = 18,
32 kHintMask = 19,
33 kCntrMask = 20,
34 kRMoveTo = 21,
35 kHMoveTo = 22,
36 kVStemHm = 23,
37 kRCurveLine = 24,
38 kRLineCurve = 25,
39 kVVCurveTo = 26,
40 kHHCurveTo = 27,
41 kCallGSubr = 29,
42 kVHCurveTo = 30,
43 kHVCurveTo = 31,
44 kAnd = (12 << 8) + 3,
45 kOr = (12 << 8) + 4,
46 kNot = (12 << 8) + 5,
47 kAbs = (12 << 8) + 9,
48 kAdd = (12 << 8) + 10,
49 kSub = (12 << 8) + 11,
50 kDiv = (12 << 8) + 12,
51 kNeg = (12 << 8) + 14,
52 kEq = (12 << 8) + 15,
53 kDrop = (12 << 8) + 18,
54 kPut = (12 << 8) + 20,
55 kGet = (12 << 8) + 21,
56 kIfElse = (12 << 8) + 22,
57 kRandom = (12 << 8) + 23,
58 kMul = (12 << 8) + 24,
59 kSqrt = (12 << 8) + 26,
60 kDup = (12 << 8) + 27,
61 kExch = (12 << 8) + 28,
62 kIndex = (12 << 8) + 29,
63 kRoll = (12 << 8) + 30,
64 kHFlex = (12 << 8) + 34,
65 kFlex = (12 << 8) + 35,
66 kHFlex1 = (12 << 8) + 36,
67 kFlex1 = (12 << 8) + 37,
68 };
69
70 // Type 2 Charstring Implementation Limits. See Appendix. B in Adobe Technical 19 // Type 2 Charstring Implementation Limits. See Appendix. B in Adobe Technical
71 // Note #5177. 20 // Note #5177.
21 const int32_t kMaxSubrsCount = 65536;
72 const size_t kMaxCharStringLength = 65535; 22 const size_t kMaxCharStringLength = 65535;
73 const size_t kMaxArgumentStack = 48; 23 const size_t kMaxArgumentStack = 48;
74 const size_t kMaxNumberOfStemHints = 96; 24 const size_t kMaxNumberOfStemHints = 96;
75 const size_t kMaxSubrNesting = 10; 25 const size_t kMaxSubrNesting = 10;
76 26
27 // |dummy_result| should be a huge positive integer so callsubr and callgsubr
28 // will fail with the dummy value.
29 const int32_t dummy_result = INT_MAX;
30
77 bool ExecuteType2CharString(size_t call_depth, 31 bool ExecuteType2CharString(size_t call_depth,
78 const ots::CFFIndex& global_subrs_index, 32 const ots::CFFIndex& global_subrs_index,
79 const ots::CFFIndex& local_subrs_index, 33 const ots::CFFIndex& local_subrs_index,
80 ots::Buffer *cff_table, 34 ots::Buffer *cff_table,
81 ots::Buffer *char_string, 35 ots::Buffer *char_string,
82 std::stack<int32_t> *argument_stack, 36 std::stack<int32_t> *argument_stack,
83 bool *out_found_endchar, 37 bool *out_found_endchar,
84 bool *out_found_width, 38 bool *out_found_width,
85 size_t *in_out_num_stems); 39 size_t *in_out_num_stems);
86 40
87 // Converts |op| to a string and returns it. 41 // Converts |op| to a string and returns it.
88 const char *Type2CharStringOperatorToString(Type2CharStringOperator op) { 42 const char *Type2CharStringOperatorToString(ots::Type2CharStringOperator op) {
89 switch (op) { 43 switch (op) {
90 case kHStem: 44 case ots::kHStem:
91 return "HStem"; 45 return "HStem";
92 case kVStem: 46 case ots::kVStem:
93 return "VStem"; 47 return "VStem";
94 case kVMoveTo: 48 case ots::kVMoveTo:
95 return "VMoveTo"; 49 return "VMoveTo";
96 case kRLineTo: 50 case ots::kRLineTo:
97 return "RLineTo"; 51 return "RLineTo";
98 case kHLineTo: 52 case ots::kHLineTo:
99 return "HLineTo"; 53 return "HLineTo";
100 case kVLineTo: 54 case ots::kVLineTo:
101 return "VLineTo"; 55 return "VLineTo";
102 case kRRCurveTo: 56 case ots::kRRCurveTo:
103 return "RRCurveTo"; 57 return "RRCurveTo";
104 case kCallSubr: 58 case ots::kCallSubr:
105 return "CallSubr"; 59 return "CallSubr";
106 case kReturn: 60 case ots::kReturn:
107 return "Return"; 61 return "Return";
108 case kEndChar: 62 case ots::kEndChar:
109 return "EndChar"; 63 return "EndChar";
110 case kHStemHm: 64 case ots::kHStemHm:
111 return "HStemHm"; 65 return "HStemHm";
112 case kHintMask: 66 case ots::kHintMask:
113 return "HintMask"; 67 return "HintMask";
114 case kCntrMask: 68 case ots::kCntrMask:
115 return "CntrMask"; 69 return "CntrMask";
116 case kRMoveTo: 70 case ots::kRMoveTo:
117 return "RMoveTo"; 71 return "RMoveTo";
118 case kHMoveTo: 72 case ots::kHMoveTo:
119 return "HMoveTo"; 73 return "HMoveTo";
120 case kVStemHm: 74 case ots::kVStemHm:
121 return "VStemHm"; 75 return "VStemHm";
122 case kRCurveLine: 76 case ots::kRCurveLine:
123 return "RCurveLine"; 77 return "RCurveLine";
124 case kRLineCurve: 78 case ots::kRLineCurve:
125 return "RLineCurve"; 79 return "RLineCurve";
126 case kVVCurveTo: 80 case ots::kVVCurveTo:
127 return "VVCurveTo"; 81 return "VVCurveTo";
128 case kHHCurveTo: 82 case ots::kHHCurveTo:
129 return "HHCurveTo"; 83 return "HHCurveTo";
130 case kCallGSubr: 84 case ots::kCallGSubr:
131 return "CallGSubr"; 85 return "CallGSubr";
132 case kVHCurveTo: 86 case ots::kVHCurveTo:
133 return "VHCurveTo"; 87 return "VHCurveTo";
134 case kHVCurveTo: 88 case ots::kHVCurveTo:
135 return "HVCurveTo"; 89 return "HVCurveTo";
136 case kAnd: 90 case ots::kAnd:
137 return "And"; 91 return "And";
138 case kOr: 92 case ots::kOr:
139 return "Or"; 93 return "Or";
140 case kNot: 94 case ots::kNot:
141 return "Not"; 95 return "Not";
142 case kAbs: 96 case ots::kAbs:
143 return "Abs"; 97 return "Abs";
144 case kAdd: 98 case ots::kAdd:
145 return "Add"; 99 return "Add";
146 case kSub: 100 case ots::kSub:
147 return "Sub"; 101 return "Sub";
148 case kDiv: 102 case ots::kDiv:
149 return "Div"; 103 return "Div";
150 case kNeg: 104 case ots::kNeg:
151 return "Neg"; 105 return "Neg";
152 case kEq: 106 case ots::kEq:
153 return "Eq"; 107 return "Eq";
154 case kDrop: 108 case ots::kDrop:
155 return "Drop"; 109 return "Drop";
156 case kPut: 110 case ots::kPut:
157 return "Put"; 111 return "Put";
158 case kGet: 112 case ots::kGet:
159 return "Get"; 113 return "Get";
160 case kIfElse: 114 case ots::kIfElse:
161 return "IfElse"; 115 return "IfElse";
162 case kRandom: 116 case ots::kRandom:
163 return "Random"; 117 return "Random";
164 case kMul: 118 case ots::kMul:
165 return "Mul"; 119 return "Mul";
166 case kSqrt: 120 case ots::kSqrt:
167 return "Sqrt"; 121 return "Sqrt";
168 case kDup: 122 case ots::kDup:
169 return "Dup"; 123 return "Dup";
170 case kExch: 124 case ots::kExch:
171 return "Exch"; 125 return "Exch";
172 case kIndex: 126 case ots::kIndex:
173 return "Index"; 127 return "Index";
174 case kRoll: 128 case ots::kRoll:
175 return "Roll"; 129 return "Roll";
176 case kHFlex: 130 case ots::kHFlex:
177 return "HFlex"; 131 return "HFlex";
178 case kFlex: 132 case ots::kFlex:
179 return "Flex"; 133 return "Flex";
180 case kHFlex1: 134 case ots::kHFlex1:
181 return "HFlex1"; 135 return "HFlex1";
182 case kFlex1: 136 case ots::kFlex1:
183 return "Flex1"; 137 return "Flex1";
184 } 138 }
185 139
186 return "UNKNOWN"; 140 return "UNKNOWN";
187 } 141 }
188 142
189 // Read one or more bytes from the |char_string| buffer and stores the number 143 // Read one or more bytes from the |char_string| buffer and stores the number
190 // read on |out_number|. If the number read is an operator (ex 'vstem'), sets 144 // read on |out_number|. If the number read is an operator (ex 'vstem'), sets
191 // true on |out_is_operator|. Returns true if the function read a number. 145 // true on |out_is_operator|. Returns true if the function read a number.
192 bool ReadNextNumberFromType2CharString(ots::Buffer *char_string, 146 bool ReadNextNumberFromType2CharString(ots::Buffer *char_string,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 *out_number = ((static_cast<int32_t>(v) - 247) * 256) + 193 *out_number = ((static_cast<int32_t>(v) - 247) * 256) +
240 static_cast<int32_t>(w) + 108; 194 static_cast<int32_t>(w) + 108;
241 } else if (v <= 254) { 195 } else if (v <= 254) {
242 uint8_t w = 0; 196 uint8_t w = 0;
243 if (!char_string->ReadU8(&w)) { 197 if (!char_string->ReadU8(&w)) {
244 return OTS_FAILURE(); 198 return OTS_FAILURE();
245 } 199 }
246 *out_number = -((static_cast<int32_t>(v) - 251) * 256) - 200 *out_number = -((static_cast<int32_t>(v) - 251) * 256) -
247 static_cast<int32_t>(w) - 108; 201 static_cast<int32_t>(w) - 108;
248 } else if (v == 255) { 202 } else if (v == 255) {
249 uint32_t result = 0; 203 // TODO(yusukes): We should not skip the 4 bytes. Note that when v is 255,
250 for (size_t i = 0; i < 4; ++i) { 204 // we should treat the following 4-bytes as a 16.16 fixed-point number
251 if (!char_string->ReadU8(&v)) { 205 // rather than 32bit signed int.
252 return OTS_FAILURE(); 206 if (!char_string->Skip(4)) {
253 } 207 return OTS_FAILURE();
254 result = (result << 8) + v;
255 } 208 }
256 // TODO(yusukes): |result| should be treated as 16.16 fixed-point number 209 *out_number = dummy_result;
257 // rather than 32bit signed int.
258 *out_number = static_cast<int32_t>(result);
259 } else { 210 } else {
260 return OTS_FAILURE(); 211 return OTS_FAILURE();
261 } 212 }
262 213
263 return true; 214 return true;
264 } 215 }
265 216
266 // Executes |op| and updates |argument_stack|. Returns true if the execution 217 // Executes |op| and updates |argument_stack|. Returns true if the execution
267 // succeeds. If the |op| is kCallSubr or kCallGSubr, the function recursively 218 // succeeds. If the |op| is kCallSubr or kCallGSubr, the function recursively
268 // calls ExecuteType2CharString() function. The arguments other than |op| and 219 // calls ExecuteType2CharString() function. The arguments other than |op| and
269 // |argument_stack| are passed for that reason. 220 // |argument_stack| are passed for that reason.
270 bool ExecuteType2CharStringOperator(int32_t op, 221 bool ExecuteType2CharStringOperator(int32_t op,
271 size_t call_depth, 222 size_t call_depth,
272 const ots::CFFIndex& global_subrs_index, 223 const ots::CFFIndex& global_subrs_index,
273 const ots::CFFIndex& local_subrs_index, 224 const ots::CFFIndex& local_subrs_index,
274 ots::Buffer *cff_table, 225 ots::Buffer *cff_table,
275 ots::Buffer *char_string, 226 ots::Buffer *char_string,
276 std::stack<int32_t> *argument_stack, 227 std::stack<int32_t> *argument_stack,
277 bool *out_found_endchar, 228 bool *out_found_endchar,
278 bool *in_out_found_width, 229 bool *in_out_found_width,
279 size_t *in_out_num_stems) { 230 size_t *in_out_num_stems) {
280 // |dummy_result| should be a huge positive integer so callsubr and callgsubr
281 // will fail with the dummy value.
282 const int32_t dummy_result = std::numeric_limits<int>::max();
283 const size_t stack_size = argument_stack->size(); 231 const size_t stack_size = argument_stack->size();
284 232
285 switch (op) { 233 switch (op) {
286 case kCallSubr: 234 case ots::kCallSubr:
287 case kCallGSubr: { 235 case ots::kCallGSubr: {
288 const ots::CFFIndex& subrs_index = 236 const ots::CFFIndex& subrs_index =
289 (op == kCallSubr ? local_subrs_index : global_subrs_index); 237 (op == ots::kCallSubr ? local_subrs_index : global_subrs_index);
290 238
291 if (stack_size < 1) { 239 if (stack_size < 1) {
292 return OTS_FAILURE(); 240 return OTS_FAILURE();
293 } 241 }
294 int32_t subr_number = argument_stack->top(); 242 int32_t subr_number = argument_stack->top();
295 argument_stack->pop(); 243 argument_stack->pop();
296 if (subr_number == dummy_result) { 244 if (subr_number == dummy_result) {
297 // For safety, we allow subr calls only with immediate subr numbers for 245 // For safety, we allow subr calls only with immediate subr numbers for
298 // now. For example, we allow "123 callgsubr", but does not allow "100 12 246 // now. For example, we allow "123 callgsubr", but does not allow "100 12
299 // add callgsubr". Please note that arithmetic and conditional operators 247 // add callgsubr". Please note that arithmetic and conditional operators
300 // always push the |dummy_result| in this implementation. 248 // always push the |dummy_result| in this implementation.
301 return OTS_FAILURE(); 249 return OTS_FAILURE();
302 } 250 }
303 251
304 // See Adobe Technical Note #5176 (CFF), "16. Local/GlobalSubrs INDEXes." 252 // See Adobe Technical Note #5176 (CFF), "16. Local/GlobalSubrs INDEXes."
305 int32_t bias = 32768; 253 int32_t bias = 32768;
306 if (subrs_index.count < 1240) { 254 if (subrs_index.count < 1240) {
307 bias = 107; 255 bias = 107;
308 } else if (subrs_index.count < 33900) { 256 } else if (subrs_index.count < 33900) {
309 bias = 1131; 257 bias = 1131;
310 } 258 }
311 subr_number += bias; 259 subr_number += bias;
312 260
313 // Sanity checks of |subr_number|. 261 // Sanity checks of |subr_number|.
314 if (subr_number < 0) { 262 if (subr_number < 0) {
315 return OTS_FAILURE(); 263 return OTS_FAILURE();
316 } 264 }
317 if (subrs_index.offsets.size() <= static_cast<size_t>(subr_number)) { 265 if (subr_number >= kMaxSubrsCount) {
266 return OTS_FAILURE();
267 }
268 if (subrs_index.offsets.size() <= static_cast<size_t>(subr_number + 1)) {
318 return OTS_FAILURE(); // The number is out-of-bounds. 269 return OTS_FAILURE(); // The number is out-of-bounds.
319 } 270 }
320 271
321 // Prepare ots::Buffer where we're going to jump. 272 // Prepare ots::Buffer where we're going to jump.
322 const size_t length = 273 const size_t length =
323 subrs_index.offsets[subr_number + 1] - subrs_index.offsets[subr_number]; 274 subrs_index.offsets[subr_number + 1] - subrs_index.offsets[subr_number];
324 if (length > kMaxCharStringLength) { 275 if (length > kMaxCharStringLength) {
325 return OTS_FAILURE(); 276 return OTS_FAILURE();
326 } 277 }
327 const size_t offset = subrs_index.offsets[subr_number]; 278 const size_t offset = subrs_index.offsets[subr_number];
328 cff_table->set_offset(offset); 279 cff_table->set_offset(offset);
329 if (!cff_table->Skip(length)) { 280 if (!cff_table->Skip(length)) {
330 return OTS_FAILURE(); 281 return OTS_FAILURE();
331 } 282 }
332 ots::Buffer char_string_to_jump(cff_table->buffer() + offset, length); 283 ots::Buffer char_string_to_jump(cff_table->buffer() + offset, length);
333 284
334 return ExecuteType2CharString(call_depth + 1, 285 return ExecuteType2CharString(call_depth + 1,
335 global_subrs_index, 286 global_subrs_index,
336 local_subrs_index, 287 local_subrs_index,
337 cff_table, 288 cff_table,
338 &char_string_to_jump, 289 &char_string_to_jump,
339 argument_stack, 290 argument_stack,
340 out_found_endchar, 291 out_found_endchar,
341 in_out_found_width, 292 in_out_found_width,
342 in_out_num_stems); 293 in_out_num_stems);
343 } 294 }
344 295
345 case kReturn: 296 case ots::kReturn:
346 return true; 297 return true;
347 298
348 case kEndChar: 299 case ots::kEndChar:
349 *out_found_endchar = true; 300 *out_found_endchar = true;
350 *in_out_found_width = true; // just in case. 301 *in_out_found_width = true; // just in case.
351 return true; 302 return true;
352 303
353 case kHStem: 304 case ots::kHStem:
354 case kVStem: 305 case ots::kVStem:
355 case kHStemHm: 306 case ots::kHStemHm:
356 case kVStemHm: { 307 case ots::kVStemHm: {
357 bool successful = false; 308 bool successful = false;
358 if (stack_size < 2) { 309 if (stack_size < 2) {
359 return OTS_FAILURE(); 310 return OTS_FAILURE();
360 } 311 }
361 if ((stack_size % 2) == 0) { 312 if ((stack_size % 2) == 0) {
362 successful = true; 313 successful = true;
363 } else if ((!(*in_out_found_width)) && (((stack_size - 1) % 2) == 0)) { 314 } else if ((!(*in_out_found_width)) && (((stack_size - 1) % 2) == 0)) {
364 // The -1 is for "width" argument. For details, see Adobe Technical Note 315 // The -1 is for "width" argument. For details, see Adobe Technical Note
365 // #5177, page 16, note 4. 316 // #5177, page 16, note 4.
366 successful = true; 317 successful = true;
367 } 318 }
368 (*in_out_num_stems) += (stack_size / 2); 319 (*in_out_num_stems) += (stack_size / 2);
369 if ((*in_out_num_stems) > kMaxNumberOfStemHints) { 320 if ((*in_out_num_stems) > kMaxNumberOfStemHints) {
370 return OTS_FAILURE(); 321 return OTS_FAILURE();
371 } 322 }
372 while (!argument_stack->empty()) 323 while (!argument_stack->empty())
373 argument_stack->pop(); 324 argument_stack->pop();
374 *in_out_found_width = true; // always set true since "w" might be 0 byte. 325 *in_out_found_width = true; // always set true since "w" might be 0 byte.
375 return successful ? true : OTS_FAILURE(); 326 return successful ? true : OTS_FAILURE();
376 } 327 }
377 328
378 case kRMoveTo: { 329 case ots::kRMoveTo: {
379 bool successful = false; 330 bool successful = false;
380 if (stack_size == 2) { 331 if (stack_size == 2) {
381 successful = true; 332 successful = true;
382 } else if ((!(*in_out_found_width)) && (stack_size - 1 == 2)) { 333 } else if ((!(*in_out_found_width)) && (stack_size - 1 == 2)) {
383 successful = true; 334 successful = true;
384 } 335 }
385 while (!argument_stack->empty()) 336 while (!argument_stack->empty())
386 argument_stack->pop(); 337 argument_stack->pop();
387 *in_out_found_width = true; 338 *in_out_found_width = true;
388 return successful ? true : OTS_FAILURE(); 339 return successful ? true : OTS_FAILURE();
389 } 340 }
390 341
391 case kVMoveTo: 342 case ots::kVMoveTo:
392 case kHMoveTo: { 343 case ots::kHMoveTo: {
393 bool successful = false; 344 bool successful = false;
394 if (stack_size == 1) { 345 if (stack_size == 1) {
395 successful = true; 346 successful = true;
396 } else if ((!(*in_out_found_width)) && (stack_size - 1 == 1)) { 347 } else if ((!(*in_out_found_width)) && (stack_size - 1 == 1)) {
397 successful = true; 348 successful = true;
398 } 349 }
399 while (!argument_stack->empty()) 350 while (!argument_stack->empty())
400 argument_stack->pop(); 351 argument_stack->pop();
401 *in_out_found_width = true; 352 *in_out_found_width = true;
402 return successful ? true : OTS_FAILURE(); 353 return successful ? true : OTS_FAILURE();
403 } 354 }
404 355
405 case kHintMask: 356 case ots::kHintMask:
406 case kCntrMask: { 357 case ots::kCntrMask: {
407 bool successful = false; 358 bool successful = false;
408 if (stack_size == 0) { 359 if (stack_size == 0) {
409 successful = true; 360 successful = true;
410 } else if ((!(*in_out_found_width)) && (stack_size == 1)) { 361 } else if ((!(*in_out_found_width)) && (stack_size == 1)) {
411 // A number for "width" is found. 362 // A number for "width" is found.
412 successful = true; 363 successful = true;
413 } else if ((!(*in_out_found_width)) || // in this case, any sizes are ok. 364 } else if ((!(*in_out_found_width)) || // in this case, any sizes are ok.
414 ((stack_size % 2) == 0)) { 365 ((stack_size % 2) == 0)) {
415 // The numbers are vstem definition. 366 // The numbers are vstem definition.
416 // See Adobe Technical Note #5177, page 24, hintmask. 367 // See Adobe Technical Note #5177, page 24, hintmask.
(...skipping 13 matching lines...) Expand all
430 const size_t mask_bytes = (*in_out_num_stems + 7) / 8; 381 const size_t mask_bytes = (*in_out_num_stems + 7) / 8;
431 if (!char_string->Skip(mask_bytes)) { 382 if (!char_string->Skip(mask_bytes)) {
432 return OTS_FAILURE(); 383 return OTS_FAILURE();
433 } 384 }
434 while (!argument_stack->empty()) 385 while (!argument_stack->empty())
435 argument_stack->pop(); 386 argument_stack->pop();
436 *in_out_found_width = true; 387 *in_out_found_width = true;
437 return true; 388 return true;
438 } 389 }
439 390
440 case kRLineTo: 391 case ots::kRLineTo:
441 if (!(*in_out_found_width)) { 392 if (!(*in_out_found_width)) {
442 // The first stack-clearing operator should be one of hstem, hstemhm, 393 // The first stack-clearing operator should be one of hstem, hstemhm,
443 // vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto, rmoveto, or 394 // vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto, rmoveto, or
444 // endchar. For details, see Adobe Technical Note #5177, page 16, note 4. 395 // endchar. For details, see Adobe Technical Note #5177, page 16, note 4.
445 return OTS_FAILURE(); 396 return OTS_FAILURE();
446 } 397 }
447 if (stack_size < 2) { 398 if (stack_size < 2) {
448 return OTS_FAILURE(); 399 return OTS_FAILURE();
449 } 400 }
450 if ((stack_size % 2) != 0) { 401 if ((stack_size % 2) != 0) {
451 return OTS_FAILURE(); 402 return OTS_FAILURE();
452 } 403 }
453 while (!argument_stack->empty()) 404 while (!argument_stack->empty())
454 argument_stack->pop(); 405 argument_stack->pop();
455 return true; 406 return true;
456 407
457 case kHLineTo: 408 case ots::kHLineTo:
458 case kVLineTo: 409 case ots::kVLineTo:
459 if (!(*in_out_found_width)) { 410 if (!(*in_out_found_width)) {
460 return OTS_FAILURE(); 411 return OTS_FAILURE();
461 } 412 }
462 if (stack_size < 1) { 413 if (stack_size < 1) {
463 return OTS_FAILURE(); 414 return OTS_FAILURE();
464 } 415 }
465 while (!argument_stack->empty()) 416 while (!argument_stack->empty())
466 argument_stack->pop(); 417 argument_stack->pop();
467 return true; 418 return true;
468 419
469 case kRRCurveTo: 420 case ots::kRRCurveTo:
470 if (!(*in_out_found_width)) { 421 if (!(*in_out_found_width)) {
471 return OTS_FAILURE(); 422 return OTS_FAILURE();
472 } 423 }
473 if (stack_size < 6) { 424 if (stack_size < 6) {
474 return OTS_FAILURE(); 425 return OTS_FAILURE();
475 } 426 }
476 if ((stack_size % 6) != 0) { 427 if ((stack_size % 6) != 0) {
477 return OTS_FAILURE(); 428 return OTS_FAILURE();
478 } 429 }
479 while (!argument_stack->empty()) 430 while (!argument_stack->empty())
480 argument_stack->pop(); 431 argument_stack->pop();
481 return true; 432 return true;
482 433
483 case kRCurveLine: 434 case ots::kRCurveLine:
484 if (!(*in_out_found_width)) { 435 if (!(*in_out_found_width)) {
485 return OTS_FAILURE(); 436 return OTS_FAILURE();
486 } 437 }
487 if (stack_size < 8) { 438 if (stack_size < 8) {
488 return OTS_FAILURE(); 439 return OTS_FAILURE();
489 } 440 }
490 if (((stack_size - 2) % 6) != 0) { 441 if (((stack_size - 2) % 6) != 0) {
491 return OTS_FAILURE(); 442 return OTS_FAILURE();
492 } 443 }
493 while (!argument_stack->empty()) 444 while (!argument_stack->empty())
494 argument_stack->pop(); 445 argument_stack->pop();
495 return true; 446 return true;
496 447
497 case kRLineCurve: 448 case ots::kRLineCurve:
498 if (!(*in_out_found_width)) { 449 if (!(*in_out_found_width)) {
499 return OTS_FAILURE(); 450 return OTS_FAILURE();
500 } 451 }
501 if (stack_size < 8) { 452 if (stack_size < 8) {
502 return OTS_FAILURE(); 453 return OTS_FAILURE();
503 } 454 }
504 if (((stack_size - 6) % 2) != 0) { 455 if (((stack_size - 6) % 2) != 0) {
505 return OTS_FAILURE(); 456 return OTS_FAILURE();
506 } 457 }
507 while (!argument_stack->empty()) 458 while (!argument_stack->empty())
508 argument_stack->pop(); 459 argument_stack->pop();
509 return true; 460 return true;
510 461
511 case kVVCurveTo: 462 case ots::kVVCurveTo:
512 if (!(*in_out_found_width)) { 463 if (!(*in_out_found_width)) {
513 return OTS_FAILURE(); 464 return OTS_FAILURE();
514 } 465 }
515 if (stack_size < 4) { 466 if (stack_size < 4) {
516 return OTS_FAILURE(); 467 return OTS_FAILURE();
517 } 468 }
518 if (((stack_size % 4) != 0) && 469 if (((stack_size % 4) != 0) &&
519 (((stack_size - 1) % 4) != 0)) { 470 (((stack_size - 1) % 4) != 0)) {
520 return OTS_FAILURE(); 471 return OTS_FAILURE();
521 } 472 }
522 while (!argument_stack->empty()) 473 while (!argument_stack->empty())
523 argument_stack->pop(); 474 argument_stack->pop();
524 return true; 475 return true;
525 476
526 case kHHCurveTo: { 477 case ots::kHHCurveTo: {
527 bool successful = false; 478 bool successful = false;
528 if (!(*in_out_found_width)) { 479 if (!(*in_out_found_width)) {
529 return OTS_FAILURE(); 480 return OTS_FAILURE();
530 } 481 }
531 if (stack_size < 4) { 482 if (stack_size < 4) {
532 return OTS_FAILURE(); 483 return OTS_FAILURE();
533 } 484 }
534 if ((stack_size % 4) == 0) { 485 if ((stack_size % 4) == 0) {
535 // {dxa dxb dyb dxc}+ 486 // {dxa dxb dyb dxc}+
536 successful = true; 487 successful = true;
537 } else if (((stack_size - 1) % 4) == 0) { 488 } else if (((stack_size - 1) % 4) == 0) {
538 // dy1? {dxa dxb dyb dxc}+ 489 // dy1? {dxa dxb dyb dxc}+
539 successful = true; 490 successful = true;
540 } 491 }
541 while (!argument_stack->empty()) 492 while (!argument_stack->empty())
542 argument_stack->pop(); 493 argument_stack->pop();
543 return successful ? true : OTS_FAILURE(); 494 return successful ? true : OTS_FAILURE();
544 } 495 }
545 496
546 case kVHCurveTo: 497 case ots::kVHCurveTo:
547 case kHVCurveTo: { 498 case ots::kHVCurveTo: {
548 bool successful = false; 499 bool successful = false;
549 if (!(*in_out_found_width)) { 500 if (!(*in_out_found_width)) {
550 return OTS_FAILURE(); 501 return OTS_FAILURE();
551 } 502 }
552 if (stack_size < 4) { 503 if (stack_size < 4) {
553 return OTS_FAILURE(); 504 return OTS_FAILURE();
554 } 505 }
555 if (((stack_size - 4) % 8) == 0) { 506 if (((stack_size - 4) % 8) == 0) {
556 // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* 507 // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}*
557 successful = true; 508 successful = true;
558 } else if ((stack_size >= 5) && 509 } else if ((stack_size >= 5) &&
559 ((stack_size - 5) % 8) == 0) { 510 ((stack_size - 5) % 8) == 0) {
560 // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf 511 // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf
561 successful = true; 512 successful = true;
562 } else if ((stack_size >= 8) && 513 } else if ((stack_size >= 8) &&
563 ((stack_size - 8) % 8) == 0) { 514 ((stack_size - 8) % 8) == 0) {
564 // {dxa dxb dyb dyc dyd dxe dye dxf}+ 515 // {dxa dxb dyb dyc dyd dxe dye dxf}+
565 successful = true; 516 successful = true;
566 } else if ((stack_size >= 9) && 517 } else if ((stack_size >= 9) &&
567 ((stack_size - 9) % 8) == 0) { 518 ((stack_size - 9) % 8) == 0) {
568 // {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf? 519 // {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf?
569 successful = true; 520 successful = true;
570 } 521 }
571 while (!argument_stack->empty()) 522 while (!argument_stack->empty())
572 argument_stack->pop(); 523 argument_stack->pop();
573 return successful ? true : OTS_FAILURE(); 524 return successful ? true : OTS_FAILURE();
574 } 525 }
575 526
576 case kAnd: 527 case ots::kAnd:
577 case kOr: 528 case ots::kOr:
578 case kEq: 529 case ots::kEq:
579 case kAdd: 530 case ots::kAdd:
580 case kSub: 531 case ots::kSub:
581 if (stack_size < 2) { 532 if (stack_size < 2) {
582 return OTS_FAILURE(); 533 return OTS_FAILURE();
583 } 534 }
584 argument_stack->pop(); 535 argument_stack->pop();
585 argument_stack->pop(); 536 argument_stack->pop();
586 argument_stack->push(dummy_result); 537 argument_stack->push(dummy_result);
587 // TODO(yusukes): Implement this. We should push a real value for all 538 // TODO(yusukes): Implement this. We should push a real value for all
588 // arithmetic and conditional operations. 539 // arithmetic and conditional operations.
589 return true; 540 return true;
590 541
591 case kNot: 542 case ots::kNot:
592 case kAbs: 543 case ots::kAbs:
593 case kNeg: 544 case ots::kNeg:
594 if (stack_size < 1) { 545 if (stack_size < 1) {
595 return OTS_FAILURE(); 546 return OTS_FAILURE();
596 } 547 }
597 argument_stack->pop(); 548 argument_stack->pop();
598 argument_stack->push(dummy_result); 549 argument_stack->push(dummy_result);
599 // TODO(yusukes): Implement this. We should push a real value for all 550 // TODO(yusukes): Implement this. We should push a real value for all
600 // arithmetic and conditional operations. 551 // arithmetic and conditional operations.
601 return true; 552 return true;
602 553
603 case kDiv: 554 case ots::kDiv:
604 // TODO(yusukes): Should detect div-by-zero errors. 555 // TODO(yusukes): Should detect div-by-zero errors.
605 if (stack_size < 1) { 556 if (stack_size < 2) {
606 return OTS_FAILURE(); 557 return OTS_FAILURE();
607 } 558 }
608 argument_stack->pop(); 559 argument_stack->pop();
560 argument_stack->pop();
609 argument_stack->push(dummy_result); 561 argument_stack->push(dummy_result);
610 // TODO(yusukes): Implement this. We should push a real value for all 562 // TODO(yusukes): Implement this. We should push a real value for all
611 // arithmetic and conditional operations. 563 // arithmetic and conditional operations.
612 return true; 564 return true;
613 565
614 case kDrop: 566 case ots::kDrop:
615 if (stack_size < 1) { 567 if (stack_size < 1) {
616 return OTS_FAILURE(); 568 return OTS_FAILURE();
617 } 569 }
618 argument_stack->pop(); 570 argument_stack->pop();
619 return true; 571 return true;
620 572
621 case kPut: 573 case ots::kPut:
622 case kGet: 574 case ots::kGet:
623 case kIndex: 575 case ots::kIndex:
624 // For now, just call OTS_FAILURE since there is no way to check whether the 576 // For now, just call OTS_FAILURE since there is no way to check whether the
625 // index argument, |i|, is out-of-bounds or not. Fortunately, no OpenType 577 // index argument, |i|, is out-of-bounds or not. Fortunately, no OpenType
626 // fonts I have (except malicious ones!) use the operators. 578 // fonts I have (except malicious ones!) use the operators.
627 // TODO(yusukes): Implement them in a secure way. 579 // TODO(yusukes): Implement them in a secure way.
628 return OTS_FAILURE(); 580 return OTS_FAILURE();
629 581
630 case kRoll: 582 case ots::kRoll:
631 // Likewise, just call OTS_FAILURE for kRoll since there is no way to check 583 // Likewise, just call OTS_FAILURE for kRoll since there is no way to check
632 // whether |N| is smaller than the current stack depth or not. 584 // whether |N| is smaller than the current stack depth or not.
633 // TODO(yusukes): Implement them in a secure way. 585 // TODO(yusukes): Implement them in a secure way.
634 return OTS_FAILURE(); 586 return OTS_FAILURE();
635 587
636 case kRandom: 588 case ots::kRandom:
637 // For now, we don't handle the 'random' operator since the operator makes 589 // For now, we don't handle the 'random' operator since the operator makes
638 // it hard to analyze hinting code statically. 590 // it hard to analyze hinting code statically.
639 return OTS_FAILURE(); 591 return OTS_FAILURE();
640 592
641 case kIfElse: 593 case ots::kIfElse:
642 if (stack_size < 4) { 594 if (stack_size < 4) {
643 return OTS_FAILURE(); 595 return OTS_FAILURE();
644 } 596 }
645 argument_stack->pop(); 597 argument_stack->pop();
646 argument_stack->pop(); 598 argument_stack->pop();
647 argument_stack->pop(); 599 argument_stack->pop();
648 argument_stack->pop(); 600 argument_stack->pop();
649 argument_stack->push(dummy_result); 601 argument_stack->push(dummy_result);
650 // TODO(yusukes): Implement this. We should push a real value for all 602 // TODO(yusukes): Implement this. We should push a real value for all
651 // arithmetic and conditional operations. 603 // arithmetic and conditional operations.
652 return true; 604 return true;
653 605
654 case kMul: 606 case ots::kMul:
655 // TODO(yusukes): Should detect overflows. 607 // TODO(yusukes): Should detect overflows.
656 if (stack_size < 2) { 608 if (stack_size < 2) {
657 return OTS_FAILURE(); 609 return OTS_FAILURE();
658 } 610 }
659 argument_stack->pop(); 611 argument_stack->pop();
660 argument_stack->pop(); 612 argument_stack->pop();
661 argument_stack->push(dummy_result); 613 argument_stack->push(dummy_result);
662 // TODO(yusukes): Implement this. We should push a real value for all 614 // TODO(yusukes): Implement this. We should push a real value for all
663 // arithmetic and conditional operations. 615 // arithmetic and conditional operations.
664 return true; 616 return true;
665 617
666 case kSqrt: 618 case ots::kSqrt:
667 // TODO(yusukes): Should check if the argument is negative. 619 // TODO(yusukes): Should check if the argument is negative.
668 if (stack_size < 1) { 620 if (stack_size < 1) {
669 return OTS_FAILURE(); 621 return OTS_FAILURE();
670 } 622 }
671 argument_stack->pop(); 623 argument_stack->pop();
672 argument_stack->push(dummy_result); 624 argument_stack->push(dummy_result);
673 // TODO(yusukes): Implement this. We should push a real value for all 625 // TODO(yusukes): Implement this. We should push a real value for all
674 // arithmetic and conditional operations. 626 // arithmetic and conditional operations.
675 return true; 627 return true;
676 628
677 case kDup: 629 case ots::kDup:
678 if (stack_size < 1) { 630 if (stack_size < 1) {
679 return OTS_FAILURE(); 631 return OTS_FAILURE();
680 } 632 }
681 argument_stack->pop(); 633 argument_stack->pop();
682 argument_stack->push(dummy_result); 634 argument_stack->push(dummy_result);
683 argument_stack->push(dummy_result); 635 argument_stack->push(dummy_result);
684 if (argument_stack->size() > kMaxArgumentStack) { 636 if (argument_stack->size() > kMaxArgumentStack) {
685 return OTS_FAILURE(); 637 return OTS_FAILURE();
686 } 638 }
687 // TODO(yusukes): Implement this. We should push a real value for all 639 // TODO(yusukes): Implement this. We should push a real value for all
688 // arithmetic and conditional operations. 640 // arithmetic and conditional operations.
689 return true; 641 return true;
690 642
691 case kExch: 643 case ots::kExch:
692 if (stack_size < 2) { 644 if (stack_size < 2) {
693 return OTS_FAILURE(); 645 return OTS_FAILURE();
694 } 646 }
695 argument_stack->pop(); 647 argument_stack->pop();
696 argument_stack->pop(); 648 argument_stack->pop();
697 argument_stack->push(dummy_result); 649 argument_stack->push(dummy_result);
698 argument_stack->push(dummy_result); 650 argument_stack->push(dummy_result);
699 // TODO(yusukes): Implement this. We should push a real value for all 651 // TODO(yusukes): Implement this. We should push a real value for all
700 // arithmetic and conditional operations. 652 // arithmetic and conditional operations.
701 return true; 653 return true;
702 654
703 case kHFlex: 655 case ots::kHFlex:
704 if (!(*in_out_found_width)) { 656 if (!(*in_out_found_width)) {
705 return OTS_FAILURE(); 657 return OTS_FAILURE();
706 } 658 }
707 if (stack_size != 7) { 659 if (stack_size != 7) {
708 return OTS_FAILURE(); 660 return OTS_FAILURE();
709 } 661 }
710 while (!argument_stack->empty()) 662 while (!argument_stack->empty())
711 argument_stack->pop(); 663 argument_stack->pop();
712 return true; 664 return true;
713 665
714 case kFlex: 666 case ots::kFlex:
715 if (!(*in_out_found_width)) { 667 if (!(*in_out_found_width)) {
716 return OTS_FAILURE(); 668 return OTS_FAILURE();
717 } 669 }
718 if (stack_size != 13) { 670 if (stack_size != 13) {
719 return OTS_FAILURE(); 671 return OTS_FAILURE();
720 } 672 }
721 while (!argument_stack->empty()) 673 while (!argument_stack->empty())
722 argument_stack->pop(); 674 argument_stack->pop();
723 return true; 675 return true;
724 676
725 case kHFlex1: 677 case ots::kHFlex1:
726 if (!(*in_out_found_width)) { 678 if (!(*in_out_found_width)) {
727 return OTS_FAILURE(); 679 return OTS_FAILURE();
728 } 680 }
729 if (stack_size != 9) { 681 if (stack_size != 9) {
730 return OTS_FAILURE(); 682 return OTS_FAILURE();
731 } 683 }
732 while (!argument_stack->empty()) 684 while (!argument_stack->empty())
733 argument_stack->pop(); 685 argument_stack->pop();
734 return true; 686 return true;
735 687
736 case kFlex1: 688 case ots::kFlex1:
737 if (!(*in_out_found_width)) { 689 if (!(*in_out_found_width)) {
738 return OTS_FAILURE(); 690 return OTS_FAILURE();
739 } 691 }
740 if (stack_size != 11) { 692 if (stack_size != 11) {
741 return OTS_FAILURE(); 693 return OTS_FAILURE();
742 } 694 }
743 while (!argument_stack->empty()) 695 while (!argument_stack->empty())
744 argument_stack->pop(); 696 argument_stack->pop();
745 return true; 697 return true;
746 } 698 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 char_string, 769 char_string,
818 argument_stack, 770 argument_stack,
819 out_found_endchar, 771 out_found_endchar,
820 in_out_found_width, 772 in_out_found_width,
821 in_out_num_stems)) { 773 in_out_num_stems)) {
822 return OTS_FAILURE(); 774 return OTS_FAILURE();
823 } 775 }
824 if (*out_found_endchar) { 776 if (*out_found_endchar) {
825 return true; 777 return true;
826 } 778 }
827 if (operator_or_operand == kReturn) { 779 if (operator_or_operand == ots::kReturn) {
828 return true; 780 return true;
829 } 781 }
830 } 782 }
831 783
832 // No endchar operator is found. 784 // No endchar operator is found.
833 return OTS_FAILURE(); 785 return OTS_FAILURE();
834 } 786 }
835 787
836 // Selects a set of subroutings for |glyph_index| from |cff| and sets it on 788 // Selects a set of subroutings for |glyph_index| from |cff| and sets it on
837 // |out_local_subrs_to_use|. Returns true on success. 789 // |out_local_subrs_to_use|. Returns true on success.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 std::stack<int32_t> argument_stack; 872 std::stack<int32_t> argument_stack;
921 bool found_endchar = false; 873 bool found_endchar = false;
922 bool found_width = false; 874 bool found_width = false;
923 size_t num_stems = 0; 875 size_t num_stems = 0;
924 if (!ExecuteType2CharString(0 /* initial call_depth is zero */, 876 if (!ExecuteType2CharString(0 /* initial call_depth is zero */,
925 global_subrs_index, *local_subrs_to_use, 877 global_subrs_index, *local_subrs_to_use,
926 cff_table, &char_string, &argument_stack, 878 cff_table, &char_string, &argument_stack,
927 &found_endchar, &found_width, &num_stems)) { 879 &found_endchar, &found_width, &num_stems)) {
928 return OTS_FAILURE(); 880 return OTS_FAILURE();
929 } 881 }
882 if (!found_endchar) {
883 return OTS_FAILURE();
884 }
930 } 885 }
931 return true; 886 return true;
932 } 887 }
933 888
934 } // namespace ots 889 } // namespace ots
OLDNEW
« no previous file with comments | « src/cff_type2_charstring.h ('k') | test/SConstruct » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698