| OLD | NEW |
| 1 /***************************************************************************/ | 1 /***************************************************************************/ |
| 2 /* */ | 2 /* */ |
| 3 /* t1parse.c */ | 3 /* t1parse.c */ |
| 4 /* */ | 4 /* */ |
| 5 /* Type 1 parser (body). */ | 5 /* Type 1 parser (body). */ |
| 6 /* */ | 6 /* */ |
| 7 /* Copyright 1996-2005, 2008, 2009, 2012-2014 by */ | 7 /* Copyright 1996-2015 by */ |
| 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
| 9 /* */ | 9 /* */ |
| 10 /* This file is part of the FreeType project, and may only be used, */ | 10 /* This file is part of the FreeType project, and may only be used, */ |
| 11 /* modified, and distributed under the terms of the FreeType project */ | 11 /* modified, and distributed under the terms of the FreeType project */ |
| 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
| 13 /* this file you indicate that you have read the license and */ | 13 /* this file you indicate that you have read the license and */ |
| 14 /* understand and accept it fully. */ | 14 /* understand and accept it fully. */ |
| 15 /* */ | 15 /* */ |
| 16 /***************************************************************************/ | 16 /***************************************************************************/ |
| 17 | 17 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 T1_New_Parser( T1_Parser parser, | 136 T1_New_Parser( T1_Parser parser, |
| 137 FT_Stream stream, | 137 FT_Stream stream, |
| 138 FT_Memory memory, | 138 FT_Memory memory, |
| 139 PSAux_Service psaux ) | 139 PSAux_Service psaux ) |
| 140 { | 140 { |
| 141 FT_Error error; | 141 FT_Error error; |
| 142 FT_UShort tag; | 142 FT_UShort tag; |
| 143 FT_ULong size; | 143 FT_ULong size; |
| 144 | 144 |
| 145 | 145 |
| 146 psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); | 146 psaux->ps_parser_funcs->init( &parser->root, NULL, NULL, memory ); |
| 147 | 147 |
| 148 parser->stream = stream; | 148 parser->stream = stream; |
| 149 parser->base_len = 0; | 149 parser->base_len = 0; |
| 150 parser->base_dict = 0; | 150 parser->base_dict = NULL; |
| 151 parser->private_len = 0; | 151 parser->private_len = 0; |
| 152 parser->private_dict = 0; | 152 parser->private_dict = NULL; |
| 153 parser->in_pfb = 0; | 153 parser->in_pfb = 0; |
| 154 parser->in_memory = 0; | 154 parser->in_memory = 0; |
| 155 parser->single_block = 0; | 155 parser->single_block = 0; |
| 156 | 156 |
| 157 /* check the header format */ | 157 /* check the header format */ |
| 158 error = check_type1_format( stream, "%!PS-AdobeFont", 14 ); | 158 error = check_type1_format( stream, "%!PS-AdobeFont", 14 ); |
| 159 if ( error ) | 159 if ( error ) |
| 160 { | 160 { |
| 161 if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) | 161 if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) |
| 162 goto Exit; | 162 goto Exit; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 FT_Error error = FT_Err_Ok; | 266 FT_Error error = FT_Err_Ok; |
| 267 FT_ULong size; | 267 FT_ULong size; |
| 268 | 268 |
| 269 | 269 |
| 270 if ( parser->in_pfb ) | 270 if ( parser->in_pfb ) |
| 271 { | 271 { |
| 272 /* in the case of the PFB format, the private dictionary can be */ | 272 /* in the case of the PFB format, the private dictionary can be */ |
| 273 /* made of several segments. We thus first read the number of */ | 273 /* made of several segments. We thus first read the number of */ |
| 274 /* segments to compute the total size of the private dictionary */ | 274 /* segments to compute the total size of the private dictionary */ |
| 275 /* then re-read them into memory. */ | 275 /* then re-read them into memory. */ |
| 276 FT_Long start_pos = FT_STREAM_POS(); | 276 FT_ULong start_pos = FT_STREAM_POS(); |
| 277 FT_UShort tag; | 277 FT_UShort tag; |
| 278 | 278 |
| 279 | 279 |
| 280 parser->private_len = 0; | 280 parser->private_len = 0; |
| 281 for (;;) | 281 for (;;) |
| 282 { | 282 { |
| 283 error = read_pfb_tag( stream, &tag, &size ); | 283 error = read_pfb_tag( stream, &tag, &size ); |
| 284 if ( error ) | 284 if ( error ) |
| 285 goto Fail; | 285 goto Fail; |
| 286 | 286 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 else | 327 else |
| 328 { | 328 { |
| 329 /* We have already `loaded' the whole PFA font file into memory; */ | 329 /* We have already `loaded' the whole PFA font file into memory; */ |
| 330 /* if this is a memory resource, allocate a new block to hold */ | 330 /* if this is a memory resource, allocate a new block to hold */ |
| 331 /* the private dict. Otherwise, simply overwrite into the base */ | 331 /* the private dict. Otherwise, simply overwrite into the base */ |
| 332 /* dictionary block in the heap. */ | 332 /* dictionary block in the heap. */ |
| 333 | 333 |
| 334 /* first of all, look at the `eexec' keyword */ | 334 /* first of all, look at the `eexec' keyword */ |
| 335 FT_Byte* cur = parser->base_dict; | 335 FT_Byte* cur = parser->base_dict; |
| 336 FT_Byte* limit = cur + parser->base_len; | 336 FT_Byte* limit = cur + parser->base_len; |
| 337 FT_Byte c; | |
| 338 FT_Pointer pos_lf; | 337 FT_Pointer pos_lf; |
| 339 FT_Bool test_cr; | 338 FT_Bool test_cr; |
| 340 | 339 |
| 341 | 340 |
| 342 Again: | 341 Again: |
| 343 for (;;) | 342 for (;;) |
| 344 { | 343 { |
| 345 c = cur[0]; | 344 if ( cur[0] == 'e' && |
| 346 if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ | 345 cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ |
| 347 /* whitespace + 4 chars */ | 346 /* whitespace + 4 chars */ |
| 348 { | 347 { |
| 349 if ( cur[1] == 'e' && | 348 if ( cur[1] == 'e' && |
| 350 cur[2] == 'x' && | 349 cur[2] == 'x' && |
| 351 cur[3] == 'e' && | 350 cur[3] == 'e' && |
| 352 cur[4] == 'c' ) | 351 cur[4] == 'c' ) |
| 353 break; | 352 break; |
| 354 } | 353 } |
| 355 cur++; | 354 cur++; |
| 356 if ( cur >= limit ) | 355 if ( cur >= limit ) |
| 357 { | 356 { |
| 358 FT_ERROR(( "T1_Get_Private_Dict:" | 357 FT_ERROR(( "T1_Get_Private_Dict:" |
| 359 " could not find `eexec' keyword\n" )); | 358 " could not find `eexec' keyword\n" )); |
| 360 error = FT_THROW( Invalid_File_Format ); | 359 error = FT_THROW( Invalid_File_Format ); |
| 361 goto Exit; | 360 goto Exit; |
| 362 } | 361 } |
| 363 } | 362 } |
| 364 | 363 |
| 365 /* check whether `eexec' was real -- it could be in a comment */ | 364 /* check whether `eexec' was real -- it could be in a comment */ |
| 366 /* or string (as e.g. in u003043t.gsf from ghostscript) */ | 365 /* or string (as e.g. in u003043t.gsf from ghostscript) */ |
| 367 | 366 |
| 368 parser->root.cursor = parser->base_dict; | 367 parser->root.cursor = parser->base_dict; |
| 369 /* set limit to `eexec' + whitespace + 4 characters */ | 368 /* set limit to `eexec' + whitespace + 4 characters */ |
| 370 parser->root.limit = cur + 10; | 369 parser->root.limit = cur + 10; |
| 371 | 370 |
| 372 cur = parser->root.cursor; | 371 cur = parser->root.cursor; |
| 373 limit = parser->root.limit; | 372 limit = parser->root.limit; |
| 374 | 373 |
| 375 while ( cur < limit ) | 374 while ( cur < limit ) |
| 376 { | 375 { |
| 377 if ( *cur == 'e' && ft_strncmp( (char*)cur, "eexec", 5 ) == 0 ) | 376 if ( cur[0] == 'e' && |
| 378 goto Found; | 377 cur + 5 < limit ) |
| 378 { |
| 379 if ( cur[1] == 'e' && |
| 380 cur[2] == 'x' && |
| 381 cur[3] == 'e' && |
| 382 cur[4] == 'c' ) |
| 383 goto Found; |
| 384 } |
| 379 | 385 |
| 380 T1_Skip_PS_Token( parser ); | 386 T1_Skip_PS_Token( parser ); |
| 381 if ( parser->root.error ) | 387 if ( parser->root.error ) |
| 382 break; | 388 break; |
| 383 T1_Skip_Spaces ( parser ); | 389 T1_Skip_Spaces ( parser ); |
| 384 cur = parser->root.cursor; | 390 cur = parser->root.cursor; |
| 385 } | 391 } |
| 386 | 392 |
| 387 /* we haven't found the correct `eexec'; go back and continue */ | 393 /* we haven't found the correct `eexec'; go back and continue */ |
| 388 /* searching */ | 394 /* searching */ |
| 389 | 395 |
| 390 cur = limit; | 396 cur = limit; |
| 391 limit = parser->base_dict + parser->base_len; | 397 limit = parser->base_dict + parser->base_len; |
| 398 |
| 399 if ( cur >= limit ) |
| 400 { |
| 401 FT_ERROR(( "T1_Get_Private_Dict:" |
| 402 " premature end in private dictionary\n" )); |
| 403 error = FT_THROW( Invalid_File_Format ); |
| 404 goto Exit; |
| 405 } |
| 406 |
| 392 goto Again; | 407 goto Again; |
| 393 | 408 |
| 394 /* now determine where to write the _encrypted_ binary private */ | 409 /* now determine where to write the _encrypted_ binary private */ |
| 395 /* dictionary. We overwrite the base dictionary for disk-based */ | 410 /* dictionary. We overwrite the base dictionary for disk-based */ |
| 396 /* resources and allocate a new block otherwise */ | 411 /* resources and allocate a new block otherwise */ |
| 397 | 412 |
| 398 Found: | 413 Found: |
| 399 parser->root.limit = parser->base_dict + parser->base_len; | 414 parser->root.limit = parser->base_dict + parser->base_len; |
| 400 | 415 |
| 401 T1_Skip_PS_Token( parser ); | 416 T1_Skip_PS_Token( parser ); |
| 402 cur = parser->root.cursor; | 417 cur = parser->root.cursor; |
| 403 limit = parser->root.limit; | 418 limit = parser->root.limit; |
| 404 | 419 |
| 405 /* According to the Type 1 spec, the first cipher byte must not be */ | 420 /* According to the Type 1 spec, the first cipher byte must not be */ |
| 406 /* an ASCII whitespace character code (blank, tab, carriage return */ | 421 /* an ASCII whitespace character code (blank, tab, carriage return */ |
| 407 /* or line feed). We have seen Type 1 fonts with two line feed */ | 422 /* or line feed). We have seen Type 1 fonts with two line feed */ |
| 408 /* characters... So skip now all whitespace character codes. */ | 423 /* characters... So skip now all whitespace character codes. */ |
| 409 /* */ | 424 /* */ |
| 410 /* On the other hand, Adobe's Type 1 parser handles fonts just */ | 425 /* On the other hand, Adobe's Type 1 parser handles fonts just */ |
| 411 /* fine that are violating this limitation, so we add a heuristic */ | 426 /* fine that are violating this limitation, so we add a heuristic */ |
| 412 /* test to stop at \r only if it is not used for EOL. */ | 427 /* test to stop at \r only if it is not used for EOL. */ |
| 413 | 428 |
| 414 pos_lf = ft_memchr( cur, '\n', limit - cur ); | 429 pos_lf = ft_memchr( cur, '\n', (size_t)( limit - cur ) ); |
| 415 test_cr = FT_BOOL( !pos_lf || | 430 test_cr = FT_BOOL( !pos_lf || |
| 416 pos_lf > ft_memchr( cur, '\r', limit - cur ) ); | 431 pos_lf > ft_memchr( cur, |
| 432 '\r', |
| 433 (size_t)( limit - cur ) ) ); |
| 417 | 434 |
| 418 while ( cur < limit && | 435 while ( cur < limit && |
| 419 ( *cur == ' ' || | 436 ( *cur == ' ' || |
| 420 *cur == '\t' || | 437 *cur == '\t' || |
| 421 (test_cr && *cur == '\r' ) || | 438 (test_cr && *cur == '\r' ) || |
| 422 *cur == '\n' ) ) | 439 *cur == '\n' ) ) |
| 423 ++cur; | 440 ++cur; |
| 424 if ( cur >= limit ) | 441 if ( cur >= limit ) |
| 425 { | 442 { |
| 426 FT_ERROR(( "T1_Get_Private_Dict:" | 443 FT_ERROR(( "T1_Get_Private_Dict:" |
| 427 " `eexec' not properly terminated\n" )); | 444 " `eexec' not properly terminated\n" )); |
| 428 error = FT_THROW( Invalid_File_Format ); | 445 error = FT_THROW( Invalid_File_Format ); |
| 429 goto Exit; | 446 goto Exit; |
| 430 } | 447 } |
| 431 | 448 |
| 432 size = (FT_ULong)( parser->base_len - ( cur - parser->base_dict ) ); | 449 size = parser->base_len - (FT_ULong)( cur - parser->base_dict ); |
| 433 | 450 |
| 434 if ( parser->in_memory ) | 451 if ( parser->in_memory ) |
| 435 { | 452 { |
| 436 /* note that we allocate one more byte to put a terminating `0' */ | 453 /* note that we allocate one more byte to put a terminating `0' */ |
| 437 if ( FT_ALLOC( parser->private_dict, size + 1 ) ) | 454 if ( FT_ALLOC( parser->private_dict, size + 1 ) ) |
| 438 goto Fail; | 455 goto Fail; |
| 439 parser->private_len = size; | 456 parser->private_len = size; |
| 440 } | 457 } |
| 441 else | 458 else |
| 442 { | 459 { |
| 443 parser->single_block = 1; | 460 parser->single_block = 1; |
| 444 parser->private_dict = parser->base_dict; | 461 parser->private_dict = parser->base_dict; |
| 445 parser->private_len = size; | 462 parser->private_len = size; |
| 446 parser->base_dict = 0; | 463 parser->base_dict = NULL; |
| 447 parser->base_len = 0; | 464 parser->base_len = 0; |
| 448 } | 465 } |
| 449 | 466 |
| 450 /* now determine whether the private dictionary is encoded in binary */ | 467 /* now determine whether the private dictionary is encoded in binary */ |
| 451 /* or hexadecimal ASCII format -- decode it accordingly */ | 468 /* or hexadecimal ASCII format -- decode it accordingly */ |
| 452 | 469 |
| 453 /* we need to access the next 4 bytes (after the final whitespace */ | 470 /* we need to access the next 4 bytes (after the final whitespace */ |
| 454 /* following the `eexec' keyword); if they all are hexadecimal */ | 471 /* following the `eexec' keyword); if they all are hexadecimal */ |
| 455 /* digits, then we have a case of ASCII storage */ | 472 /* digits, then we have a case of ASCII storage */ |
| 456 | 473 |
| 457 if ( cur + 3 < limit && | 474 if ( cur + 3 < limit && |
| 458 ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) && | 475 ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) && |
| 459 ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) ) | 476 ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) ) |
| 460 { | 477 { |
| 461 /* ASCII hexadecimal encoding */ | 478 /* ASCII hexadecimal encoding */ |
| 462 FT_Long len; | 479 FT_ULong len; |
| 463 | 480 |
| 464 | 481 |
| 465 parser->root.cursor = cur; | 482 parser->root.cursor = cur; |
| 466 (void)psaux->ps_parser_funcs->to_bytes( &parser->root, | 483 (void)psaux->ps_parser_funcs->to_bytes( &parser->root, |
| 467 parser->private_dict, | 484 parser->private_dict, |
| 468 parser->private_len, | 485 parser->private_len, |
| 469 &len, | 486 &len, |
| 470 0 ); | 487 0 ); |
| 471 parser->private_len = len; | 488 parser->private_len = len; |
| 472 | 489 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 499 parser->root.cursor = parser->private_dict; | 516 parser->root.cursor = parser->private_dict; |
| 500 parser->root.limit = parser->root.cursor + parser->private_len; | 517 parser->root.limit = parser->root.cursor + parser->private_len; |
| 501 | 518 |
| 502 Fail: | 519 Fail: |
| 503 Exit: | 520 Exit: |
| 504 return error; | 521 return error; |
| 505 } | 522 } |
| 506 | 523 |
| 507 | 524 |
| 508 /* END */ | 525 /* END */ |
| OLD | NEW |