Coverage Report

Created: 2026-01-17 06:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/lzo-2.10/src/lzo1f_d.ch
Line
Count
Source
1
/* lzo1f_d.ch -- implementation of the LZO1F 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
LZO_PUBLIC(int)
37
DO_DECOMPRESS  ( const lzo_bytep in , lzo_uint  in_len,
38
                       lzo_bytep out, lzo_uintp out_len,
39
                       lzo_voidp wrkmem )
40
1.66k
{
41
1.66k
    lzo_bytep op;
42
1.66k
    const lzo_bytep ip;
43
1.66k
    lzo_uint t;
44
1.66k
    const lzo_bytep m_pos;
45
46
1.66k
    const lzo_bytep const ip_end = in + in_len;
47
#if defined(HAVE_ANY_OP)
48
420
    lzo_bytep const op_end = out + *out_len;
49
#endif
50
51
1.66k
    LZO_UNUSED(wrkmem);
52
53
1.66k
    *out_len = 0;
54
55
1.66k
    op = out;
56
1.66k
    ip = in;
57
58
195k
    while (TEST_IP_AND_TEST_OP)
59
280k
    {
60
280k
        t = *ip++;
61
280k
        if (t > 31)
62
180k
            goto match;
63
64
        /* a literal run */
65
99.9k
        if (t == 0)
66
13.7k
        {
67
13.7k
            NEED_IP(1);
68
1.25M
            while (*ip == 0)
69
1.24M
            {
70
1.24M
                t += 255;
71
1.24M
                ip++;
72
1.24M
                TEST_IV(t);
73
1.24M
                NEED_IP(1);
74
1.21M
            }
75
1.26k
            t += 31 + *ip++;
76
1.26k
        }
77
        /* copy literals */
78
99.9k
        assert(t > 0); NEED_OP(t); NEED_IP(t+1);
79
16.0k
#if (LZO_OPT_UNALIGNED32)
80
99.8k
        if (t >= 4)
81
97.1k
        {
82
2.74M
            do {
83
2.74M
                UA_COPY4(op, ip);
84
2.74M
                op += 4; ip += 4; t -= 4;
85
2.74M
            } while (t >= 4);
86
123k
            if (t > 0) do *op++ = *ip++; while (--t > 0);
87
97.1k
        }
88
2.66k
        else
89
2.66k
#endif
90
4.16k
        do *op++ = *ip++; while (--t > 0);
91
92
16.0k
        t = *ip++;
93
94
195k
        while (TEST_IP_AND_TEST_OP)
95
303k
        {
96
            /* handle matches */
97
303k
            if (t < 32)
98
45.8k
            {
99
45.8k
                m_pos = op - 1 - 0x800;
100
45.8k
                m_pos -= (t >> 2) & 7;
101
45.8k
                m_pos -= *ip++ << 3;
102
45.8k
                TEST_LB(m_pos); NEED_OP(3);
103
30.3k
                *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++;
104
30.3k
            }
105
257k
            else
106
257k
            {
107
437k
match:
108
437k
                if (t < M3_MARKER)
109
269k
                {
110
269k
                    m_pos = op - 1;
111
269k
                    m_pos -= (t >> 2) & 7;
112
269k
                    m_pos -= *ip++ << 3;
113
269k
                    t >>= 5;
114
269k
                    TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
115
125k
                    goto copy_match;
116
125k
                }
117
168k
                else
118
168k
                {
119
168k
                    t &= 31;
120
168k
                    if (t == 0)
121
28.5k
                    {
122
28.5k
                        NEED_IP(1);
123
1.12M
                        while (*ip == 0)
124
1.09M
                        {
125
1.09M
                            t += 255;
126
1.09M
                            ip++;
127
1.09M
                            TEST_OV(t);
128
1.09M
                            NEED_IP(1);
129
1.03M
                        }
130
6.10k
                        t += 31 + *ip++;
131
6.10k
                    }
132
168k
                    NEED_IP(2);
133
21.2k
                    m_pos = op;
134
21.2k
#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
135
168k
                    m_pos -= UA_GET_LE16(ip) >> 2;
136
21.2k
                    ip += 2;
137
#else
138
                    m_pos -= *ip++ >> 2;
139
                    m_pos -= *ip++ << 6;
140
#endif
141
168k
                    if (m_pos == op)
142
1.25k
                        goto eof_found;
143
21.2k
                }
144
145
                /* copy match */
146
167k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
147
21.2k
#if (LZO_OPT_UNALIGNED32)
148
167k
                if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
149
74.1k
                {
150
74.1k
                    UA_COPY4(op, m_pos);
151
74.1k
                    op += 4; m_pos += 4; t -= 4 - (3 - 1);
152
3.27M
                    do {
153
3.27M
                        UA_COPY4(op, m_pos);
154
3.27M
                        op += 4; m_pos += 4; t -= 4;
155
3.27M
                    } while (t >= 4);
156
105k
                    if (t > 0) do *op++ = *m_pos++; while (--t > 0);
157
74.1k
                }
158
93.0k
                else
159
93.0k
#endif
160
93.0k
                {
161
362k
copy_match:
162
362k
                *op++ = *m_pos++; *op++ = *m_pos++;
163
17.5M
                do *op++ = *m_pos++; while (--t > 0);
164
362k
                }
165
21.2k
            }
166
482k
            t = ip[-2] & 3;
167
482k
            if (t == 0)
168
278k
                break;
169
170
            /* copy literals */
171
482k
            assert(t > 0); NEED_OP(t); NEED_IP(t+1);
172
360k
            do *op++ = *ip++; while (--t > 0);
173
92.3k
            t = *ip++;
174
92.3k
        }
175
16.0k
    }
176
177
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
178
    /* no EOF code was found */
179
36
    *out_len = pd(op, out);
180
36
    return LZO_E_EOF_NOT_FOUND;
181
0
#endif
182
183
1.25k
eof_found:
184
1.25k
    assert(t == 1);
185
1.25k
    *out_len = pd(op, out);
186
1.25k
    return (ip == ip_end ? LZO_E_OK :
187
1.25k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
188
189
190
#if defined(HAVE_NEED_IP)
191
201
input_overrun:
192
201
    *out_len = pd(op, out);
193
201
    return LZO_E_INPUT_OVERRUN;
194
0
#endif
195
196
#if defined(HAVE_NEED_OP)
197
37
output_overrun:
198
37
    *out_len = pd(op, out);
199
37
    return LZO_E_OUTPUT_OVERRUN;
200
0
#endif
201
202
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
203
131
lookbehind_overrun:
204
131
    *out_len = pd(op, out);
205
131
    return LZO_E_LOOKBEHIND_OVERRUN;
206
#endif
207
1.66k
}
lzo1f_decompress
Line
Count
Source
40
1.24k
{
41
1.24k
    lzo_bytep op;
42
1.24k
    const lzo_bytep ip;
43
1.24k
    lzo_uint t;
44
1.24k
    const lzo_bytep m_pos;
45
46
1.24k
    const lzo_bytep const ip_end = in + in_len;
47
#if defined(HAVE_ANY_OP)
48
    lzo_bytep const op_end = out + *out_len;
49
#endif
50
51
1.24k
    LZO_UNUSED(wrkmem);
52
53
1.24k
    *out_len = 0;
54
55
1.24k
    op = out;
56
1.24k
    ip = in;
57
58
195k
    while (TEST_IP_AND_TEST_OP)
59
195k
    {
60
195k
        t = *ip++;
61
195k
        if (t > 31)
62
111k
            goto match;
63
64
        /* a literal run */
65
83.7k
        if (t == 0)
66
12.4k
        {
67
12.4k
            NEED_IP(1);
68
42.8k
            while (*ip == 0)
69
30.3k
            {
70
30.3k
                t += 255;
71
30.3k
                ip++;
72
30.3k
                TEST_IV(t);
73
30.3k
                NEED_IP(1);
74
30.3k
            }
75
12.4k
            t += 31 + *ip++;
76
12.4k
        }
77
        /* copy literals */
78
83.7k
        assert(t > 0); NEED_OP(t); NEED_IP(t+1);
79
83.7k
#if (LZO_OPT_UNALIGNED32)
80
83.7k
        if (t >= 4)
81
83.2k
        {
82
2.42M
            do {
83
2.42M
                UA_COPY4(op, ip);
84
2.42M
                op += 4; ip += 4; t -= 4;
85
2.42M
            } while (t >= 4);
86
109k
            if (t > 0) do *op++ = *ip++; while (--t > 0);
87
83.2k
        }
88
566
        else
89
566
#endif
90
951
        do *op++ = *ip++; while (--t > 0);
91
92
83.7k
        t = *ip++;
93
94
195k
        while (TEST_IP_AND_TEST_OP)
95
195k
        {
96
            /* handle matches */
97
195k
            if (t < 32)
98
15.4k
            {
99
15.4k
                m_pos = op - 1 - 0x800;
100
15.4k
                m_pos -= (t >> 2) & 7;
101
15.4k
                m_pos -= *ip++ << 3;
102
15.4k
                TEST_LB(m_pos); NEED_OP(3);
103
15.4k
                *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++;
104
15.4k
            }
105
179k
            else
106
179k
            {
107
290k
match:
108
290k
                if (t < M3_MARKER)
109
143k
                {
110
143k
                    m_pos = op - 1;
111
143k
                    m_pos -= (t >> 2) & 7;
112
143k
                    m_pos -= *ip++ << 3;
113
143k
                    t >>= 5;
114
143k
                    TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
115
143k
                    goto copy_match;
116
143k
                }
117
147k
                else
118
147k
                {
119
147k
                    t &= 31;
120
147k
                    if (t == 0)
121
22.3k
                    {
122
22.3k
                        NEED_IP(1);
123
90.2k
                        while (*ip == 0)
124
67.8k
                        {
125
67.8k
                            t += 255;
126
67.8k
                            ip++;
127
67.8k
                            TEST_OV(t);
128
67.8k
                            NEED_IP(1);
129
67.8k
                        }
130
22.3k
                        t += 31 + *ip++;
131
22.3k
                    }
132
147k
                    NEED_IP(2);
133
147k
                    m_pos = op;
134
147k
#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
135
147k
                    m_pos -= UA_GET_LE16(ip) >> 2;
136
147k
                    ip += 2;
137
#else
138
                    m_pos -= *ip++ >> 2;
139
                    m_pos -= *ip++ << 6;
140
#endif
141
147k
                    if (m_pos == op)
142
1.24k
                        goto eof_found;
143
147k
                }
144
145
                /* copy match */
146
145k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
147
145k
#if (LZO_OPT_UNALIGNED32)
148
145k
                if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
149
58.2k
                {
150
58.2k
                    UA_COPY4(op, m_pos);
151
58.2k
                    op += 4; m_pos += 4; t -= 4 - (3 - 1);
152
2.66M
                    do {
153
2.66M
                        UA_COPY4(op, m_pos);
154
2.66M
                        op += 4; m_pos += 4; t -= 4;
155
2.66M
                    } while (t >= 4);
156
82.0k
                    if (t > 0) do *op++ = *m_pos++; while (--t > 0);
157
58.2k
                }
158
87.7k
                else
159
87.7k
#endif
160
87.7k
                {
161
231k
copy_match:
162
231k
                *op++ = *m_pos++; *op++ = *m_pos++;
163
9.79M
                do *op++ = *m_pos++; while (--t > 0);
164
231k
                }
165
145k
            }
166
305k
            t = ip[-2] & 3;
167
305k
            if (t == 0)
168
193k
                break;
169
170
            /* copy literals */
171
305k
            assert(t > 0); NEED_OP(t); NEED_IP(t+1);
172
178k
            do *op++ = *ip++; while (--t > 0);
173
111k
            t = *ip++;
174
111k
        }
175
83.7k
    }
176
177
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
178
    /* no EOF code was found */
179
    *out_len = pd(op, out);
180
    return LZO_E_EOF_NOT_FOUND;
181
#endif
182
183
1.24k
eof_found:
184
1.24k
    assert(t == 1);
185
1.24k
    *out_len = pd(op, out);
186
1.24k
    return (ip == ip_end ? LZO_E_OK :
187
1.24k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
188
189
190
#if defined(HAVE_NEED_IP)
191
input_overrun:
192
    *out_len = pd(op, out);
193
    return LZO_E_INPUT_OVERRUN;
194
#endif
195
196
#if defined(HAVE_NEED_OP)
197
output_overrun:
198
    *out_len = pd(op, out);
199
    return LZO_E_OUTPUT_OVERRUN;
200
#endif
201
202
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
203
lookbehind_overrun:
204
    *out_len = pd(op, out);
205
    return LZO_E_LOOKBEHIND_OVERRUN;
206
#endif
207
1.24k
}
lzo1f_decompress_safe
Line
Count
Source
40
420
{
41
420
    lzo_bytep op;
42
420
    const lzo_bytep ip;
43
420
    lzo_uint t;
44
420
    const lzo_bytep m_pos;
45
46
420
    const lzo_bytep const ip_end = in + in_len;
47
420
#if defined(HAVE_ANY_OP)
48
420
    lzo_bytep const op_end = out + *out_len;
49
420
#endif
50
51
420
    LZO_UNUSED(wrkmem);
52
53
420
    *out_len = 0;
54
55
420
    op = out;
56
420
    ip = in;
57
58
420
    while (TEST_IP_AND_TEST_OP)
59
85.0k
    {
60
85.0k
        t = *ip++;
61
85.0k
        if (t > 31)
62
68.8k
            goto match;
63
64
        /* a literal run */
65
16.2k
        if (t == 0)
66
1.29k
        {
67
1.29k
            NEED_IP(1);
68
1.21M
            while (*ip == 0)
69
1.21M
            {
70
1.21M
                t += 255;
71
1.21M
                ip++;
72
1.21M
                TEST_IV(t);
73
1.21M
                NEED_IP(1);
74
1.21M
            }
75
1.26k
            t += 31 + *ip++;
76
1.26k
        }
77
        /* copy literals */
78
16.2k
        assert(t > 0); NEED_OP(t); NEED_IP(t+1);
79
16.0k
#if (LZO_OPT_UNALIGNED32)
80
16.0k
        if (t >= 4)
81
13.9k
        {
82
328k
            do {
83
328k
                UA_COPY4(op, ip);
84
328k
                op += 4; ip += 4; t -= 4;
85
328k
            } while (t >= 4);
86
14.5k
            if (t > 0) do *op++ = *ip++; while (--t > 0);
87
13.9k
        }
88
2.10k
        else
89
2.10k
#endif
90
3.21k
        do *op++ = *ip++; while (--t > 0);
91
92
16.0k
        t = *ip++;
93
94
16.0k
        while (TEST_IP_AND_TEST_OP)
95
108k
        {
96
            /* handle matches */
97
108k
            if (t < 32)
98
30.4k
            {
99
30.4k
                m_pos = op - 1 - 0x800;
100
30.4k
                m_pos -= (t >> 2) & 7;
101
30.4k
                m_pos -= *ip++ << 3;
102
30.4k
                TEST_LB(m_pos); NEED_OP(3);
103
30.3k
                *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++;
104
30.3k
            }
105
77.9k
            else
106
77.9k
            {
107
146k
match:
108
146k
                if (t < M3_MARKER)
109
125k
                {
110
125k
                    m_pos = op - 1;
111
125k
                    m_pos -= (t >> 2) & 7;
112
125k
                    m_pos -= *ip++ << 3;
113
125k
                    t >>= 5;
114
125k
                    TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
115
125k
                    goto copy_match;
116
125k
                }
117
21.3k
                else
118
21.3k
                {
119
21.3k
                    t &= 31;
120
21.3k
                    if (t == 0)
121
6.13k
                    {
122
6.13k
                        NEED_IP(1);
123
1.03M
                        while (*ip == 0)
124
1.03M
                        {
125
1.03M
                            t += 255;
126
1.03M
                            ip++;
127
1.03M
                            TEST_OV(t);
128
1.03M
                            NEED_IP(1);
129
1.03M
                        }
130
6.10k
                        t += 31 + *ip++;
131
6.10k
                    }
132
21.3k
                    NEED_IP(2);
133
21.2k
                    m_pos = op;
134
21.2k
#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
135
21.2k
                    m_pos -= UA_GET_LE16(ip) >> 2;
136
21.2k
                    ip += 2;
137
#else
138
                    m_pos -= *ip++ >> 2;
139
                    m_pos -= *ip++ << 6;
140
#endif
141
21.2k
                    if (m_pos == op)
142
15
                        goto eof_found;
143
21.2k
                }
144
145
                /* copy match */
146
21.2k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
147
21.2k
#if (LZO_OPT_UNALIGNED32)
148
21.2k
                if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
149
15.9k
                {
150
15.9k
                    UA_COPY4(op, m_pos);
151
15.9k
                    op += 4; m_pos += 4; t -= 4 - (3 - 1);
152
613k
                    do {
153
613k
                        UA_COPY4(op, m_pos);
154
613k
                        op += 4; m_pos += 4; t -= 4;
155
613k
                    } while (t >= 4);
156
23.2k
                    if (t > 0) do *op++ = *m_pos++; while (--t > 0);
157
15.9k
                }
158
5.23k
                else
159
5.23k
#endif
160
5.23k
                {
161
130k
copy_match:
162
130k
                *op++ = *m_pos++; *op++ = *m_pos++;
163
7.74M
                do *op++ = *m_pos++; while (--t > 0);
164
130k
                }
165
21.2k
            }
166
177k
            t = ip[-2] & 3;
167
177k
            if (t == 0)
168
84.6k
                break;
169
170
            /* copy literals */
171
177k
            assert(t > 0); NEED_OP(t); NEED_IP(t+1);
172
181k
            do *op++ = *ip++; while (--t > 0);
173
92.3k
            t = *ip++;
174
92.3k
        }
175
16.0k
    }
176
177
36
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
178
    /* no EOF code was found */
179
36
    *out_len = pd(op, out);
180
36
    return LZO_E_EOF_NOT_FOUND;
181
0
#endif
182
183
15
eof_found:
184
15
    assert(t == 1);
185
15
    *out_len = pd(op, out);
186
15
    return (ip == ip_end ? LZO_E_OK :
187
15
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
188
189
190
0
#if defined(HAVE_NEED_IP)
191
201
input_overrun:
192
201
    *out_len = pd(op, out);
193
201
    return LZO_E_INPUT_OVERRUN;
194
0
#endif
195
196
0
#if defined(HAVE_NEED_OP)
197
37
output_overrun:
198
37
    *out_len = pd(op, out);
199
37
    return LZO_E_OUTPUT_OVERRUN;
200
0
#endif
201
202
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
203
131
lookbehind_overrun:
204
131
    *out_len = pd(op, out);
205
131
    return LZO_E_LOOKBEHIND_OVERRUN;
206
420
#endif
207
420
}
208
209
210
/* vim:set ts=4 sw=4 et: */