Coverage Report

Created: 2025-08-26 06:41

/src/lzo-2.10/src/lzo2a_d.ch
Line
Count
Source (jump to first uncovered line)
1
/* lzo2a_d.ch -- implementation of the LZO2A decompression algorithm
2
3
   This file is part of the LZO real-time data compression library.
4
5
   Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
6
   All Rights Reserved.
7
8
   The LZO library is free software; you can redistribute it and/or
9
   modify it under the terms of the GNU General Public License as
10
   published by the Free Software Foundation; either version 2 of
11
   the License, or (at your option) any later version.
12
13
   The LZO library is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with the LZO library; see the file COPYING.
20
   If not, write to the Free Software Foundation, Inc.,
21
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22
23
   Markus F.X.J. Oberhumer
24
   <markus@oberhumer.com>
25
   http://www.oberhumer.com/opensource/lzo/
26
 */
27
28
29
#include "lzo1_d.ch"
30
31
32
/***********************************************************************
33
// decompress a block of data.
34
************************************************************************/
35
36
356k
#define _NEEDBYTE   NEED_IP(1)
37
356k
#define _NEXTBYTE   (*ip++)
38
39
LZO_PUBLIC(int)
40
DO_DECOMPRESS    ( const lzo_bytep in , lzo_uint  in_len,
41
                         lzo_bytep out, lzo_uintp out_len,
42
                         lzo_voidp wrkmem )
43
871
{
44
871
    lzo_bytep op;
45
871
    const lzo_bytep ip;
46
871
    const lzo_bytep m_pos;
47
48
871
    lzo_uint t;
49
871
    const lzo_bytep const ip_end = in + in_len;
50
#if defined(HAVE_ANY_OP)
51
191
    lzo_bytep const op_end = out + *out_len;
52
#endif
53
54
871
    lzo_uint32_t b = 0;     /* bit buffer */
55
871
    unsigned k = 0;         /* bits in bit buffer */
56
57
871
    LZO_UNUSED(wrkmem);
58
59
871
    op = out;
60
871
    ip = in;
61
62
2.31M
    while (TEST_IP_AND_TEST_OP)
63
2.49M
    {
64
2.49M
        NEEDBITS(1);
65
2.49M
        if (MASKBITS(1) == 0)
66
2.33M
        {
67
2.33M
            DUMPBITS(1);
68
            /* a literal */
69
2.33M
            NEED_IP(1); NEED_OP(1);
70
169k
            *op++ = *ip++;
71
169k
            continue;
72
169k
        }
73
163k
        DUMPBITS(1);
74
75
163k
        NEEDBITS(1);
76
163k
        if (MASKBITS(1) == 0)
77
93.1k
        {
78
93.1k
            DUMPBITS(1);
79
            /* a M1 match */
80
93.1k
            NEEDBITS(2);
81
93.1k
            t = M1_MIN_LEN + (lzo_uint) MASKBITS(2);
82
93.1k
            DUMPBITS(2);
83
93.1k
            NEED_IP(1); NEED_OP(t);
84
5.16k
            m_pos = op - 1 - *ip++;
85
5.16k
            assert(m_pos >= out); assert(m_pos < op);
86
93.1k
            TEST_LB(m_pos);
87
93.1k
            MEMCPY_DS(op,m_pos,t);
88
5.14k
            continue;
89
5.16k
        }
90
69.8k
        DUMPBITS(1);
91
92
69.8k
        NEED_IP(2);
93
6.18k
        t = *ip++;
94
6.18k
        m_pos = op;
95
6.18k
        m_pos -= (t & 31) | (((lzo_uint) *ip++) << 5);
96
6.18k
        t >>= 5;
97
69.8k
        if (t == 0)
98
29.5k
        {
99
#if (SWD_N >= 8192)
100
            NEEDBITS(1);
101
            t = MASKBITS(1);
102
            DUMPBITS(1);
103
            if (t == 0)
104
                t = 10 - 1;
105
            else
106
            {
107
                /* a M3 match */
108
                m_pos -= 8192;      /* t << 13 */
109
                t = M3_MIN_LEN - 1;
110
            }
111
#else
112
29.5k
            t = 10 - 1;
113
29.5k
#endif
114
29.5k
            NEED_IP(1);
115
1.71M
            while (*ip == 0)
116
1.68M
            {
117
1.68M
                t += 255;
118
1.68M
                ip++;
119
1.68M
                TEST_OV(t);
120
1.68M
                NEED_IP(1);
121
1.67M
            }
122
4.22k
            t += *ip++;
123
4.22k
        }
124
40.3k
        else
125
40.3k
        {
126
40.3k
#if defined(LZO_EOF_CODE)
127
40.3k
            if (m_pos == op)
128
685
                goto eof_found;
129
39.6k
#endif
130
39.6k
            t += 2;
131
39.6k
        }
132
69.1k
        assert(m_pos >= out); assert(m_pos < op);
133
69.1k
        TEST_LB(m_pos);
134
69.1k
        NEED_OP(t);
135
69.1k
        MEMCPY_DS(op,m_pos,t);
136
6.09k
    }
137
138
139
51
#if defined(LZO_EOF_CODE)
140
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
141
    /* no EOF code was found */
142
51
    *out_len = pd(op, out);
143
51
    return LZO_E_EOF_NOT_FOUND;
144
0
#endif
145
146
685
eof_found:
147
685
    assert(t == 1);
148
685
#endif
149
685
    *out_len = pd(op, out);
150
685
    return (ip == ip_end ? LZO_E_OK :
151
685
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
152
153
154
#if defined(HAVE_NEED_IP)
155
38
input_overrun:
156
38
    *out_len = pd(op, out);
157
38
    return LZO_E_INPUT_OVERRUN;
158
0
#endif
159
160
#if defined(HAVE_NEED_OP)
161
9
output_overrun:
162
9
    *out_len = pd(op, out);
163
9
    return LZO_E_OUTPUT_OVERRUN;
164
0
#endif
165
166
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
167
88
lookbehind_overrun:
168
88
    *out_len = pd(op, out);
169
88
    return LZO_E_LOOKBEHIND_OVERRUN;
170
#endif
171
871
}
lzo2a_decompress
Line
Count
Source
43
680
{
44
680
    lzo_bytep op;
45
680
    const lzo_bytep ip;
46
680
    const lzo_bytep m_pos;
47
48
680
    lzo_uint t;
49
680
    const lzo_bytep const ip_end = in + in_len;
50
#if defined(HAVE_ANY_OP)
51
    lzo_bytep const op_end = out + *out_len;
52
#endif
53
54
680
    lzo_uint32_t b = 0;     /* bit buffer */
55
680
    unsigned k = 0;         /* bits in bit buffer */
56
57
680
    LZO_UNUSED(wrkmem);
58
59
680
    op = out;
60
680
    ip = in;
61
62
2.31M
    while (TEST_IP_AND_TEST_OP)
63
2.31M
    {
64
2.31M
        NEEDBITS(1);
65
2.31M
        if (MASKBITS(1) == 0)
66
2.16M
        {
67
2.16M
            DUMPBITS(1);
68
            /* a literal */
69
2.16M
            NEED_IP(1); NEED_OP(1);
70
2.16M
            *op++ = *ip++;
71
2.16M
            continue;
72
2.16M
        }
73
151k
        DUMPBITS(1);
74
75
151k
        NEEDBITS(1);
76
151k
        if (MASKBITS(1) == 0)
77
87.9k
        {
78
87.9k
            DUMPBITS(1);
79
            /* a M1 match */
80
87.9k
            NEEDBITS(2);
81
87.9k
            t = M1_MIN_LEN + (lzo_uint) MASKBITS(2);
82
87.9k
            DUMPBITS(2);
83
87.9k
            NEED_IP(1); NEED_OP(t);
84
87.9k
            m_pos = op - 1 - *ip++;
85
87.9k
            assert(m_pos >= out); assert(m_pos < op);
86
87.9k
            TEST_LB(m_pos);
87
87.9k
            MEMCPY_DS(op,m_pos,t);
88
87.9k
            continue;
89
87.9k
        }
90
63.6k
        DUMPBITS(1);
91
92
63.6k
        NEED_IP(2);
93
63.6k
        t = *ip++;
94
63.6k
        m_pos = op;
95
63.6k
        m_pos -= (t & 31) | (((lzo_uint) *ip++) << 5);
96
63.6k
        t >>= 5;
97
63.6k
        if (t == 0)
98
25.3k
        {
99
#if (SWD_N >= 8192)
100
            NEEDBITS(1);
101
            t = MASKBITS(1);
102
            DUMPBITS(1);
103
            if (t == 0)
104
                t = 10 - 1;
105
            else
106
            {
107
                /* a M3 match */
108
                m_pos -= 8192;      /* t << 13 */
109
                t = M3_MIN_LEN - 1;
110
            }
111
#else
112
25.3k
            t = 10 - 1;
113
25.3k
#endif
114
25.3k
            NEED_IP(1);
115
42.5k
            while (*ip == 0)
116
17.2k
            {
117
17.2k
                t += 255;
118
17.2k
                ip++;
119
17.2k
                TEST_OV(t);
120
17.2k
                NEED_IP(1);
121
17.2k
            }
122
25.3k
            t += *ip++;
123
25.3k
        }
124
38.3k
        else
125
38.3k
        {
126
38.3k
#if defined(LZO_EOF_CODE)
127
38.3k
            if (m_pos == op)
128
680
                goto eof_found;
129
37.7k
#endif
130
37.7k
            t += 2;
131
37.7k
        }
132
63.0k
        assert(m_pos >= out); assert(m_pos < op);
133
63.0k
        TEST_LB(m_pos);
134
63.0k
        NEED_OP(t);
135
63.0k
        MEMCPY_DS(op,m_pos,t);
136
63.0k
    }
137
138
139
0
#if defined(LZO_EOF_CODE)
140
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
141
    /* no EOF code was found */
142
    *out_len = pd(op, out);
143
    return LZO_E_EOF_NOT_FOUND;
144
#endif
145
146
680
eof_found:
147
680
    assert(t == 1);
148
680
#endif
149
680
    *out_len = pd(op, out);
150
680
    return (ip == ip_end ? LZO_E_OK :
151
680
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
152
153
154
#if defined(HAVE_NEED_IP)
155
input_overrun:
156
    *out_len = pd(op, out);
157
    return LZO_E_INPUT_OVERRUN;
158
#endif
159
160
#if defined(HAVE_NEED_OP)
161
output_overrun:
162
    *out_len = pd(op, out);
163
    return LZO_E_OUTPUT_OVERRUN;
164
#endif
165
166
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
167
lookbehind_overrun:
168
    *out_len = pd(op, out);
169
    return LZO_E_LOOKBEHIND_OVERRUN;
170
#endif
171
680
}
lzo2a_decompress_safe
Line
Count
Source
43
191
{
44
191
    lzo_bytep op;
45
191
    const lzo_bytep ip;
46
191
    const lzo_bytep m_pos;
47
48
191
    lzo_uint t;
49
191
    const lzo_bytep const ip_end = in + in_len;
50
191
#if defined(HAVE_ANY_OP)
51
191
    lzo_bytep const op_end = out + *out_len;
52
191
#endif
53
54
191
    lzo_uint32_t b = 0;     /* bit buffer */
55
191
    unsigned k = 0;         /* bits in bit buffer */
56
57
191
    LZO_UNUSED(wrkmem);
58
59
191
    op = out;
60
191
    ip = in;
61
62
191
    while (TEST_IP_AND_TEST_OP)
63
181k
    {
64
181k
        NEEDBITS(1);
65
181k
        if (MASKBITS(1) == 0)
66
169k
        {
67
169k
            DUMPBITS(1);
68
            /* a literal */
69
169k
            NEED_IP(1); NEED_OP(1);
70
169k
            *op++ = *ip++;
71
169k
            continue;
72
169k
        }
73
11.3k
        DUMPBITS(1);
74
75
11.3k
        NEEDBITS(1);
76
11.3k
        if (MASKBITS(1) == 0)
77
5.17k
        {
78
5.17k
            DUMPBITS(1);
79
            /* a M1 match */
80
5.17k
            NEEDBITS(2);
81
5.17k
            t = M1_MIN_LEN + (lzo_uint) MASKBITS(2);
82
5.17k
            DUMPBITS(2);
83
5.17k
            NEED_IP(1); NEED_OP(t);
84
5.16k
            m_pos = op - 1 - *ip++;
85
5.16k
            assert(m_pos >= out); assert(m_pos < op);
86
5.16k
            TEST_LB(m_pos);
87
5.14k
            MEMCPY_DS(op,m_pos,t);
88
5.14k
            continue;
89
5.16k
        }
90
6.19k
        DUMPBITS(1);
91
92
6.19k
        NEED_IP(2);
93
6.18k
        t = *ip++;
94
6.18k
        m_pos = op;
95
6.18k
        m_pos -= (t & 31) | (((lzo_uint) *ip++) << 5);
96
6.18k
        t >>= 5;
97
6.18k
        if (t == 0)
98
4.23k
        {
99
#if (SWD_N >= 8192)
100
            NEEDBITS(1);
101
            t = MASKBITS(1);
102
            DUMPBITS(1);
103
            if (t == 0)
104
                t = 10 - 1;
105
            else
106
            {
107
                /* a M3 match */
108
                m_pos -= 8192;      /* t << 13 */
109
                t = M3_MIN_LEN - 1;
110
            }
111
#else
112
4.23k
            t = 10 - 1;
113
4.23k
#endif
114
4.23k
            NEED_IP(1);
115
1.67M
            while (*ip == 0)
116
1.67M
            {
117
1.67M
                t += 255;
118
1.67M
                ip++;
119
1.67M
                TEST_OV(t);
120
1.67M
                NEED_IP(1);
121
1.67M
            }
122
4.22k
            t += *ip++;
123
4.22k
        }
124
1.95k
        else
125
1.95k
        {
126
1.95k
#if defined(LZO_EOF_CODE)
127
1.95k
            if (m_pos == op)
128
5
                goto eof_found;
129
1.94k
#endif
130
1.94k
            t += 2;
131
1.94k
        }
132
6.16k
        assert(m_pos >= out); assert(m_pos < op);
133
6.16k
        TEST_LB(m_pos);
134
6.09k
        NEED_OP(t);
135
6.09k
        MEMCPY_DS(op,m_pos,t);
136
6.09k
    }
137
138
139
51
#if defined(LZO_EOF_CODE)
140
51
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
141
    /* no EOF code was found */
142
51
    *out_len = pd(op, out);
143
51
    return LZO_E_EOF_NOT_FOUND;
144
0
#endif
145
146
5
eof_found:
147
5
    assert(t == 1);
148
5
#endif
149
5
    *out_len = pd(op, out);
150
5
    return (ip == ip_end ? LZO_E_OK :
151
5
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
152
153
154
0
#if defined(HAVE_NEED_IP)
155
38
input_overrun:
156
38
    *out_len = pd(op, out);
157
38
    return LZO_E_INPUT_OVERRUN;
158
0
#endif
159
160
0
#if defined(HAVE_NEED_OP)
161
9
output_overrun:
162
9
    *out_len = pd(op, out);
163
9
    return LZO_E_OUTPUT_OVERRUN;
164
0
#endif
165
166
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
167
88
lookbehind_overrun:
168
88
    *out_len = pd(op, out);
169
88
    return LZO_E_LOOKBEHIND_OVERRUN;
170
191
#endif
171
191
}
172
173
174
/* vim:set ts=4 sw=4 et: */