예제 #1
0
        private static bool IsFormatV1(ReadOnlySpan <byte> buffer, out Endianness endianness)
        {
            endianness = Endianness.Little;

            // Need at least 256 bytes
            if (buffer.Length < 256)
            {
                return(false);
            }

            if (buffer[0] == 0)
            {
                // First byte is zero.
                // V1 not an option, as it would make for an invalid entry name
                // V2-3 are not an option either, as it would mean the entry count is 0
                // Either invalid, or big endian
                return(false);
            }

            bool nameTerminated = false;

            for (int i = 0; i < 252; i++)
            {
                if (buffer[i] == 0)
                {
                    nameTerminated = true;
                }

                // If the name has already been terminated but there's still data in the reserved space,
                // fail the test
                if (nameTerminated && buffer[i] != 0)
                {
                    return(false);
                }
            }

            var length = BinaryPrimitives.ReadInt32LittleEndian(buffer.Slice(252));

            if (length < 0 || length >= MAX_LENGTH_SANITY_VALUE)
            {
                BinaryOperations <int> .Reverse(ref length);

                if (length < 0 || length >= MAX_LENGTH_SANITY_VALUE)
                {
                    return(false);
                }

                endianness = Endianness.Big;
            }

            return(true);
        }
예제 #2
0
        private static bool IsFormatV2OrV3(ReadOnlySpan <byte> buffer, int entrySize, out Endianness endianness)
        {
            endianness = Endianness.Little;

            // Need at least a full entry
            if (buffer.Length < 4 + entrySize)
            {
                return(false);
            }

            var entryCount = BinaryPrimitives.ReadInt32LittleEndian(buffer);

            if (entryCount <= 0 || entryCount > 1024)
            {
                BinaryOperations <int> .Reverse(ref entryCount);

                if (entryCount <= 0 || entryCount > 1024)
                {
                    return(false);
                }

                endianness = Endianness.Big;
            }

            // check if the name field is correct
            if (buffer[4] == 0)
            {
                return(false);
            }

            var nameTerminated = false;

            for (int i = 0; i < (entrySize - 4); i++)
            {
                if (buffer[4 + i] == 0x00)
                {
                    nameTerminated = true;
                }
                else if (nameTerminated)
                {
                    return(false);
                }
            }

            // Data length sanity check
            var length = BinaryPrimitives.ReadInt32LittleEndian(buffer.Slice(4 + entrySize - 4));

            if (length < 0 || length >= MAX_LENGTH_SANITY_VALUE)
            {
                BinaryOperations <int> .Reverse(ref length);

                if (length < 0 || length >= MAX_LENGTH_SANITY_VALUE)
                {
                    return(false);
                }

                endianness = Endianness.Big;
            }

            return(true);
        }