您的位置:首页 > 编程语言

一个用了两年多的lzo压缩代码,竟然有问题.

2017-08-04 13:33 232 查看
一个短短的lzo代码,我使用了两年

今天才发现它有问题,我平时也用zlib和7zip的压缩

这两天编译64位版本,lzo运行就直接崩了,发现它没有考虑到数据类型,并且,它竟然没有初始化应该初始化的数据!

#include "lzo.h"

UINT _do_compress(BYTE *in, UINT in_len, BYTE *out, UINT *out_len, BYTE *buffer)

{

    BYTE *ip;

    BYTE *op;

    BYTE *in_end = in + in_len;

    BYTE *ip_end = in + in_len - 13;

    BYTE *ii;

    UINT *dict = (UINT *)buffer;

    BYTE *p;    // xy添加的

    UINT m_pos;

    UINT m_off;

    UINT m_len;

    UINT dindex;

    UINT t;

    UINT tt;

    BYTE *end;

    BYTE *m;

    op = out;

    ip = in;

    ii = ip;

    ip += 4;

    for (t = 0; t < 0x4000; t++)

    {

        dict[t] = 0xffffffff;

    }

    for (;;)

    {

        dindex = ((0x21 * (((((((UINT)(ip[3]) << 6) ^ ip[2]) << 5) ^ ip[1]) << 5) ^ ip[0])) >> 5) & 0x3fff;

        m_pos = dict[dindex];

        if (m_pos == 0xffffffff || (m_off = (UINT)(ip - in - m_pos)) == 0 || m_off > 0xbfff)

            goto literal;

        p = in + m_pos;

        if (m_off <= 0x0800 || p[3] == ip[3])

            goto try_match;

        dindex = (dindex & 0x7ff) ^ 0x201f;

        m_pos = dict[dindex];

        if (m_pos == 0xffffffff || (m_off = (UINT)(ip - in - m_pos)) == 0 || m_off > 0xbfff)

            goto literal;

        p = in + m_pos;

        if (m_off <= 0x0800 || p[3] == ip[3])

            goto try_match;

        goto literal;

    try_match:

        p = in + m_pos;

        if (*(USHORT*)p == *(USHORT *)ip && p[2] == ip[2])

            goto match;

        literal:

        dict[dindex] = ip - in;

        ++ip;

        if (ip >= ip_end)

            break;

        continue;

    match:

        dict[dindex] = ip - in;

        if (ip - ii > 0)

        {

            t = ip - ii;

            if (t <= 3)

            {

                op[-2] |= (BYTE)t;

            }

            else if (t <= 18)

            {

                *op++ = (BYTE)(t - 3);

            }

            else

            {

                tt = t - 18;

                *op++ = 0;

                while (tt > 255)

                {

                    tt -= 255;

                    *op++ = 0;

                }

                *op++ = (BYTE)tt;

            }

            do *op++ = *ii++; while (--t > 0);

        }

        ip += 3;

        p = in + m_pos;

        if (p[3] != *ip++ || p[4] != *ip++ || p[5] != *ip++ ||

            p[6] != *ip++ || p[7] != *ip++ || p[8] != *ip++)

        {

            --ip;

            m_len = ip - ii;

            if (m_off <= 0x0800)

            {

                --m_off;

                *op++ = (BYTE)(((m_len - 1) << 5) | ((m_off & 7) << 2));

                *op++ = (BYTE)(m_off >> 3);

            }

            else

                if (m_off <= 0x4000)

                {

                    --m_off;

                    *op++ = (BYTE)(32 | (m_len - 2));

                    goto m3_m4_offset;

                }

                else

                {

                    m_off -= 0x4000;

                    *op++ = (BYTE)(16 | ((m_off & 0x4000) >> 11) | (m_len - 2));

                    goto m3_m4_offset;

                }

        }

        else

        {

            {

                end = in_end;

                m = p + 9;

                while (ip < end && *m == *ip)

                    m++, ip++;

                m_len = (ip - ii);

            }

            if (m_off <= 0x4000)

            {

                --m_off;

                if (m_len <= 33)

                    *op++ = (BYTE)(32 | (m_len - 2));

                else

                {

                    m_len -= 33;

                    *op++ = 32;

                    goto m3_m4_len;

                }

            }

            else

            {

                m_off -= 0x4000;

                if (m_len <= 9)

                    *op++ = (BYTE)(16 | ((m_off & 0x4000) >> 11) | (m_len - 2));

                else

                {

                    m_len -= 9;

                    *op++ = (BYTE)(16 | ((m_off & 0x4000) >> 11));

                m3_m4_len:

                    while (m_len > 255)

                    {

                        m_len -= 255;

                        *op++ = 0;

                    }

                    *op++ = (BYTE)m_len;

                }

            }

        m3_m4_offset:

            *op++ = (BYTE)((m_off & 63) << 2);

            *op++ = (BYTE)(m_off >> 6);

        }

        ii = ip;

        if (ip >= ip_end)

            break;

    }

    *out_len = op - out;

    return (UINT)(in_end - ii);

}

UINT WINAPI lzo_compress(void *in, UINT in_len, void *out, BYTE *buffer)

{

    BYTE *op = (BYTE *)out;

    UINT t, out_len;

    UINT tt;

    BYTE *ii;

    if (in_len <= 13)

        t = in_len;

    else

    {

        t = _do_compress((BYTE *)in, in_len, (BYTE *)op, &out_len, buffer);

        op += out_len;

    }

    if (t > 0)

    {

        ii = (BYTE*)in + in_len - t;

        if (op == (BYTE*)out && t <= 238)

            *op++ = (BYTE)(17 + t);

        else

            if (t <= 3)

                op[-2] |= (BYTE)t;

            else

                if (t <= 18)

                    *op++ = (BYTE)(t - 3);

                else

                {

                    tt = t - 18;

                    *op++ = 0;

                    while (tt > 255)

                    {

                        tt -= 255;

                        *op++ = 0;

                    }

                    *op++ = (BYTE)tt;

                }

        do *op++ = *ii++; while (--t > 0);

    }

    *op++ = 17;

    *op++ = 0;

    *op++ = 0;

    return (op - (BYTE*)out);

}

UINT WINAPI lzo_decompress(void *in, UINT in_len, void *out)

{

    BYTE *op;

    BYTE *ip;

    UINT t;

    BYTE *m_pos;

    BYTE *ip_end;

    ip_end = (BYTE*)in + in_len;

    op = (BYTE *)out;

    ip = (BYTE *)in;

    if (*ip > 17)

    {

        t = *ip++ - 17;

        if (t < 4)

            goto match_next;

        do *op++ = *ip++; while (--t > 0);

        goto first_literal_run;

    }

    for (;;)

    {

        t = *ip++;

        if (t >= 16) goto match;

        if (t == 0)

        {

            while (*ip == 0)

            {

                t += 255;

                ip++;

            }

            t += 15 + *ip++;

        }

        *(UINT *)op = *(UINT *)ip;

        op += 4; ip += 4;

        if (--t > 0)

        {

            if (t >= 4)

            {

                do

                {

                    *(UINT *)op = *(UINT *)ip;

                    op += 4; ip += 4; t -= 4;

                } while (t >= 4);

                if (t > 0) do *op++ = *ip++; while (--t > 0);

            }

            else

                do *op++ = *ip++; while (--t > 0);

        }

    first_literal_run:

        t = *ip++;

        if (t >= 16)

            goto match;

        m_pos = op - 0x0801;

        m_pos -= t >> 2;

        m_pos -= *ip++ << 2;

        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;

        goto match_done;

        for (;;)

        {

        match:

            if (t >= 64)

            {

                m_pos = op - 1;

                m_pos -= (t >> 2) & 7;

                m_pos -= *ip++ << 3;

                t = (t >> 5) - 1;

                goto copy_match;

            }

            else

                if (t >= 32)

                {

                    t &= 31;

                    if (t == 0)

                    {

                        while (*ip == 0)

                        {

                            t += 255;

                            ip++;

                        }

                        t += 31 + *ip++;

                    }

                    m_pos = op - 1;

                    m_pos -= (*(USHORT *)ip) >> 2;

                    ip += 2;

                }

                else

                    if (t >= 16)

                    {

                        m_pos = op;

                        m_pos -= (t & 8) << 11;

                        t &= 7;

                        if (t == 0)

                        {

                            while (*ip == 0)

                            {

                                t += 255;

                                ip++;

                            }

                            t += 7 + *ip++;

                        }

                        m_pos -= (*(USHORT *)ip) >> 2;

                        ip += 2;

                        if (m_pos == op)

                            goto eof_found;

                        m_pos -= 0x4000;

                    }

                    else

                    {

                        m_pos = op - 1;

                        m_pos -= t >> 2;

                        m_pos -= *ip++ << 2;

                        *op++ = *m_pos++; *op++ = *m_pos;

                        goto match_done;

                    }

            if (t >= 6 && (op - m_pos) >= 4)

            {

                *(UINT *)op = *(UINT *)m_pos;

                op += 4; m_pos += 4; t -= 2;

                do

                {

                    *(UINT *)op = *(UINT *)m_pos;

                    op += 4; m_pos += 4; t -= 4;

                } while (t >= 4);

                if (t > 0)

                    do *op++ = *m_pos++; while (--t > 0);

            }

            else

            {

            copy_match:

                *op++ = *m_pos++; *op++ = *m_pos++;

                do *op++ = *m_pos++; while (--t > 0);

            }

        match_done:

            t = ip[-2] & 3;

            if (t == 0)    break;

        match_next:

            do *op++ = *ip++; while (--t > 0);

            t = *ip++;

        }

    }

eof_found:

    if (ip != ip_end) return -1;

    return (op - (BYTE*)out);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: