00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <ft2build.h>
00037 #include FT_INTERNAL_DEBUG_H
00038 #include FT_INTERNAL_STREAM_H
00039 #include FT_INTERNAL_POSTSCRIPT_AUX_H
00040
00041 #include "t1parse.h"
00042
00043 #include "t1errors.h"
00044
00045
00046
00047
00048
00049
00050
00051
00052 #undef FT_COMPONENT
00053 #define FT_COMPONENT trace_t1parse
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 static FT_Error
00070 read_pfb_tag( FT_Stream stream,
00071 FT_UShort *atag,
00072 FT_ULong *asize )
00073 {
00074 FT_Error error;
00075 FT_UShort tag;
00076 FT_ULong size;
00077
00078
00079 *atag = 0;
00080 *asize = 0;
00081
00082 if ( !FT_READ_USHORT( tag ) )
00083 {
00084 if ( tag == 0x8001U || tag == 0x8002U )
00085 {
00086 if ( !FT_READ_ULONG_LE( size ) )
00087 *asize = size;
00088 }
00089
00090 *atag = tag;
00091 }
00092
00093 return error;
00094 }
00095
00096
00097 static FT_Error
00098 check_type1_format( FT_Stream stream,
00099 const char* header_string,
00100 size_t header_length )
00101 {
00102 FT_Error error;
00103 FT_UShort tag;
00104 FT_ULong dummy;
00105
00106
00107 if ( FT_STREAM_SEEK( 0 ) )
00108 goto Exit;
00109
00110 error = read_pfb_tag( stream, &tag, &dummy );
00111 if ( error )
00112 goto Exit;
00113
00114
00115
00116
00117 if ( tag != 0x8001U && FT_STREAM_SEEK( 0 ) )
00118 goto Exit;
00119
00120 if ( !FT_FRAME_ENTER( header_length ) )
00121 {
00122 error = T1_Err_Ok;
00123
00124 if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 )
00125 error = T1_Err_Unknown_File_Format;
00126
00127 FT_FRAME_EXIT();
00128 }
00129
00130 Exit:
00131 return error;
00132 }
00133
00134
00135 FT_LOCAL_DEF( FT_Error )
00136 T1_New_Parser( T1_Parser parser,
00137 FT_Stream stream,
00138 FT_Memory memory,
00139 PSAux_Service psaux )
00140 {
00141 FT_Error error;
00142 FT_UShort tag;
00143 FT_ULong size;
00144
00145
00146 psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );
00147
00148 parser->stream = stream;
00149 parser->base_len = 0;
00150 parser->base_dict = 0;
00151 parser->private_len = 0;
00152 parser->private_dict = 0;
00153 parser->in_pfb = 0;
00154 parser->in_memory = 0;
00155 parser->single_block = 0;
00156
00157
00158 error = check_type1_format( stream, "%!PS-AdobeFont", 14 );
00159 if ( error )
00160 {
00161 if ( error != T1_Err_Unknown_File_Format )
00162 goto Exit;
00163
00164 error = check_type1_format( stream, "%!FontType", 10 );
00165 if ( error )
00166 {
00167 FT_TRACE2(( "[not a Type1 font]\n" ));
00168 goto Exit;
00169 }
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 if ( FT_STREAM_SEEK( 0L ) )
00191 goto Exit;
00192
00193 error = read_pfb_tag( stream, &tag, &size );
00194 if ( error )
00195 goto Exit;
00196
00197 if ( tag != 0x8001U )
00198 {
00199
00200
00201 if ( FT_STREAM_SEEK( 0L ) )
00202 goto Exit;
00203 size = stream->size;
00204 }
00205 else
00206 parser->in_pfb = 1;
00207
00208
00209
00210
00211
00212 if ( !stream->read )
00213 {
00214 parser->base_dict = (FT_Byte*)stream->base + stream->pos;
00215 parser->base_len = size;
00216 parser->in_memory = 1;
00217
00218
00219 if ( FT_STREAM_SKIP( size ) )
00220 goto Exit;
00221 }
00222 else
00223 {
00224
00225 if ( FT_ALLOC( parser->base_dict, size ) ||
00226 FT_STREAM_READ( parser->base_dict, size ) )
00227 goto Exit;
00228 parser->base_len = size;
00229 }
00230
00231 parser->root.base = parser->base_dict;
00232 parser->root.cursor = parser->base_dict;
00233 parser->root.limit = parser->root.cursor + parser->base_len;
00234
00235 Exit:
00236 if ( error && !parser->in_memory )
00237 FT_FREE( parser->base_dict );
00238
00239 return error;
00240 }
00241
00242
00243 FT_LOCAL_DEF( void )
00244 T1_Finalize_Parser( T1_Parser parser )
00245 {
00246 FT_Memory memory = parser->root.memory;
00247
00248
00249
00250 FT_FREE( parser->private_dict );
00251
00252
00253 if ( !parser->in_memory )
00254 FT_FREE( parser->base_dict );
00255
00256 parser->root.funcs.done( &parser->root );
00257 }
00258
00259
00260 FT_LOCAL_DEF( FT_Error )
00261 T1_Get_Private_Dict( T1_Parser parser,
00262 PSAux_Service psaux )
00263 {
00264 FT_Stream stream = parser->stream;
00265 FT_Memory memory = parser->root.memory;
00266 FT_Error error = T1_Err_Ok;
00267 FT_ULong size;
00268
00269
00270 if ( parser->in_pfb )
00271 {
00272
00273
00274
00275
00276 FT_Long start_pos = FT_STREAM_POS();
00277 FT_UShort tag;
00278
00279
00280 parser->private_len = 0;
00281 for (;;)
00282 {
00283 error = read_pfb_tag( stream, &tag, &size );
00284 if ( error )
00285 goto Fail;
00286
00287 if ( tag != 0x8002U )
00288 break;
00289
00290 parser->private_len += size;
00291
00292 if ( FT_STREAM_SKIP( size ) )
00293 goto Fail;
00294 }
00295
00296
00297
00298 if ( parser->private_len == 0 )
00299 {
00300 FT_ERROR(( "T1_Get_Private_Dict:"
00301 " invalid private dictionary section\n" ));
00302 error = T1_Err_Invalid_File_Format;
00303 goto Fail;
00304 }
00305
00306 if ( FT_STREAM_SEEK( start_pos ) ||
00307 FT_ALLOC( parser->private_dict, parser->private_len ) )
00308 goto Fail;
00309
00310 parser->private_len = 0;
00311 for (;;)
00312 {
00313 error = read_pfb_tag( stream, &tag, &size );
00314 if ( error || tag != 0x8002U )
00315 {
00316 error = T1_Err_Ok;
00317 break;
00318 }
00319
00320 if ( FT_STREAM_READ( parser->private_dict + parser->private_len,
00321 size ) )
00322 goto Fail;
00323
00324 parser->private_len += size;
00325 }
00326 }
00327 else
00328 {
00329
00330
00331
00332
00333
00334
00335 FT_Byte* cur = parser->base_dict;
00336 FT_Byte* limit = cur + parser->base_len;
00337 FT_Byte c;
00338
00339
00340 Again:
00341 for (;;)
00342 {
00343 c = cur[0];
00344 if ( c == 'e' && cur + 9 < limit )
00345
00346 {
00347 if ( cur[1] == 'e' &&
00348 cur[2] == 'x' &&
00349 cur[3] == 'e' &&
00350 cur[4] == 'c' )
00351 break;
00352 }
00353 cur++;
00354 if ( cur >= limit )
00355 {
00356 FT_ERROR(( "T1_Get_Private_Dict:"
00357 " could not find `eexec' keyword\n" ));
00358 error = T1_Err_Invalid_File_Format;
00359 goto Exit;
00360 }
00361 }
00362
00363
00364
00365
00366 parser->root.cursor = parser->base_dict;
00367 parser->root.limit = cur + 9;
00368
00369 cur = parser->root.cursor;
00370 limit = parser->root.limit;
00371
00372 while ( cur < limit )
00373 {
00374 if ( *cur == 'e' && ft_strncmp( (char*)cur, "eexec", 5 ) == 0 )
00375 goto Found;
00376
00377 T1_Skip_PS_Token( parser );
00378 if ( parser->root.error )
00379 break;
00380 T1_Skip_Spaces ( parser );
00381 cur = parser->root.cursor;
00382 }
00383
00384
00385
00386
00387 cur = limit;
00388 limit = parser->base_dict + parser->base_len;
00389 goto Again;
00390
00391
00392
00393
00394
00395 Found:
00396 parser->root.limit = parser->base_dict + parser->base_len;
00397
00398 T1_Skip_PS_Token( parser );
00399 cur = parser->root.cursor;
00400
00401
00402
00403
00404
00405 while ( cur < limit &&
00406 ( *cur == ' ' ||
00407 *cur == '\t' ||
00408 *cur == '\r' ||
00409 *cur == '\n' ) )
00410 ++cur;
00411 if ( cur >= limit )
00412 {
00413 FT_ERROR(( "T1_Get_Private_Dict:"
00414 " `eexec' not properly terminated\n" ));
00415 error = T1_Err_Invalid_File_Format;
00416 goto Exit;
00417 }
00418
00419 size = parser->base_len - ( cur - parser->base_dict );
00420
00421 if ( parser->in_memory )
00422 {
00423
00424 if ( FT_ALLOC( parser->private_dict, size + 1 ) )
00425 goto Fail;
00426 parser->private_len = size;
00427 }
00428 else
00429 {
00430 parser->single_block = 1;
00431 parser->private_dict = parser->base_dict;
00432 parser->private_len = size;
00433 parser->base_dict = 0;
00434 parser->base_len = 0;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444 if ( ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) &&
00445 ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) )
00446 {
00447
00448 FT_Long len;
00449
00450
00451 parser->root.cursor = cur;
00452 (void)psaux->ps_parser_funcs->to_bytes( &parser->root,
00453 parser->private_dict,
00454 parser->private_len,
00455 &len,
00456 0 );
00457 parser->private_len = len;
00458
00459
00460 parser->private_dict[len] = '\0';
00461 }
00462 else
00463
00464 FT_MEM_MOVE( parser->private_dict, cur, size );
00465 }
00466
00467
00468 psaux->t1_decrypt( parser->private_dict, parser->private_len, 55665U );
00469
00470
00471 parser->private_dict[0] = ' ';
00472 parser->private_dict[1] = ' ';
00473 parser->private_dict[2] = ' ';
00474 parser->private_dict[3] = ' ';
00475
00476 parser->root.base = parser->private_dict;
00477 parser->root.cursor = parser->private_dict;
00478 parser->root.limit = parser->root.cursor + parser->private_len;
00479
00480 Fail:
00481 Exit:
00482 return error;
00483 }
00484
00485
00486