Coverage Report

Created: 2026-04-12 07:05

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.65k
{
41
1.65k
    lzo_bytep op;
42
1.65k
    const lzo_bytep ip;
43
1.65k
    lzo_uint t;
44
1.65k
    const lzo_bytep m_pos;
45
46
1.65k
    const lzo_bytep const ip_end = in + in_len;
47
#if defined(HAVE_ANY_OP)
48
438
    lzo_bytep const op_end = out + *out_len;
49
#endif
50
51
1.65k
    LZO_UNUSED(wrkmem);
52
53
1.65k
    *out_len = 0;
54
55
1.65k
    op = out;
56
1.65k
    ip = in;
57
58
246k
    while (TEST_IP_AND_TEST_OP)
59
300k
    {
60
300k
        t = *ip++;
61
300k
        if (t > 31)
62
175k
            goto match;
63
64
        /* a literal run */
65
124k
        if (t == 0)
66
13.7k
        {
67
13.7k
            NEED_IP(1);
68
1.19M
            while (*ip == 0)
69
1.18M
            {
70
1.18M
                t += 255;
71
1.18M
                ip++;
72
1.18M
                TEST_IV(t);
73
1.18M
                NEED_IP(1);
74
1.14M
            }
75
832
            t += 31 + *ip++;
76
832
        }
77
        /* copy literals */
78
124k
        assert(t > 0); NEED_OP(t); NEED_IP(t+1);
79
10.4k
#if (LZO_OPT_UNALIGNED32)
80
124k
        if (t >= 4)
81
122k
        {
82
3.15M
            do {
83
3.15M
                UA_COPY4(op, ip);
84
3.15M
                op += 4; ip += 4; t -= 4;
85
3.15M
            } while (t >= 4);
86
158k
            if (t > 0) do *op++ = *ip++; while (--t > 0);
87
122k
        }
88
1.99k
        else
89
1.99k
#endif
90
3.53k
        do *op++ = *ip++; while (--t > 0);
91
92
10.4k
        t = *ip++;
93
94
241k
        while (TEST_IP_AND_TEST_OP)
95
321k
        {
96
            /* handle matches */
97
321k
            if (t < 32)
98
42.7k
            {
99
42.7k
                m_pos = op - 1 - 0x800;
100
42.7k
                m_pos -= (t >> 2) & 7;
101
42.7k
                m_pos -= *ip++ << 3;
102
42.7k
                TEST_LB(m_pos); NEED_OP(3);
103
26.4k
                *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++;
104
26.4k
            }
105
278k
            else
106
278k
            {
107
454k
match:
108
454k
                if (t < M3_MARKER)
109
288k
                {
110
288k
                    m_pos = op - 1;
111
288k
                    m_pos -= (t >> 2) & 7;
112
288k
                    m_pos -= *ip++ << 3;
113
288k
                    t >>= 5;
114
288k
                    TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
115
83.5k
                    goto copy_match;
116
83.5k
                }
117
166k
                else
118
166k
                {
119
166k
                    t &= 31;
120
166k
                    if (t == 0)
121
17.9k
                    {
122
17.9k
                        NEED_IP(1);
123
1.14M
                        while (*ip == 0)
124
1.12M
                        {
125
1.12M
                            t += 255;
126
1.12M
                            ip++;
127
1.12M
                            TEST_OV(t);
128
1.12M
                            NEED_IP(1);
129
1.05M
                        }
130
1.93k
                        t += 31 + *ip++;
131
1.93k
                    }
132
166k
                    NEED_IP(2);
133
13.3k
                    m_pos = op;
134
13.3k
#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
135
166k
                    m_pos -= UA_GET_LE16(ip) >> 2;
136
13.3k
                    ip += 2;
137
#else
138
                    m_pos -= *ip++ >> 2;
139
                    m_pos -= *ip++ << 6;
140
#endif
141
166k
                    if (m_pos == op)
142
1.23k
                        goto eof_found;
143
13.3k
                }
144
145
                /* copy match */
146
164k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
147
13.2k
#if (LZO_OPT_UNALIGNED32)
148
164k
                if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
149
51.8k
                {
150
51.8k
                    UA_COPY4(op, m_pos);
151
51.8k
                    op += 4; m_pos += 4; t -= 4 - (3 - 1);
152
3.32M
                    do {
153
3.32M
                        UA_COPY4(op, m_pos);
154
3.32M
                        op += 4; m_pos += 4; t -= 4;
155
3.32M
                    } while (t >= 4);
156
72.3k
                    if (t > 0) do *op++ = *m_pos++; while (--t > 0);
157
51.8k
                }
158
112k
                else
159
112k
#endif
160
112k
                {
161
401k
copy_match:
162
401k
                *op++ = *m_pos++; *op++ = *m_pos++;
163
14.3M
                do *op++ = *m_pos++; while (--t > 0);
164
401k
                }
165
13.2k
            }
166
495k
            t = ip[-2] & 3;
167
495k
            if (t == 0)
168
298k
                break;
169
170
            /* copy literals */
171
495k
            assert(t > 0); NEED_OP(t); NEED_IP(t+1);
172
350k
            do *op++ = *ip++; while (--t > 0);
173
69.8k
            t = *ip++;
174
69.8k
        }
175
10.4k
    }
176
177
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
178
    /* no EOF code was found */
179
42
    *out_len = pd(op, out);
180
42
    return LZO_E_EOF_NOT_FOUND;
181
0
#endif
182
183
1.23k
eof_found:
184
1.23k
    assert(t == 1);
185
1.23k
    *out_len = pd(op, out);
186
1.23k
    return (ip == ip_end ? LZO_E_OK :
187
1.23k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
188
189
190
#if defined(HAVE_NEED_IP)
191
214
input_overrun:
192
214
    *out_len = pd(op, out);
193
214
    return LZO_E_INPUT_OVERRUN;
194
0
#endif
195
196
#if defined(HAVE_NEED_OP)
197
34
output_overrun:
198
34
    *out_len = pd(op, out);
199
34
    return LZO_E_OUTPUT_OVERRUN;
200
0
#endif
201
202
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
203
128
lookbehind_overrun:
204
128
    *out_len = pd(op, out);
205
128
    return LZO_E_LOOKBEHIND_OVERRUN;
206
#endif
207
1.65k
}
lzo1f_decompress
Line
Count
Source
40
1.21k
{
41
1.21k
    lzo_bytep op;
42
1.21k
    const lzo_bytep ip;
43
1.21k
    lzo_uint t;
44
1.21k
    const lzo_bytep m_pos;
45
46
1.21k
    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.21k
    LZO_UNUSED(wrkmem);
52
53
1.21k
    *out_len = 0;
54
55
1.21k
    op = out;
56
1.21k
    ip = in;
57
58
246k
    while (TEST_IP_AND_TEST_OP)
59
246k
    {
60
246k
        t = *ip++;
61
246k
        if (t > 31)
62
132k
            goto match;
63
64
        /* a literal run */
65
114k
        if (t == 0)
66
12.9k
        {
67
12.9k
            NEED_IP(1);
68
49.7k
            while (*ip == 0)
69
36.8k
            {
70
36.8k
                t += 255;
71
36.8k
                ip++;
72
36.8k
                TEST_IV(t);
73
36.8k
                NEED_IP(1);
74
36.8k
            }
75
12.9k
            t += 31 + *ip++;
76
12.9k
        }
77
        /* copy literals */
78
114k
        assert(t > 0); NEED_OP(t); NEED_IP(t+1);
79
114k
#if (LZO_OPT_UNALIGNED32)
80
114k
        if (t >= 4)
81
113k
        {
82
2.85M
            do {
83
2.85M
                UA_COPY4(op, ip);
84
2.85M
                op += 4; ip += 4; t -= 4;
85
2.85M
            } while (t >= 4);
86
148k
            if (t > 0) do *op++ = *ip++; while (--t > 0);
87
113k
        }
88
531
        else
89
531
#endif
90
858
        do *op++ = *ip++; while (--t > 0);
91
92
114k
        t = *ip++;
93
94
241k
        while (TEST_IP_AND_TEST_OP)
95
241k
        {
96
            /* handle matches */
97
241k
            if (t < 32)
98
16.2k
            {
99
16.2k
                m_pos = op - 1 - 0x800;
100
16.2k
                m_pos -= (t >> 2) & 7;
101
16.2k
                m_pos -= *ip++ << 3;
102
16.2k
                TEST_LB(m_pos); NEED_OP(3);
103
16.2k
                *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++;
104
16.2k
            }
105
224k
            else
106
224k
            {
107
357k
match:
108
357k
                if (t < M3_MARKER)
109
204k
                {
110
204k
                    m_pos = op - 1;
111
204k
                    m_pos -= (t >> 2) & 7;
112
204k
                    m_pos -= *ip++ << 3;
113
204k
                    t >>= 5;
114
204k
                    TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
115
204k
                    goto copy_match;
116
204k
                }
117
152k
                else
118
152k
                {
119
152k
                    t &= 31;
120
152k
                    if (t == 0)
121
16.0k
                    {
122
16.0k
                        NEED_IP(1);
123
82.9k
                        while (*ip == 0)
124
66.9k
                        {
125
66.9k
                            t += 255;
126
66.9k
                            ip++;
127
66.9k
                            TEST_OV(t);
128
66.9k
                            NEED_IP(1);
129
66.9k
                        }
130
16.0k
                        t += 31 + *ip++;
131
16.0k
                    }
132
152k
                    NEED_IP(2);
133
152k
                    m_pos = op;
134
152k
#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
135
152k
                    m_pos -= UA_GET_LE16(ip) >> 2;
136
152k
                    ip += 2;
137
#else
138
                    m_pos -= *ip++ >> 2;
139
                    m_pos -= *ip++ << 6;
140
#endif
141
152k
                    if (m_pos == op)
142
1.21k
                        goto eof_found;
143
152k
                }
144
145
                /* copy match */
146
151k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
147
151k
#if (LZO_OPT_UNALIGNED32)
148
151k
                if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
149
41.6k
                {
150
41.6k
                    UA_COPY4(op, m_pos);
151
41.6k
                    op += 4; m_pos += 4; t -= 4 - (3 - 1);
152
2.68M
                    do {
153
2.68M
                        UA_COPY4(op, m_pos);
154
2.68M
                        op += 4; m_pos += 4; t -= 4;
155
2.68M
                    } while (t >= 4);
156
57.6k
                    if (t > 0) do *op++ = *m_pos++; while (--t > 0);
157
41.6k
                }
158
109k
                else
159
109k
#endif
160
109k
                {
161
314k
copy_match:
162
314k
                *op++ = *m_pos++; *op++ = *m_pos++;
163
8.93M
                do *op++ = *m_pos++; while (--t > 0);
164
314k
                }
165
151k
            }
166
372k
            t = ip[-2] & 3;
167
372k
            if (t == 0)
168
245k
                break;
169
170
            /* copy literals */
171
372k
            assert(t > 0); NEED_OP(t); NEED_IP(t+1);
172
215k
            do *op++ = *ip++; while (--t > 0);
173
126k
            t = *ip++;
174
126k
        }
175
114k
    }
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.21k
eof_found:
184
1.21k
    assert(t == 1);
185
1.21k
    *out_len = pd(op, out);
186
1.21k
    return (ip == ip_end ? LZO_E_OK :
187
1.21k
           (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.21k
}
lzo1f_decompress_safe
Line
Count
Source
40
438
{
41
438
    lzo_bytep op;
42
438
    const lzo_bytep ip;
43
438
    lzo_uint t;
44
438
    const lzo_bytep m_pos;
45
46
438
    const lzo_bytep const ip_end = in + in_len;
47
438
#if defined(HAVE_ANY_OP)
48
438
    lzo_bytep const op_end = out + *out_len;
49
438
#endif
50
51
438
    LZO_UNUSED(wrkmem);
52
53
438
    *out_len = 0;
54
55
438
    op = out;
56
438
    ip = in;
57
58
438
    while (TEST_IP_AND_TEST_OP)
59
53.7k
    {
60
53.7k
        t = *ip++;
61
53.7k
        if (t > 31)
62
43.1k
            goto match;
63
64
        /* a literal run */
65
10.5k
        if (t == 0)
66
863
        {
67
863
            NEED_IP(1);
68
1.14M
            while (*ip == 0)
69
1.14M
            {
70
1.14M
                t += 255;
71
1.14M
                ip++;
72
1.14M
                TEST_IV(t);
73
1.14M
                NEED_IP(1);
74
1.14M
            }
75
832
            t += 31 + *ip++;
76
832
        }
77
        /* copy literals */
78
10.5k
        assert(t > 0); NEED_OP(t); NEED_IP(t+1);
79
10.4k
#if (LZO_OPT_UNALIGNED32)
80
10.4k
        if (t >= 4)
81
8.97k
        {
82
298k
            do {
83
298k
                UA_COPY4(op, ip);
84
298k
                op += 4; ip += 4; t -= 4;
85
298k
            } while (t >= 4);
86
9.76k
            if (t > 0) do *op++ = *ip++; while (--t > 0);
87
8.97k
        }
88
1.46k
        else
89
1.46k
#endif
90
2.67k
        do *op++ = *ip++; while (--t > 0);
91
92
10.4k
        t = *ip++;
93
94
10.4k
        while (TEST_IP_AND_TEST_OP)
95
80.2k
        {
96
            /* handle matches */
97
80.2k
            if (t < 32)
98
26.4k
            {
99
26.4k
                m_pos = op - 1 - 0x800;
100
26.4k
                m_pos -= (t >> 2) & 7;
101
26.4k
                m_pos -= *ip++ << 3;
102
26.4k
                TEST_LB(m_pos); NEED_OP(3);
103
26.4k
                *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++;
104
26.4k
            }
105
53.8k
            else
106
53.8k
            {
107
96.9k
match:
108
96.9k
                if (t < M3_MARKER)
109
83.5k
                {
110
83.5k
                    m_pos = op - 1;
111
83.5k
                    m_pos -= (t >> 2) & 7;
112
83.5k
                    m_pos -= *ip++ << 3;
113
83.5k
                    t >>= 5;
114
83.5k
                    TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
115
83.5k
                    goto copy_match;
116
83.5k
                }
117
13.3k
                else
118
13.3k
                {
119
13.3k
                    t &= 31;
120
13.3k
                    if (t == 0)
121
1.95k
                    {
122
1.95k
                        NEED_IP(1);
123
1.05M
                        while (*ip == 0)
124
1.05M
                        {
125
1.05M
                            t += 255;
126
1.05M
                            ip++;
127
1.05M
                            TEST_OV(t);
128
1.05M
                            NEED_IP(1);
129
1.05M
                        }
130
1.93k
                        t += 31 + *ip++;
131
1.93k
                    }
132
13.3k
                    NEED_IP(2);
133
13.3k
                    m_pos = op;
134
13.3k
#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
135
13.3k
                    m_pos -= UA_GET_LE16(ip) >> 2;
136
13.3k
                    ip += 2;
137
#else
138
                    m_pos -= *ip++ >> 2;
139
                    m_pos -= *ip++ << 6;
140
#endif
141
13.3k
                    if (m_pos == op)
142
20
                        goto eof_found;
143
13.3k
                }
144
145
                /* copy match */
146
13.3k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
147
13.2k
#if (LZO_OPT_UNALIGNED32)
148
13.2k
                if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
149
10.1k
                {
150
10.1k
                    UA_COPY4(op, m_pos);
151
10.1k
                    op += 4; m_pos += 4; t -= 4 - (3 - 1);
152
647k
                    do {
153
647k
                        UA_COPY4(op, m_pos);
154
647k
                        op += 4; m_pos += 4; t -= 4;
155
647k
                    } while (t >= 4);
156
14.7k
                    if (t > 0) do *op++ = *m_pos++; while (--t > 0);
157
10.1k
                }
158
3.12k
                else
159
3.12k
#endif
160
3.12k
                {
161
86.6k
copy_match:
162
86.6k
                *op++ = *m_pos++; *op++ = *m_pos++;
163
5.39M
                do *op++ = *m_pos++; while (--t > 0);
164
86.6k
                }
165
13.2k
            }
166
123k
            t = ip[-2] & 3;
167
123k
            if (t == 0)
168
53.3k
                break;
169
170
            /* copy literals */
171
123k
            assert(t > 0); NEED_OP(t); NEED_IP(t+1);
172
134k
            do *op++ = *ip++; while (--t > 0);
173
69.8k
            t = *ip++;
174
69.8k
        }
175
10.4k
    }
176
177
42
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
178
    /* no EOF code was found */
179
42
    *out_len = pd(op, out);
180
42
    return LZO_E_EOF_NOT_FOUND;
181
0
#endif
182
183
20
eof_found:
184
20
    assert(t == 1);
185
20
    *out_len = pd(op, out);
186
20
    return (ip == ip_end ? LZO_E_OK :
187
20
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
188
189
190
0
#if defined(HAVE_NEED_IP)
191
214
input_overrun:
192
214
    *out_len = pd(op, out);
193
214
    return LZO_E_INPUT_OVERRUN;
194
0
#endif
195
196
0
#if defined(HAVE_NEED_OP)
197
34
output_overrun:
198
34
    *out_len = pd(op, out);
199
34
    return LZO_E_OUTPUT_OVERRUN;
200
0
#endif
201
202
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
203
128
lookbehind_overrun:
204
128
    *out_len = pd(op, out);
205
128
    return LZO_E_LOOKBEHIND_OVERRUN;
206
438
#endif
207
438
}
208
209
210
/* vim:set ts=4 sw=4 et: */