Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

woff2 read header error did not specify the use of big-endian #234

Open
emako opened this issue Dec 30, 2024 · 0 comments
Open

woff2 read header error did not specify the use of big-endian #234

emako opened this issue Dec 30, 2024 · 0 comments

Comments

@emako
Copy link

emako commented Dec 30, 2024

See https://www.w3.org/TR/2024/REC-WOFF2-20240808/

3.1. Data types

Data Types
UInt8 8-bit unsigned integer.
Int16 16-bit signed integer in 2's complement format, stored big-endian.
UInt16 16-bit unsigned integer, stored big-endian.
UInt32 32-bit unsigned integer, stored big-endian.
255UInt16 Variable-length encoding of a 16-bit unsigned integer for optimized intermediate font data storage.
UIntBase128 Variable-length encoding of 32-bit unsigned integers.

But the method in Woff2Header ReadHeader(BinaryReader reader) did not specify the use of big-endian

The fixed code should be like it:

        Woff2Header ReadHeader(BinaryReader reader)
        {
            //WOFF2 Header
            //UInt32  signature             0x774F4632 'wOF2'
            //UInt32  flavor                The "sfnt version" of the input font.
            //UInt32  length                Total size of the WOFF file.
            //UInt16  numTables             Number of entries in directory of font tables.
            //UInt16  reserved              Reserved; set to 0.
            //UInt32  totalSfntSize         Total size needed for the uncompressed font data, including the sfnt header,
            //                              directory, and font tables(including padding).
            //UInt32  totalCompressedSize   Total length of the compressed data block.
            //UInt16  majorVersion          Major version of the WOFF file.
            //UInt16  minorVersion          Minor version of the WOFF file.
            //UInt32  metaOffset            Offset to metadata block, from beginning of WOFF file.
            //UInt32  metaLength            Length of compressed metadata block.
            //UInt32  metaOrigLength        Uncompressed size of metadata block.
            //UInt32  privOffset            Offset to private data block, from beginning of WOFF file.
            //UInt32  privLength            Length of private data block.

            Woff2Header header = new Woff2Header();
            byte b0 = reader.ReadByte();
            byte b1 = reader.ReadByte();
            byte b2 = reader.ReadByte();
            byte b3 = reader.ReadByte();
            if (!(b0 == 0x77 && b1 == 0x4f && b2 == 0x46 && b3 == 0x32))
            {
                return null;
            }

            header.flavor = reader.ReadUInt32BE(); // sfnt version
            string flavorName = Utils.TagToString(header.flavor);

            header.length = reader.ReadUInt32BE();
            header.numTables = reader.ReadUInt16BE();
            ushort reserved = reader.ReadUInt16BE();
            header.totalSfntSize = reader.ReadUInt32BE();
            header.totalCompressedSize = reader.ReadUInt32BE();

            header.majorVersion = reader.ReadUInt16BE();
            header.minorVersion = reader.ReadUInt16BE();

            header.metaOffset = reader.ReadUInt32BE();
            header.metaLength = reader.ReadUInt32BE();
            header.metaOriginalLength = reader.ReadUInt32BE();

            header.privOffset = reader.ReadUInt32BE();
            header.privLength = reader.ReadUInt32BE();

            return header;
        }


internal static class BinaryReaderExtensions
{
    public static ushort ReadUInt16BE(this BinaryReader reader)
    {
        byte[] bytes = reader.ReadBytes(2);
        return (ushort)((bytes[0] << 8) | bytes[1]);
    }

    public static uint ReadUInt32BE(this BinaryReader reader)
    {
        byte[] bytes = reader.ReadBytes(4);
        return (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);
    }
}
@emako emako changed the title woff2 read header error 没有指定使用 big-endian woff2 read header error did not specify the use of big-endian Dec 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant