зеркало из https://github.com/stride3d/freetype.git
[truetype] Fix Savannah bug #35466.
Jump instructions are now bound to the current function. The MS Windows rasterizer behaves the same, as confirmed by Greg Hitchcock. * src/truetype/ttinterp.h (TT_CallRec): Add `Cur_End' element. * src/truetype/ttobjs.h (TT_DefRecord): Add `end' element. * src/truetype/ttinterp.c (DO_JROT, DO_JMPR, DO_JROF): Check upper bound of jump address. (Ins_FDEF, Ins_CALL, Ins_LOOPCALL, Ins_UNKNOWN, TT_RunIns): Updated.
This commit is contained in:
Родитель
185606a64d
Коммит
b4e06818ed
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2012-02-11 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[truetype] Fix Savannah bug #35466.
|
||||
|
||||
Jump instructions are now bound to the current function. The MS
|
||||
Windows rasterizer behaves the same, as confirmed by Greg Hitchcock.
|
||||
|
||||
* src/truetype/ttinterp.h (TT_CallRec): Add `Cur_End' element.
|
||||
* src/truetype/ttobjs.h (TT_DefRecord): Add `end' element.
|
||||
|
||||
* src/truetype/ttinterp.c (DO_JROT, DO_JMPR, DO_JROF): Check upper
|
||||
bound of jump address.
|
||||
(Ins_FDEF, Ins_CALL, Ins_LOOPCALL, Ins_UNKNOWN, TT_RunIns): Updated.
|
||||
|
||||
2012-02-11 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
We don't use `extensions'.
|
||||
|
|
|
@ -715,7 +715,7 @@
|
|||
FT_Error error;
|
||||
|
||||
|
||||
if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) )
|
||||
if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) )
|
||||
!= TT_Err_Ok )
|
||||
return error;
|
||||
|
||||
|
@ -1800,7 +1800,7 @@
|
|||
|
||||
/* NOTE: Because the last instruction of a program may be a CALL */
|
||||
/* which will return to the first byte *after* the code */
|
||||
/* range, we test for AIP <= Size, instead of AIP < Size. */
|
||||
/* range, we test for aIP <= Size, instead of aIP < Size. */
|
||||
|
||||
if ( aIP > range->size )
|
||||
{
|
||||
|
@ -2757,7 +2757,7 @@
|
|||
W = Vx * Vx + Vy * Vy;
|
||||
|
||||
/* Now, we want that Sqrt( W ) = 0x4000 */
|
||||
/* Or 0x10000000 <= W < 0x10004000 */
|
||||
/* Or 0x10000000 <= W < 0x10004000 */
|
||||
|
||||
if ( Vx < 0 )
|
||||
{
|
||||
|
@ -3199,36 +3199,42 @@
|
|||
}
|
||||
|
||||
|
||||
#define DO_JROT \
|
||||
if ( args[1] != 0 ) \
|
||||
{ \
|
||||
if ( args[0] == 0 && CUR.args == 0 ) \
|
||||
CUR.error = TT_Err_Bad_Argument; \
|
||||
CUR.IP += args[0]; \
|
||||
if ( CUR.IP < 0 ) \
|
||||
CUR.error = TT_Err_Bad_Argument; \
|
||||
CUR.step_ins = FALSE; \
|
||||
#define DO_JROT \
|
||||
if ( args[1] != 0 ) \
|
||||
{ \
|
||||
if ( args[0] == 0 && CUR.args == 0 ) \
|
||||
CUR.error = TT_Err_Bad_Argument; \
|
||||
CUR.IP += args[0]; \
|
||||
if ( CUR.IP < 0 || \
|
||||
( CUR.callTop > 0 && \
|
||||
CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
|
||||
CUR.error = TT_Err_Bad_Argument; \
|
||||
CUR.step_ins = FALSE; \
|
||||
}
|
||||
|
||||
|
||||
#define DO_JMPR \
|
||||
if ( args[0] == 0 && CUR.args == 0 ) \
|
||||
CUR.error = TT_Err_Bad_Argument; \
|
||||
CUR.IP += args[0]; \
|
||||
if ( CUR.IP < 0 ) \
|
||||
CUR.error = TT_Err_Bad_Argument; \
|
||||
#define DO_JMPR \
|
||||
if ( args[0] == 0 && CUR.args == 0 ) \
|
||||
CUR.error = TT_Err_Bad_Argument; \
|
||||
CUR.IP += args[0]; \
|
||||
if ( CUR.IP < 0 || \
|
||||
( CUR.callTop > 0 && \
|
||||
CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
|
||||
CUR.error = TT_Err_Bad_Argument; \
|
||||
CUR.step_ins = FALSE;
|
||||
|
||||
|
||||
#define DO_JROF \
|
||||
if ( args[1] == 0 ) \
|
||||
{ \
|
||||
if ( args[0] == 0 && CUR.args == 0 ) \
|
||||
CUR.error = TT_Err_Bad_Argument; \
|
||||
CUR.IP += args[0]; \
|
||||
if ( CUR.IP < 0 ) \
|
||||
CUR.error = TT_Err_Bad_Argument; \
|
||||
CUR.step_ins = FALSE; \
|
||||
#define DO_JROF \
|
||||
if ( args[1] == 0 ) \
|
||||
{ \
|
||||
if ( args[0] == 0 && CUR.args == 0 ) \
|
||||
CUR.error = TT_Err_Bad_Argument; \
|
||||
CUR.IP += args[0]; \
|
||||
if ( CUR.IP < 0 || \
|
||||
( CUR.callTop > 0 && \
|
||||
CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
|
||||
CUR.error = TT_Err_Bad_Argument; \
|
||||
CUR.step_ins = FALSE; \
|
||||
}
|
||||
|
||||
|
||||
|
@ -4640,6 +4646,7 @@
|
|||
return;
|
||||
|
||||
case 0x2D: /* ENDF */
|
||||
rec->end = CUR.IP;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -4757,6 +4764,7 @@
|
|||
pCrec->Caller_IP = CUR.IP + 1;
|
||||
pCrec->Cur_Count = 1;
|
||||
pCrec->Cur_Restart = def->start;
|
||||
pCrec->Cur_End = def->end;
|
||||
|
||||
CUR.callTop++;
|
||||
|
||||
|
@ -4835,6 +4843,7 @@
|
|||
pCrec->Caller_IP = CUR.IP + 1;
|
||||
pCrec->Cur_Count = (FT_Int)args[0];
|
||||
pCrec->Cur_Restart = def->start;
|
||||
pCrec->Cur_End = def->end;
|
||||
|
||||
CUR.callTop++;
|
||||
|
||||
|
@ -7173,6 +7182,7 @@
|
|||
call->Caller_IP = CUR.IP + 1;
|
||||
call->Cur_Count = 1;
|
||||
call->Cur_Restart = def->start;
|
||||
call->Cur_End = def->end;
|
||||
|
||||
INS_Goto_CodeRange( def->range, def->start );
|
||||
|
||||
|
@ -8181,6 +8191,7 @@
|
|||
callrec->Caller_IP = CUR.IP + 1;
|
||||
callrec->Cur_Count = 1;
|
||||
callrec->Cur_Restart = def->start;
|
||||
callrec->Cur_End = def->end;
|
||||
|
||||
if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE )
|
||||
goto LErrorLabel_;
|
||||
|
|
|
@ -102,6 +102,7 @@ FT_BEGIN_HEADER
|
|||
FT_Long Caller_IP;
|
||||
FT_Long Cur_Count;
|
||||
FT_Long Cur_Restart;
|
||||
FT_Long Cur_End;
|
||||
|
||||
} TT_CallRec, *TT_CallStack;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/* */
|
||||
/* Objects manager (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2009, 2011 by */
|
||||
/* Copyright 1996-2009, 2011-2012 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
|
@ -175,6 +175,7 @@ FT_BEGIN_HEADER
|
|||
{
|
||||
FT_Int range; /* in which code range is it located? */
|
||||
FT_Long start; /* where does it start? */
|
||||
FT_Long end; /* where does it end? */
|
||||
FT_UInt opc; /* function #, or instruction code */
|
||||
FT_Bool active; /* is it active? */
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче