summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorParth Wazurkar <parthwazurkar@gmail.com>2018-12-20 23:36:05 +0530
committerParth Wazurkar <parthwazurkar@gmail.com>2018-12-20 23:36:05 +0530
commitd64bad545a2fbf34a76d7aca6404bc47f0d8af3c (patch)
tree2778adf2d5cdf0fa85f7326b8810d413b431d583
parent75fd199d708b29af35ce74d98826e9242dbaf4e7 (diff)
downloadfreetype2-parthw-pk-vf.tar.gz
[tfm] Fixes.parthw-pk-vf
-rw-r--r--include/freetype/internal/tfm.h41
-rw-r--r--src/tfm/tfmmod.c9
-rw-r--r--src/tfm/tfmobjs.c269
3 files changed, 137 insertions, 182 deletions
diff --git a/include/freetype/internal/tfm.h b/include/freetype/internal/tfm.h
index 6478344d5..1a91eb497 100644
--- a/include/freetype/internal/tfm.h
+++ b/include/freetype/internal/tfm.h
@@ -46,19 +46,21 @@ FT_BEGIN_HEADER
typedef struct TFM_FontInfoRec_
{
/* Font Info */
- FT_ULong cs;
+ FT_Long cs; /* Check Sum */
/* Metrics */
FT_ULong ds, fs; /* Design Size */
FT_UInt design_size;
- FT_UInt slant;
+ FT_ULong slant;
FT_UInt begin_char, end_char;
FT_Long *width, *height, *depth;
/* Font bounding box */
- FT_UInt font_bbx_w, font_bbx_h;
- FT_UInt font_bbx_xoff, font_bbx_yoff;
+ FT_Long font_bbx_w, font_bbx_h;
+ FT_Long font_bbx_xoff, font_bbx_yoff;
} TFM_FontInfoRec, *TFM_FontInfo;
+ #define RDS2PT(rds) (tfm->design_size * ((FT_Long)(rds)/(FT_Long)(1<<20)))
+
/*************************************************************************/
/*************************************************************************/
/***** *****/
@@ -69,6 +71,23 @@ FT_BEGIN_HEADER
typedef struct TFM_ParserRec_* TFM_Parser;
+ typedef struct TFM_Parser_FuncsRec_
+ {
+ FT_Error
+ (*init)( TFM_Parser parser,
+ FT_Memory memory,
+ FT_Stream stream );
+
+ FT_Error
+ (*parse_metrics)( TFM_Parser parser );
+
+ void
+ (*done)( TFM_Parser parser );
+
+ } TFM_Parser_FuncsRec;
+
+
+
/**************************************************************************
*
* @struct:
@@ -110,19 +129,7 @@ FT_BEGIN_HEADER
typedef struct TFM_ServiceRec_
{
- FT_Error
- (*init)( TFM_Parser parser,
- FT_Memory memory,
- FT_Stream stream );
-
- FT_Error
- (*parse_metrics)( TFM_Parser parser );
-
- FT_Error
- (*parse_kern)( TFM_Parser parser );
-
- void
- (*done)( TFM_Parser parser );
+ const TFM_Parser_FuncsRec* tfm_parser_funcs;
} TFM_ServiceRec, *TFM_Service;
diff --git a/src/tfm/tfmmod.c b/src/tfm/tfmmod.c
index f987fa4f4..c4e882543 100644
--- a/src/tfm/tfmmod.c
+++ b/src/tfm/tfmmod.c
@@ -21,14 +21,19 @@
#include "tfmobjs.h"
- static
- const TFM_Interface tfm_interface =
+ FT_CALLBACK_TABLE_DEF
+ const TFM_Parser_FuncsRec tfm_parser_funcs =
{
tfm_init, /* init */
tfm_parse_metrics, /* parse metrics */
tfm_close, /* done */
};
+ static
+ const TFM_Interface tfm_interface =
+ {
+ &tfm_parser_funcs,
+ };
FT_CALLBACK_TABLE_DEF
const FT_Module_Class tfm_module_class =
diff --git a/src/tfm/tfmobjs.c b/src/tfm/tfmobjs.c
index 35c8ff4af..277b5ce80 100644
--- a/src/tfm/tfmobjs.c
+++ b/src/tfm/tfmobjs.c
@@ -39,8 +39,16 @@
#undef FT_COMPONENT
#define FT_COMPONENT trace_tfmobjs
+ /**************************************************************************
+ *
+ * Global TFM parameters.
+ *
+ */
+#define tfm_size 30000 /* maximum length of tfm data, in bytes */
+#define lig_size 5000 /* maximum length of lig kern program, in words */
+#define hash_size 5003
- /**************************************************************************
+ /**************************************************************************
*
* TFM font utility functions.
*
@@ -49,8 +57,9 @@
long tfm_read_intn(FT_Stream,int);
unsigned long tfm_read_uintn(FT_Stream,int);
-#define READ_UINT2( stream ) (FT_Byte)tfm_read_uintn( stream, 2)
-#define READ_UINT4( stream ) (FT_Byte)tfm_read_uintn( stream, 4)
+#define READ_UINT1( stream ) (FT_ULong)tfm_read_uintn( stream, 1)
+#define READ_UINT2( stream ) (FT_ULong)tfm_read_uintn( stream, 2)
+#define READ_UINT4( stream ) (FT_ULong)tfm_read_uintn( stream, 4)
#define READ_INT4( stream ) (FT_Long)tfm_read_intn( stream, 4)
/*
@@ -66,7 +75,7 @@
while (size >= 1)
{
if ( FT_READ_BYTE(tp) )
- return 0; /* To be changed */
+ return 0;
k =(unsigned long)tp;
v = v*256L + k;
--size;
@@ -82,7 +91,7 @@
FT_Error error= FT_Err_Ok;
unsigned long z ;
if ( FT_READ_BYTE(tp) )
- return 0; /* To be changed */
+ return 0;
z= (unsigned long)tp;
v = (long)z & 0xffL;
if (v & 0x80L)
@@ -91,7 +100,7 @@
while (size >= 1)
{
if ( FT_READ_BYTE(tp) )
- return 0; /* To be changed */
+ return 0;
z= (unsigned long)tp;
v = v*256L + z;
--size;
@@ -122,9 +131,9 @@
FT_LOCAL( void )
tfm_close( TFM_Parser parser )
{
- FT_Memory memory = parser->memory;
+ FT_UNUSED( parser );
- FT_FREE( parser->stream );
+ /* nothing */
}
@@ -137,8 +146,8 @@
FT_Error error = FT_ERR( Syntax_Error );
FT_ULong lf, lh, nc, nci;
- FT_ULong offset_header, offset_char_info, offset_param;
- FT_ULong nw, nh, nd, ni, nl, nk, neng, np;
+ FT_ULong offset_char_info, offset_param;
+ FT_ULong nw, nh, nd, ni, nl, nk, ne, np, bc, ec;
FT_Long *w, *h, *d;
FT_ULong *ci, v;
@@ -162,121 +171,109 @@
fi->font_bbx_xoff = 0.0;
fi->font_bbx_yoff = 0.0;
- /* rewind(fp); */
if( FT_STREAM_SEEK( 0 ) )
return error;
- lf = (FT_ULong)READ_UINT2( stream );
- fi->fs = 4*lf - 1 ;
+ /* Checking the correctness of the TFM file */
+ if( READ_UINT1( stream ) > 127 )
+ {
+ FT_ERROR(( "Malformed TFM file: The first byte of the input file exceeds 127!\n" ));
+ error = FT_THROW( Unknown_File_Format );
+ goto Exit;
+ }
+
+ if( FT_STREAM_SEEK( 0 ) )
+ return error;
- #if 0
- if ((lf == 11) || (lf == 9))
+ lf = READ_UINT2( stream );
+ lh = READ_UINT2( stream );
+ bc = READ_UINT2( stream );
+ ec = READ_UINT2( stream );
+ nw = READ_UINT2( stream );
+ nh = READ_UINT2( stream );
+ nd = READ_UINT2( stream );
+ ni = READ_UINT2( stream );
+ nl = READ_UINT2( stream );
+ nk = READ_UINT2( stream );
+ ne = READ_UINT2( stream );
+ np = READ_UINT2( stream );
+
+ /* Uncomment this to check for the tfm file's header info if this program returns malformed tfm file */
+ /*
+ FT_TRACE6(( "tfm_parse_metrics: First 24 bytes in the tfm file:\n"
+ " lf : %ld\n"
+ " lh : %ld\n"
+ " bc : %d\n"
+ " ec : %d\n"
+ " nw : %d\n"
+ " nh : %d\n"
+ " nd : %d\n"
+ " ni : %d\n"
+ " nl : %d\n"
+ " nk : %d\n"
+ " ne : %d\n"
+ " np : %d\n", lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np ));
+ */
+
+ if( lf == 0 || ((4*lf) - 1) > tfm_size)
{
- /* JFM file of Japanese TeX by ASCII Coop. */
- tfm->type = METRIC_TYPE_JFM;
- tfm->type_aux = (lf == 11)?METRIC_TYPE_JFM_AUX_H:METRIC_TYPE_JFM_AUX_V;
- tfm->nt = (FT_ULong)READ_UINT2(fp);
- lf = (FT_ULong)READ_UINT2(fp);
- lh = (FT_ULong)READ_UINT2(fp);
- offset_header = 4*7;
- offset_char_info = 4*(7+tfm->nt+lh);
+ FT_ERROR(( "Malformed TFM file: The file claims to have length zero, but that's impossible!\n" ));
+ error = FT_THROW( Unknown_File_Format );
+ goto Exit;
}
- else if (lf == 0)
+
+ if(lh < 2)
{
- /* Omega Metric File */
- tfm->type = METRIC_TYPE_OFM;
- tfm->type_aux = READ_INT2(fp); /* ofm_level */
- if ((tfm->type_aux < 0) || (1 < tfm->type_aux))
- tfm->type_aux = 0; /* broken, maybe */
- lf = READ_UINT4(fp);
- lh = READ_UINT4(fp);
- if (tfm->type_aux == 0)
- { /* level 0 OFM */
- offset_header = 4*14;
- offset_char_info = 4*(14+lh);
- }
- else
- { /* level 1 OFM: *** NOT SUPPORTED YET *** */
- offset_header = 4*29;
- offset_char_info = 4*(29+lh);
- }
+ FT_ERROR(( "Malformed TFM file: The header length is only %ld\n",lh ));
+ error = FT_THROW( Unknown_File_Format );
+ goto Exit;
}
- else
- { }
- #endif
- /* Traditional TeX Metric File */
- lh = (int)READ_UINT2( stream );
- offset_header = 4*6;
- offset_char_info = 4*(6+lh);
+ if( nl > lig_size )
+ {
+ FT_ERROR(( "Malformed TFM file: The lig/kern program is longer than I can handle!\n" ));
+ error = FT_THROW( Unknown_File_Format );
+ goto Exit;
+ }
- #if 0
- if (tfm->type == METRIC_TYPE_OFM)
+ if( ne > 256 )
{
- tfm->begin_char = READ_UINT4(fp);
- tfm->end_char = READ_UINT4(fp);
- nw = READ_UINT4(fp);
- nh = READ_UINT4(fp);
- nd = READ_UINT4(fp);
-
- ni = READ_UINT4(fp);
- nl = READ_UINT4(fp);
- nk = READ_UINT4(fp);
- neng = READ_UINT4(fp);
- np = READ_UINT4(fp);
- dir = READ_UINT4(fp);
-
- if (((signed)(tfm->begin_char-1) > (signed)tfm->end_char) ||
- (tfm->end_char > 65535))
- {
- error = FT_THROW( Invalid_Argument );
- goto Exit;
- }
+ FT_ERROR(( "Malformed TFM file: There are %ld extensible recipes!\n",ne ));
+ error = FT_THROW( Unknown_File_Format );
+ goto Exit;
}
- else
- { }
- #endif
-
- fi->begin_char = (int)READ_UINT2( stream );
- fi->end_char = (int)READ_UINT2( stream );
-
- nw = (FT_ULong)READ_UINT2( stream );
- nh = (FT_ULong)READ_UINT2( stream );
- nd = (FT_ULong)READ_UINT2( stream );
-
- ni = (FT_ULong)READ_UINT2( stream );
- nl = (FT_ULong)READ_UINT2( stream );
- nk = (FT_ULong)READ_UINT2( stream );
- neng = (FT_ULong)READ_UINT2( stream );
- np = (FT_ULong)READ_UINT2( stream );
-
- #if 0
- if (tfm->type == METRIC_TYPE_TFM)
- {}
- #endif
- if (((signed)(fi->begin_char-1) > (signed)fi->end_char) ||
- (fi->end_char > 255))
+
+ if ( ((signed)(fi->begin_char-1) > (signed)fi->end_char) ||
+ ( fi->end_char > 255) ||
+ ( ne > 256 ) )
{
- error = FT_THROW( Invalid_Argument );
+ FT_ERROR(( "tfm_parse_metrics: Incorrect header information in `tfm' file.\n" ));
+ error = FT_THROW( Unknown_File_Format );
goto Exit;
}
- /* fseek(fp, offset_header, SEEK_SET); */
- if (FT_STREAM_SEEK( offset_header ) )
+ if ( lf != 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np )
+ {
+ FT_ERROR(( "tfm_parse_metrics: Incorrect header information in `tfm' file.\n" ));
+ error = FT_THROW( Unknown_File_Format );
goto Exit;
- fi->cs = READ_UINT4( stream ); /* Check Sum */
- fi->ds = READ_UINT4( stream ); /* Design Size */
+ }
+ fi->begin_char = bc;
+ fi->end_char = ec;
+ fi->cs = READ_INT4( stream ); /* Check Sum */
+ fi->ds = READ_INT4( stream ); /* Design Size */
fi->design_size = (FT_ULong)((double)(fi->ds)/(double)(1<<20));
+ if( fi->cs <= 0 )
+ {
+ error = FT_THROW( Unknown_File_Format );
+ goto Exit;
+ }
+
nc = fi->end_char - fi->begin_char + 1;
nci = nc;
- #if 0
- if (tfm->type == METRIC_TYPE_OFM)
- nci *= 2;
- #endif
-
ci = (FT_ULong*)calloc(nci, sizeof(FT_ULong));
w = (FT_Long*)calloc(nw, sizeof(FT_ULong));
h = (FT_Long*)calloc(nh, sizeof(FT_ULong));
@@ -288,15 +285,14 @@
goto Exit;
}
- /* fseek(fp, offset_char_info, SEEK_SET); */
+ offset_char_info = 4*(6+lh);
if( FT_STREAM_SEEK( offset_char_info ) ) /* Skip over coding scheme and font family name */
goto Exit;
for (i = 0; i < nci; i++)
ci[i] = READ_UINT4( stream );
- /* offset_param = ftell(fp) + 4*(nw + nh + nd + ni + nl + nk + neng); */
- offset_param = stream->pos + 4*(nw + nh + nd + ni + nl + nk + neng);
+ offset_param = stream->pos + 4*(nw + nh + nd + ni + nl + nk + ne);
for (i = 0; i < nw; i++)
w[i] = READ_INT4( stream );
@@ -320,33 +316,6 @@
xoff = 0;
yoff = 0;
- #if 0
- if (tfm->type == METRIC_TYPE_OFM)
- {
- for (i = 0; i < nc; i++)
- {
- v = ci[2*i];
- tfm->depth[i] = d[v & 0xff]; v >>= 8;
- tfm->height[i] = h[v & 0xff]; v >>= 8;
- tfm->width[i] = w[v & 0xffff];
- if (bbxw < tfm->width[i])
- bbxw = tfm->width[i];
- if (bbxh < (tfm->height[i] + tfm->depth[i]))
- bbxh = tfm->height[i] + tfm->depth[i];
- if (yoff > -tfm->depth[i])
- yoff = -tfm->depth[i];
- #if 0
- printf("** %.3f %.3f %.3f\n",
- (double)tfm->width[i]/(double)(1<<20),
- (double)tfm->height[i]/(double)(1<<20),
- (double)tfm->depth[i]/(double)(1<<20));
- #endif
- }
- }
- else
- { }
- #endif
-
for (i = 0; i < nc; i++)
{
v = ci[i] / 0x10000L;
@@ -369,43 +338,17 @@
fi->font_bbx_xoff = (FT_ULong)(fi->design_size * ((double)xoff / (double)(1<<20)));
fi->font_bbx_yoff = (FT_ULong)(fi->design_size * ((double)yoff / (double)(1<<20)));
- #if 0
- if (tfm->type == METRIC_TYPE_JFM)
- {
- fseek(fp, 4*(7+lh), SEEK_SET);
- tfm->ct_kcode = (unsigned int*)calloc(tfm->nt+1, sizeof(unsigned int));
- tfm->ct_ctype = (unsigned int*)calloc(tfm->nt+1, sizeof(unsigned int));
- if ((tfm->ct_kcode == NULL) || (tfm->ct_ctype == NULL))
- {
- error = FT_THROW( Invalid_Argument );
- goto Exit;
- }
- for (i = 0; i < tfm->nt; i++)
- {
- v = READ_UINT4(fp);
- tfm->ct_kcode[i] = v/0x10000L;
- tfm->ct_ctype[i] = v%0x10000L;
- }
- tfm->ct_kcode[tfm->nt] = 0; /* sentinel */
- tfm->ct_ctype[tfm->nt] = 0;
- }
- #endif
-
- /* fseek(fp, offset_param, SEEK_SET); */
if( FT_STREAM_SEEK( offset_param ) )
- return error; /* To be changed */
+ return error;
if (FT_READ_ULONG(fi->slant) )
return error;
fi->slant = (FT_ULong)((double)fi->slant/(double)(1<<20));
Exit:
- if( !ci || !w || !h || !d )
- {
- FT_FREE(ci);
- FT_FREE(w);
- FT_FREE(h);
- FT_FREE(d);
- }
+ FT_FREE(ci);
+ FT_FREE(w);
+ FT_FREE(h);
+ FT_FREE(d);
return error;
}