freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ft-devel] cff driver bug


From: Jered Gray
Subject: [ft-devel] cff driver bug
Date: Thu, 7 Jan 2016 13:28:26 -0800

Hi,
I'm a member of a team at Google. We recently ran into a bug in the CFF driver where certain glyphs from a couple of the large Noto CJK font files failed to load. However, the bug only occurred in a specific build setting on a specific platform. I ended up tracking it down to cf2_interpT2CharString() in the cff driver.

The issue is that cf2_buf_readByte(), which produces side effects in its CF2_Buffer parameter, is being used in bitwise OR expressions within both the cf2_cmdEXTENDEDNMBR case and the default case. As a result of the side effects, the the operands must be evaluated in a left-to-right order, but that order is not guaranteed with the current logic. In the case where the bug was occurring, the compiler was evaluating them in a right-to-left order.

I'm including both the original code and the code we used to fix the bug:

1. case cf2_cmdEXTENDEDNMBR:

ORIGINAL:
          v = (FT_Short)( ( cf2_buf_readByte( charstring ) << 8 ) |
                                   cf2_buf_readByte( charstring )        );

MODIFIED:
          CF2_Int byte1 = cf2_buf_readByte( charstring );
          CF2_Int byte2 = cf2_buf_readByte( charstring );
          v = (FT_Short)( ( byte1 << 8 ) |
                                   byte2        );


2. default:

ORIGINAL
            v = (CF2_Fixed)
                  ( ( (FT_UInt32)cf2_buf_readByte( charstring ) << 24 ) |
                    ( (FT_UInt32)cf2_buf_readByte( charstring ) << 16 ) |
                    ( (FT_UInt32)cf2_buf_readByte( charstring ) <<  8 ) |
                      (FT_UInt32)cf2_buf_readByte( charstring )         );

MODIFIED:
            FT_UInt32 byte1 = (FT_UInt32)cf2_buf_readByte( charstring );
            FT_UInt32 byte2 = (FT_UInt32)cf2_buf_readByte( charstring );
            FT_UInt32 byte3 = (FT_UInt32)cf2_buf_readByte( charstring );
            FT_UInt32 byte4 = (FT_UInt32)cf2_buf_readByte( charstring );
            v = (CF2_Fixed)
                  ( ( byte1 << 24 ) |
                    ( byte2 << 16 ) |
                    ( byte3 <<  8 ) |
                      byte4         );


Best,
Jered

reply via email to

[Prev in Thread] Current Thread [Next in Thread]