[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Devel] off-by-one-digit bug in ttinterp.c?
From: |
David Turner |
Subject: |
Re: [Devel] off-by-one-digit bug in ttinterp.c? |
Date: |
Sun, 18 Jul 2004 09:26:34 +0200 |
User-agent: |
Mozilla Thunderbird 0.5 (Windows/20040207) |
david mosberger wrote:
[I sent this mail from my home machine already but it was incorrectly rejected:
<address@hidden>: host mail.freetype.org[212.43.237.66] said: 554 Service
unavailable; [66.127.195.58] blocked using dul.dnsbl.sorbs.net, reason:
Dynamic IP Address See:
http://www.dnsbl.sorbs.net/cgi-bin/lookup?IP=66.127.195.58 (in reply to
RCPT TO command)
The black-list is wrong: IP address 66.127.195.58 is a FIXED IP address and the
mail shouldn't have been rejected...]
I believe you should send a notice to the SORBS admins, there is little thing
we can do at the FreeType site unless we want to play "security russian
roulette" :-)
Hi,
I have been experiencing long stalls on certain web-pages (such as
slashdot.org) when using mozilla on a Debian/ia64 box running
"testing". During the stalls, the CPU was 100% busy in a loop inside
the TrueType's ttinterp.c:Normalize() routine. If I understand that
code correctly, it's trying to normalize the vector length to 1.0
(scaled by 16384). However, there appears to be an off-by-one-digit
error in the error-correction code that follows the main scaling. In
particular, the code there says:
/* Now, we want that Sqrt( W ) = 0x4000 */
/* Or 0x1000000 <= W < 0x1004000 */
However, 0x4000 * 0x4000 = 0x10000000, so I think the condition should
be:
/* Or 0x10000000 <= W < 0x10004000 */
Indeed, if I apply the attached patch, the hangs in mozilla do disappear.
My, oh my, I really wonder why I didn't spot this before. This code has
been in the interpreter for so long. It's really a miracle that it doesn't
seem to affect rendering quality in any way.
Thanks a lot for spotting this problem. This is now fixed in the CVS
PS: Is there a particular reason not to use IEEE extended precision
(80-bit) arithmetic on platforms that have this available?
Particularly on ia64, that would be a lot faster than using
fixed-point arithmetic, since (general) 64-bit multiplication has
to be done in the floating-point unit anyhow.
There are particular reasons not to use floating points:
- the whole TrueType virtual machine is built around 26.6
fixed point arithmetic. And it is _extremely_ sensitive
to rounding bugs, i.e. I had to experiment a lot to
determine how to perform most computations to mimic the
original Apple/Microsoft code that most TrueType bytecode
depends on.
- a very common operation in the hinters (TrueType bytecode,
Type 1, or autohint), is to fit a value to the pixel grid,
i.e., something like:
x = (x+32) & ~63;
y = y & ~63;
z = (z+63) & ~63;
these operations are typically very slow with floating
points
- performance in lots of embedded systems would suck
If you want to experiment with floating points, try to
re-implement the functions FT_MulFix and FT_MulDiv with
them, since that's where most of the CPU spends it time
during glyph loading. This may make a big difference
on certain architectures.
Best Regards,
- David Turner
- The FreeType Project (www.freetype.org)
------------------------------------------------------------------------
--- freetype2/src/truetype/ttinterp.c-orig 2004-07-15 23:57:01.763595339
-0700
+++ freetype2/src/truetype/ttinterp.c 2004-07-15 23:57:27.806845483 -0700
@@ -2474,7 +2474,7 @@
W = Vx * Vx + Vy * Vy;
/* Now, we want that Sqrt( W ) = 0x4000 */
- /* Or 0x1000000 <= W < 0x1004000 */
+ /* Or 0x10000000 <= W < 0x10004000 */
if ( Vx < 0 )
{
@@ -2492,7 +2492,7 @@
else
S2 = FALSE;
- while ( W < 0x1000000L )
+ while ( W < 0x10000000L )
{
/* We need to increase W by a minimal amount */
if ( Vx < Vy )
@@ -2503,7 +2503,7 @@
W = Vx * Vx + Vy * Vy;
}
- while ( W >= 0x1004000L )
+ while ( W >= 0x10004000L )
{
/* We need to decrease W by a minimal amount */
if ( Vx < Vy )