Coverage Report

Created: 2026-03-01 06:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/lzo-2.10/src/lzo1x_d.ch
Line
Count
Source
1
/* lzo1x_d.ch -- implementation of the LZO1X 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
#if defined(DO_DECOMPRESS)
37
LZO_PUBLIC(int)
38
DO_DECOMPRESS  ( const lzo_bytep in , lzo_uint  in_len,
39
                       lzo_bytep out, lzo_uintp out_len,
40
                       lzo_voidp wrkmem )
41
#endif
42
9.02k
{
43
9.02k
    lzo_bytep op;
44
9.02k
    const lzo_bytep ip;
45
9.02k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
9.02k
    const lzo_bytep m_pos;
51
9.02k
#endif
52
53
9.02k
    const lzo_bytep const ip_end = in + in_len;
54
#if defined(HAVE_ANY_OP)
55
1.70k
    lzo_bytep const op_end = out + *out_len;
56
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
9.02k
    LZO_UNUSED(wrkmem);
62
63
#if defined(COPY_DICT)
64
    if (dict)
65
    {
66
        if (dict_len > M4_MAX_OFFSET)
67
        {
68
            dict += dict_len - M4_MAX_OFFSET;
69
            dict_len = M4_MAX_OFFSET;
70
        }
71
        dict_end = dict + dict_len;
72
    }
73
    else
74
    {
75
        dict_len = 0;
76
        dict_end = NULL;
77
    }
78
#endif /* COPY_DICT */
79
80
9.02k
    *out_len = 0;
81
82
9.02k
    op = out;
83
9.02k
    ip = in;
84
85
9.02k
    NEED_IP(1);
86
9.02k
    if (*ip > 17)
87
5.45k
    {
88
5.45k
        t = *ip++ - 17;
89
5.45k
        if (t < 4)
90
2.62k
            goto match_next;
91
5.45k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
57.3k
        do *op++ = *ip++; while (--t > 0);
93
281
        goto first_literal_run;
94
316
    }
95
96
3.57k
    for (;;)
97
1.71M
    {
98
1.71M
        NEED_IP(3);
99
216k
        t = *ip++;
100
1.71M
        if (t >= 16)
101
1.24M
            goto match;
102
        /* a literal run */
103
468k
        if (t == 0)
104
152k
        {
105
27.9M
            while (*ip == 0)
106
27.7M
            {
107
27.7M
                t += 255;
108
27.7M
                ip++;
109
27.7M
                TEST_IV(t);
110
27.7M
                NEED_IP(1);
111
27.1M
            }
112
27.9k
            t += 15 + *ip++;
113
27.9k
        }
114
        /* copy literals */
115
468k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
56.9k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
56.9k
        t += 3;
118
468k
        if (t >= 8) do
119
22.9M
        {
120
22.9M
            UA_COPY8(op,ip);
121
22.9M
            op += 8; ip += 8; t -= 8;
122
22.9M
        } while (t >= 8);
123
468k
        if (t >= 4)
124
295k
        {
125
295k
            UA_COPY4(op,ip);
126
295k
            op += 4; ip += 4; t -= 4;
127
295k
        }
128
468k
        if (t > 0)
129
313k
        {
130
313k
            *op++ = *ip++;
131
313k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
313k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
470k
first_literal_run:
167
168
169
470k
        t = *ip++;
170
470k
        if (t >= 16)
171
425k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
13.7k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
5.63k
        m_pos = op - t;
185
5.63k
        last_m_off = t;
186
#else
187
31.7k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
        m_pos -= t >> 2;
189
        m_pos -= *ip++ << 2;
190
#endif
191
45.4k
        TEST_LB(m_pos); NEED_OP(3);
192
29.0k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
29.0k
#endif /* COPY_DICT */
194
29.0k
        goto match_done;
195
196
197
        /* handle matches */
198
2.46M
        for (;;) {
199
4.13M
match:
200
4.13M
            if (t >= 64)                /* a M2 match */
201
1.61M
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
#if defined(LZO1X)
222
                m_pos = op - 1;
223
                m_pos -= (t >> 2) & 7;
224
                m_pos -= *ip++ << 3;
225
                t = (t >> 5) - 1;
226
#elif defined(LZO1Y)
227
                m_pos = op - 1;
228
                m_pos -= (t >> 2) & 3;
229
                m_pos -= *ip++ << 2;
230
                t = (t >> 4) - 3;
231
#elif defined(LZO1Z)
232
                {
233
                    lzo_uint off = t & 0x1f;
234
                    m_pos = op;
235
448k
                    if (off >= 0x1c)
236
29.9k
                    {
237
29.9k
                        assert(last_m_off > 0);
238
29.9k
                        m_pos -= last_m_off;
239
29.9k
                    }
240
418k
                    else
241
418k
                    {
242
418k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
418k
                        m_pos -= off;
244
418k
                        last_m_off = off;
245
418k
                    }
246
                }
247
                t = (t >> 5) - 1;
248
#endif
249
1.61M
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
260k
                goto copy_match;
251
260k
#endif /* COPY_DICT */
252
260k
            }
253
2.51M
            else if (t >= 32)           /* a M3 match */
254
1.11M
            {
255
1.11M
                t &= 31;
256
1.11M
                if (t == 0)
257
219k
                {
258
19.4M
                    while (*ip == 0)
259
19.2M
                    {
260
19.2M
                        t += 255;
261
19.2M
                        ip++;
262
19.2M
                        TEST_OV(t);
263
19.2M
                        NEED_IP(1);
264
19.0M
                    }
265
9.70k
                    t += 31 + *ip++;
266
219k
                    NEED_IP(2);
267
9.70k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
23.2k
                {
278
23.2k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
23.2k
                    m_pos = op - off;
280
23.2k
                    last_m_off = off;
281
23.2k
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
72.8k
                m_pos = op - 1;
284
801k
                m_pos -= UA_GET_LE16(ip) >> 2;
285
#else
286
                m_pos = op - 1;
287
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
288
#endif
289
72.8k
#endif /* COPY_DICT */
290
72.8k
                ip += 2;
291
72.8k
            }
292
1.39M
            else if (t >= 16)           /* a M4 match */
293
364k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
364k
                m_pos = op;
298
364k
                m_pos -= (t & 8) << 11;
299
364k
#endif /* COPY_DICT */
300
364k
                t &= 7;
301
364k
                if (t == 0)
302
106k
                {
303
6.97M
                    while (*ip == 0)
304
6.86M
                    {
305
6.86M
                        t += 255;
306
6.86M
                        ip++;
307
6.86M
                        TEST_OV(t);
308
6.86M
                        NEED_IP(1);
309
6.82M
                    }
310
8.99k
                    t += 7 + *ip++;
311
106k
                    NEED_IP(2);
312
8.99k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
7.33k
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
174k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
22.2k
                ip += 2;
335
364k
                if (m_pos == op)
336
7.36k
                    goto eof_found;
337
356k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
187k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
356k
#endif /* COPY_DICT */
342
356k
            }
343
1.03M
            else                            /* a M1 match */
344
1.03M
            {
345
#if defined(COPY_DICT)
346
#if defined(LZO1Z)
347
                m_off = 1 + (t << 6) + (*ip++ >> 2);
348
                last_m_off = m_off;
349
#else
350
                m_off = 1 + (t >> 2) + (*ip++ << 2);
351
#endif
352
                NEED_OP(2);
353
                t = 2; COPY_DICT(t,m_off)
354
#else /* !COPY_DICT */
355
#if defined(LZO1Z)
356
                t = 1 + (t << 6) + (*ip++ >> 2);
357
                m_pos = op - t;
358
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
1.03M
                TEST_LB(m_pos); NEED_OP(2);
365
94.6k
                *op++ = *m_pos++; *op++ = *m_pos;
366
94.6k
#endif /* COPY_DICT */
367
94.6k
                goto match_done;
368
94.6k
            }
369
370
            /* copy match */
371
#if defined(COPY_DICT)
372
373
            NEED_OP(t+3-1);
374
            t += 3-1; COPY_DICT(t,m_off)
375
376
#else /* !COPY_DICT */
377
378
1.47M
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
125k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
1.47M
            if (op - m_pos >= 8)
381
1.39M
            {
382
1.39M
                t += (3 - 1);
383
1.39M
                if (t >= 8) do
384
9.43M
                {
385
9.43M
                    UA_COPY8(op,m_pos);
386
9.43M
                    op += 8; m_pos += 8; t -= 8;
387
9.43M
                } while (t >= 8);
388
1.39M
                if (t >= 4)
389
713k
                {
390
713k
                    UA_COPY4(op,m_pos);
391
713k
                    op += 4; m_pos += 4; t -= 4;
392
713k
                }
393
1.39M
                if (t > 0)
394
1.00M
                {
395
1.00M
                    *op++ = m_pos[0];
396
1.00M
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
1.00M
                }
398
1.39M
            }
399
75.5k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
75.5k
            {
420
1.69M
copy_match:
421
1.69M
                *op++ = *m_pos++; *op++ = *m_pos++;
422
68.1M
                do *op++ = *m_pos++; while (--t > 0);
423
1.69M
            }
424
425
125k
#endif /* COPY_DICT */
426
427
4.16M
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
4.16M
            if (t == 0)
434
1.71M
                break;
435
436
            /* copy literals */
437
2.46M
match_next:
438
2.46M
            assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
439
#if 0
440
            do *op++ = *ip++; while (--t > 0);
441
#else
442
294k
            *op++ = *ip++;
443
2.46M
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
294k
#endif
445
294k
            t = *ip++;
446
294k
        }
447
0
    }
448
449
7.36k
eof_found:
450
7.36k
    *out_len = pd(op, out);
451
7.36k
    return (ip == ip_end ? LZO_E_OK :
452
7.36k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
#if defined(HAVE_NEED_IP)
456
1.07k
input_overrun:
457
1.07k
    *out_len = pd(op, out);
458
1.07k
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
#if defined(HAVE_NEED_OP)
462
182
output_overrun:
463
182
    *out_len = pd(op, out);
464
182
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
408
lookbehind_overrun:
469
408
    *out_len = pd(op, out);
470
408
    return LZO_E_LOOKBEHIND_OVERRUN;
471
#endif
472
3.57k
}
lzo1x_decompress
Line
Count
Source
42
3.80k
{
43
3.80k
    lzo_bytep op;
44
3.80k
    const lzo_bytep ip;
45
3.80k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
3.80k
    const lzo_bytep m_pos;
51
3.80k
#endif
52
53
3.80k
    const lzo_bytep const ip_end = in + in_len;
54
#if defined(HAVE_ANY_OP)
55
    lzo_bytep const op_end = out + *out_len;
56
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
3.80k
    LZO_UNUSED(wrkmem);
62
63
#if defined(COPY_DICT)
64
    if (dict)
65
    {
66
        if (dict_len > M4_MAX_OFFSET)
67
        {
68
            dict += dict_len - M4_MAX_OFFSET;
69
            dict_len = M4_MAX_OFFSET;
70
        }
71
        dict_end = dict + dict_len;
72
    }
73
    else
74
    {
75
        dict_len = 0;
76
        dict_end = NULL;
77
    }
78
#endif /* COPY_DICT */
79
80
3.80k
    *out_len = 0;
81
82
3.80k
    op = out;
83
3.80k
    ip = in;
84
85
3.80k
    NEED_IP(1);
86
3.80k
    if (*ip > 17)
87
1.45k
    {
88
1.45k
        t = *ip++ - 17;
89
1.45k
        if (t < 4)
90
668
            goto match_next;
91
1.45k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
20.2k
        do *op++ = *ip++; while (--t > 0);
93
787
        goto first_literal_run;
94
1.45k
    }
95
96
2.34k
    for (;;)
97
781k
    {
98
781k
        NEED_IP(3);
99
781k
        t = *ip++;
100
781k
        if (t >= 16)
101
540k
            goto match;
102
        /* a literal run */
103
241k
        if (t == 0)
104
68.4k
        {
105
540k
            while (*ip == 0)
106
471k
            {
107
471k
                t += 255;
108
471k
                ip++;
109
471k
                TEST_IV(t);
110
471k
                NEED_IP(1);
111
471k
            }
112
68.4k
            t += 15 + *ip++;
113
68.4k
        }
114
        /* copy literals */
115
241k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
241k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
241k
        t += 3;
118
241k
        if (t >= 8) do
119
15.6M
        {
120
15.6M
            UA_COPY8(op,ip);
121
15.6M
            op += 8; ip += 8; t -= 8;
122
15.6M
        } while (t >= 8);
123
241k
        if (t >= 4)
124
154k
        {
125
154k
            UA_COPY4(op,ip);
126
154k
            op += 4; ip += 4; t -= 4;
127
154k
        }
128
241k
        if (t > 0)
129
158k
        {
130
158k
            *op++ = *ip++;
131
158k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
158k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
241k
first_literal_run:
167
168
169
241k
        t = *ip++;
170
241k
        if (t >= 16)
171
236k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
5.61k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
5.61k
        m_pos -= t >> 2;
189
5.61k
        m_pos -= *ip++ << 2;
190
5.61k
#endif
191
5.61k
        TEST_LB(m_pos); NEED_OP(3);
192
5.61k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
5.61k
#endif /* COPY_DICT */
194
5.61k
        goto match_done;
195
196
197
        /* handle matches */
198
696k
        for (;;) {
199
1.47M
match:
200
1.47M
            if (t >= 64)                /* a M2 match */
201
644k
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
644k
#if defined(LZO1X)
222
644k
                m_pos = op - 1;
223
644k
                m_pos -= (t >> 2) & 7;
224
644k
                m_pos -= *ip++ << 3;
225
644k
                t = (t >> 5) - 1;
226
#elif defined(LZO1Y)
227
                m_pos = op - 1;
228
                m_pos -= (t >> 2) & 3;
229
                m_pos -= *ip++ << 2;
230
                t = (t >> 4) - 3;
231
#elif defined(LZO1Z)
232
                {
233
                    lzo_uint off = t & 0x1f;
234
                    m_pos = op;
235
                    if (off >= 0x1c)
236
                    {
237
                        assert(last_m_off > 0);
238
                        m_pos -= last_m_off;
239
                    }
240
                    else
241
                    {
242
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
                        m_pos -= off;
244
                        last_m_off = off;
245
                    }
246
                }
247
                t = (t >> 5) - 1;
248
#endif
249
644k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
644k
                goto copy_match;
251
644k
#endif /* COPY_DICT */
252
644k
            }
253
828k
            else if (t >= 32)           /* a M3 match */
254
486k
            {
255
486k
                t &= 31;
256
486k
                if (t == 0)
257
107k
                {
258
223k
                    while (*ip == 0)
259
115k
                    {
260
115k
                        t += 255;
261
115k
                        ip++;
262
115k
                        TEST_OV(t);
263
115k
                        NEED_IP(1);
264
115k
                    }
265
107k
                    t += 31 + *ip++;
266
107k
                    NEED_IP(2);
267
107k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
                {
278
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
                    m_pos = op - off;
280
                    last_m_off = off;
281
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
                m_pos = op - 1;
284
486k
                m_pos -= UA_GET_LE16(ip) >> 2;
285
#else
286
                m_pos = op - 1;
287
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
288
#endif
289
486k
#endif /* COPY_DICT */
290
486k
                ip += 2;
291
486k
            }
292
341k
            else if (t >= 16)           /* a M4 match */
293
96.8k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
96.8k
                m_pos = op;
298
96.8k
                m_pos -= (t & 8) << 11;
299
96.8k
#endif /* COPY_DICT */
300
96.8k
                t &= 7;
301
96.8k
                if (t == 0)
302
33.4k
                {
303
57.9k
                    while (*ip == 0)
304
24.5k
                    {
305
24.5k
                        t += 255;
306
24.5k
                        ip++;
307
24.5k
                        TEST_OV(t);
308
24.5k
                        NEED_IP(1);
309
24.5k
                    }
310
33.4k
                    t += 7 + *ip++;
311
33.4k
                    NEED_IP(2);
312
33.4k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
96.8k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
96.8k
                ip += 2;
335
96.8k
                if (m_pos == op)
336
3.80k
                    goto eof_found;
337
93.0k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
93.0k
#endif /* COPY_DICT */
342
93.0k
            }
343
245k
            else                            /* a M1 match */
344
245k
            {
345
#if defined(COPY_DICT)
346
#if defined(LZO1Z)
347
                m_off = 1 + (t << 6) + (*ip++ >> 2);
348
                last_m_off = m_off;
349
#else
350
                m_off = 1 + (t >> 2) + (*ip++ << 2);
351
#endif
352
                NEED_OP(2);
353
                t = 2; COPY_DICT(t,m_off)
354
#else /* !COPY_DICT */
355
#if defined(LZO1Z)
356
                t = 1 + (t << 6) + (*ip++ >> 2);
357
                m_pos = op - t;
358
                last_m_off = t;
359
#else
360
245k
                m_pos = op - 1;
361
245k
                m_pos -= t >> 2;
362
245k
                m_pos -= *ip++ << 2;
363
245k
#endif
364
245k
                TEST_LB(m_pos); NEED_OP(2);
365
245k
                *op++ = *m_pos++; *op++ = *m_pos;
366
245k
#endif /* COPY_DICT */
367
245k
                goto match_done;
368
245k
            }
369
370
            /* copy match */
371
#if defined(COPY_DICT)
372
373
            NEED_OP(t+3-1);
374
            t += 3-1; COPY_DICT(t,m_off)
375
376
#else /* !COPY_DICT */
377
378
579k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
579k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
579k
            if (op - m_pos >= 8)
381
542k
            {
382
542k
                t += (3 - 1);
383
542k
                if (t >= 8) do
384
4.05M
                {
385
4.05M
                    UA_COPY8(op,m_pos);
386
4.05M
                    op += 8; m_pos += 8; t -= 8;
387
4.05M
                } while (t >= 8);
388
542k
                if (t >= 4)
389
307k
                {
390
307k
                    UA_COPY4(op,m_pos);
391
307k
                    op += 4; m_pos += 4; t -= 4;
392
307k
                }
393
542k
                if (t > 0)
394
357k
                {
395
357k
                    *op++ = m_pos[0];
396
357k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
357k
                }
398
542k
            }
399
37.0k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
37.0k
            {
420
681k
copy_match:
421
681k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
19.4M
                do *op++ = *m_pos++; while (--t > 0);
423
681k
            }
424
425
579k
#endif /* COPY_DICT */
426
427
1.47M
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
1.47M
            t = ip[-2] & 3;
432
1.47M
#endif
433
1.47M
            if (t == 0)
434
779k
                break;
435
436
            /* copy literals */
437
696k
match_next:
438
696k
            assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
439
#if 0
440
            do *op++ = *ip++; while (--t > 0);
441
#else
442
696k
            *op++ = *ip++;
443
696k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
696k
#endif
445
696k
            t = *ip++;
446
696k
        }
447
0
    }
448
449
3.80k
eof_found:
450
3.80k
    *out_len = pd(op, out);
451
3.80k
    return (ip == ip_end ? LZO_E_OK :
452
3.80k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
#if defined(HAVE_NEED_IP)
456
input_overrun:
457
    *out_len = pd(op, out);
458
    return LZO_E_INPUT_OVERRUN;
459
#endif
460
461
#if defined(HAVE_NEED_OP)
462
output_overrun:
463
    *out_len = pd(op, out);
464
    return LZO_E_OUTPUT_OVERRUN;
465
#endif
466
467
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
lookbehind_overrun:
469
    *out_len = pd(op, out);
470
    return LZO_E_LOOKBEHIND_OVERRUN;
471
#endif
472
2.34k
}
lzo1y_decompress
Line
Count
Source
42
1.83k
{
43
1.83k
    lzo_bytep op;
44
1.83k
    const lzo_bytep ip;
45
1.83k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
1.83k
    const lzo_bytep m_pos;
51
1.83k
#endif
52
53
1.83k
    const lzo_bytep const ip_end = in + in_len;
54
#if defined(HAVE_ANY_OP)
55
    lzo_bytep const op_end = out + *out_len;
56
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
1.83k
    LZO_UNUSED(wrkmem);
62
63
#if defined(COPY_DICT)
64
    if (dict)
65
    {
66
        if (dict_len > M4_MAX_OFFSET)
67
        {
68
            dict += dict_len - M4_MAX_OFFSET;
69
            dict_len = M4_MAX_OFFSET;
70
        }
71
        dict_end = dict + dict_len;
72
    }
73
    else
74
    {
75
        dict_len = 0;
76
        dict_end = NULL;
77
    }
78
#endif /* COPY_DICT */
79
80
1.83k
    *out_len = 0;
81
82
1.83k
    op = out;
83
1.83k
    ip = in;
84
85
1.83k
    NEED_IP(1);
86
1.83k
    if (*ip > 17)
87
1.34k
    {
88
1.34k
        t = *ip++ - 17;
89
1.34k
        if (t < 4)
90
551
            goto match_next;
91
1.34k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
13.8k
        do *op++ = *ip++; while (--t > 0);
93
793
        goto first_literal_run;
94
1.34k
    }
95
96
489
    for (;;)
97
334k
    {
98
334k
        NEED_IP(3);
99
334k
        t = *ip++;
100
334k
        if (t >= 16)
101
252k
            goto match;
102
        /* a literal run */
103
82.2k
        if (t == 0)
104
31.0k
        {
105
169k
            while (*ip == 0)
106
138k
            {
107
138k
                t += 255;
108
138k
                ip++;
109
138k
                TEST_IV(t);
110
138k
                NEED_IP(1);
111
138k
            }
112
31.0k
            t += 15 + *ip++;
113
31.0k
        }
114
        /* copy literals */
115
82.2k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
82.2k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
82.2k
        t += 3;
118
82.2k
        if (t >= 8) do
119
4.72M
        {
120
4.72M
            UA_COPY8(op,ip);
121
4.72M
            op += 8; ip += 8; t -= 8;
122
4.72M
        } while (t >= 8);
123
82.2k
        if (t >= 4)
124
51.4k
        {
125
51.4k
            UA_COPY4(op,ip);
126
51.4k
            op += 4; ip += 4; t -= 4;
127
51.4k
        }
128
82.2k
        if (t > 0)
129
54.5k
        {
130
54.5k
            *op++ = *ip++;
131
54.5k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
54.5k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
83.0k
first_literal_run:
167
168
169
83.0k
        t = *ip++;
170
83.0k
        if (t >= 16)
171
78.0k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
5.04k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
5.04k
        m_pos -= t >> 2;
189
5.04k
        m_pos -= *ip++ << 2;
190
5.04k
#endif
191
5.04k
        TEST_LB(m_pos); NEED_OP(3);
192
5.04k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
5.04k
#endif /* COPY_DICT */
194
5.04k
        goto match_done;
195
196
197
        /* handle matches */
198
639k
        for (;;) {
199
969k
match:
200
969k
            if (t >= 64)                /* a M2 match */
201
327k
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
#if defined(LZO1X)
222
                m_pos = op - 1;
223
                m_pos -= (t >> 2) & 7;
224
                m_pos -= *ip++ << 3;
225
                t = (t >> 5) - 1;
226
#elif defined(LZO1Y)
227
                m_pos = op - 1;
228
327k
                m_pos -= (t >> 2) & 3;
229
327k
                m_pos -= *ip++ << 2;
230
327k
                t = (t >> 4) - 3;
231
#elif defined(LZO1Z)
232
                {
233
                    lzo_uint off = t & 0x1f;
234
                    m_pos = op;
235
                    if (off >= 0x1c)
236
                    {
237
                        assert(last_m_off > 0);
238
                        m_pos -= last_m_off;
239
                    }
240
                    else
241
                    {
242
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
                        m_pos -= off;
244
                        last_m_off = off;
245
                    }
246
                }
247
                t = (t >> 5) - 1;
248
#endif
249
327k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
327k
                goto copy_match;
251
327k
#endif /* COPY_DICT */
252
327k
            }
253
642k
            else if (t >= 32)           /* a M3 match */
254
241k
            {
255
241k
                t &= 31;
256
241k
                if (t == 0)
257
53.9k
                {
258
106k
                    while (*ip == 0)
259
53.0k
                    {
260
53.0k
                        t += 255;
261
53.0k
                        ip++;
262
53.0k
                        TEST_OV(t);
263
53.0k
                        NEED_IP(1);
264
53.0k
                    }
265
53.9k
                    t += 31 + *ip++;
266
53.9k
                    NEED_IP(2);
267
53.9k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
                {
278
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
                    m_pos = op - off;
280
                    last_m_off = off;
281
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
                m_pos = op - 1;
284
241k
                m_pos -= UA_GET_LE16(ip) >> 2;
285
#else
286
                m_pos = op - 1;
287
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
288
#endif
289
241k
#endif /* COPY_DICT */
290
241k
                ip += 2;
291
241k
            }
292
400k
            else if (t >= 16)           /* a M4 match */
293
55.8k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
55.8k
                m_pos = op;
298
55.8k
                m_pos -= (t & 8) << 11;
299
55.8k
#endif /* COPY_DICT */
300
55.8k
                t &= 7;
301
55.8k
                if (t == 0)
302
18.3k
                {
303
30.0k
                    while (*ip == 0)
304
11.6k
                    {
305
11.6k
                        t += 255;
306
11.6k
                        ip++;
307
11.6k
                        TEST_OV(t);
308
11.6k
                        NEED_IP(1);
309
11.6k
                    }
310
18.3k
                    t += 7 + *ip++;
311
18.3k
                    NEED_IP(2);
312
18.3k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
55.8k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
55.8k
                ip += 2;
335
55.8k
                if (m_pos == op)
336
1.83k
                    goto eof_found;
337
54.0k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
54.0k
#endif /* COPY_DICT */
342
54.0k
            }
343
344k
            else                            /* a M1 match */
344
344k
            {
345
#if defined(COPY_DICT)
346
#if defined(LZO1Z)
347
                m_off = 1 + (t << 6) + (*ip++ >> 2);
348
                last_m_off = m_off;
349
#else
350
                m_off = 1 + (t >> 2) + (*ip++ << 2);
351
#endif
352
                NEED_OP(2);
353
                t = 2; COPY_DICT(t,m_off)
354
#else /* !COPY_DICT */
355
#if defined(LZO1Z)
356
                t = 1 + (t << 6) + (*ip++ >> 2);
357
                m_pos = op - t;
358
                last_m_off = t;
359
#else
360
344k
                m_pos = op - 1;
361
344k
                m_pos -= t >> 2;
362
344k
                m_pos -= *ip++ << 2;
363
344k
#endif
364
344k
                TEST_LB(m_pos); NEED_OP(2);
365
344k
                *op++ = *m_pos++; *op++ = *m_pos;
366
344k
#endif /* COPY_DICT */
367
344k
                goto match_done;
368
344k
            }
369
370
            /* copy match */
371
#if defined(COPY_DICT)
372
373
            NEED_OP(t+3-1);
374
            t += 3-1; COPY_DICT(t,m_off)
375
376
#else /* !COPY_DICT */
377
378
296k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
296k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
296k
            if (op - m_pos >= 8)
381
282k
            {
382
282k
                t += (3 - 1);
383
282k
                if (t >= 8) do
384
1.68M
                {
385
1.68M
                    UA_COPY8(op,m_pos);
386
1.68M
                    op += 8; m_pos += 8; t -= 8;
387
1.68M
                } while (t >= 8);
388
282k
                if (t >= 4)
389
157k
                {
390
157k
                    UA_COPY4(op,m_pos);
391
157k
                    op += 4; m_pos += 4; t -= 4;
392
157k
                }
393
282k
                if (t > 0)
394
191k
                {
395
191k
                    *op++ = m_pos[0];
396
191k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
191k
                }
398
282k
            }
399
13.5k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
13.5k
            {
420
340k
copy_match:
421
340k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
11.0M
                do *op++ = *m_pos++; while (--t > 0);
423
340k
            }
424
425
296k
#endif /* COPY_DICT */
426
427
972k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
972k
            t = ip[-2] & 3;
432
972k
#endif
433
972k
            if (t == 0)
434
334k
                break;
435
436
            /* copy literals */
437
639k
match_next:
438
639k
            assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
439
#if 0
440
            do *op++ = *ip++; while (--t > 0);
441
#else
442
639k
            *op++ = *ip++;
443
639k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
639k
#endif
445
639k
            t = *ip++;
446
639k
        }
447
0
    }
448
449
1.83k
eof_found:
450
1.83k
    *out_len = pd(op, out);
451
1.83k
    return (ip == ip_end ? LZO_E_OK :
452
1.83k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
#if defined(HAVE_NEED_IP)
456
input_overrun:
457
    *out_len = pd(op, out);
458
    return LZO_E_INPUT_OVERRUN;
459
#endif
460
461
#if defined(HAVE_NEED_OP)
462
output_overrun:
463
    *out_len = pd(op, out);
464
    return LZO_E_OUTPUT_OVERRUN;
465
#endif
466
467
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
lookbehind_overrun:
469
    *out_len = pd(op, out);
470
    return LZO_E_LOOKBEHIND_OVERRUN;
471
#endif
472
489
}
lzo1z_decompress
Line
Count
Source
42
1.69k
{
43
1.69k
    lzo_bytep op;
44
1.69k
    const lzo_bytep ip;
45
1.69k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
1.69k
    const lzo_bytep m_pos;
51
1.69k
#endif
52
53
1.69k
    const lzo_bytep const ip_end = in + in_len;
54
#if defined(HAVE_ANY_OP)
55
    lzo_bytep const op_end = out + *out_len;
56
#endif
57
1.69k
#if defined(LZO1Z)
58
1.69k
    lzo_uint last_m_off = 0;
59
1.69k
#endif
60
61
1.69k
    LZO_UNUSED(wrkmem);
62
63
#if defined(COPY_DICT)
64
    if (dict)
65
    {
66
        if (dict_len > M4_MAX_OFFSET)
67
        {
68
            dict += dict_len - M4_MAX_OFFSET;
69
            dict_len = M4_MAX_OFFSET;
70
        }
71
        dict_end = dict + dict_len;
72
    }
73
    else
74
    {
75
        dict_len = 0;
76
        dict_end = NULL;
77
    }
78
#endif /* COPY_DICT */
79
80
1.69k
    *out_len = 0;
81
82
1.69k
    op = out;
83
1.69k
    ip = in;
84
85
1.69k
    NEED_IP(1);
86
1.69k
    if (*ip > 17)
87
1.63k
    {
88
1.63k
        t = *ip++ - 17;
89
1.63k
        if (t < 4)
90
710
            goto match_next;
91
1.63k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
17.3k
        do *op++ = *ip++; while (--t > 0);
93
926
        goto first_literal_run;
94
1.63k
    }
95
96
54
    for (;;)
97
381k
    {
98
381k
        NEED_IP(3);
99
381k
        t = *ip++;
100
381k
        if (t >= 16)
101
293k
            goto match;
102
        /* a literal run */
103
87.8k
        if (t == 0)
104
24.7k
        {
105
57.3k
            while (*ip == 0)
106
32.5k
            {
107
32.5k
                t += 255;
108
32.5k
                ip++;
109
32.5k
                TEST_IV(t);
110
32.5k
                NEED_IP(1);
111
32.5k
            }
112
24.7k
            t += 15 + *ip++;
113
24.7k
        }
114
        /* copy literals */
115
87.8k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
87.8k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
87.8k
        t += 3;
118
87.8k
        if (t >= 8) do
119
1.25M
        {
120
1.25M
            UA_COPY8(op,ip);
121
1.25M
            op += 8; ip += 8; t -= 8;
122
1.25M
        } while (t >= 8);
123
87.8k
        if (t >= 4)
124
56.6k
        {
125
56.6k
            UA_COPY4(op,ip);
126
56.6k
            op += 4; ip += 4; t -= 4;
127
56.6k
        }
128
87.8k
        if (t > 0)
129
60.2k
        {
130
60.2k
            *op++ = *ip++;
131
60.2k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
60.2k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
88.8k
first_literal_run:
167
168
169
88.8k
        t = *ip++;
170
88.8k
        if (t >= 16)
171
83.1k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
5.63k
#if defined(LZO1Z)
183
5.63k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
5.63k
        m_pos = op - t;
185
5.63k
        last_m_off = t;
186
#else
187
        m_pos = op - (1 + M2_MAX_OFFSET);
188
        m_pos -= t >> 2;
189
        m_pos -= *ip++ << 2;
190
#endif
191
5.63k
        TEST_LB(m_pos); NEED_OP(3);
192
5.63k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
5.63k
#endif /* COPY_DICT */
194
5.63k
        goto match_done;
195
196
197
        /* handle matches */
198
831k
        for (;;) {
199
1.20M
match:
200
1.20M
            if (t >= 64)                /* a M2 match */
201
384k
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
#if defined(LZO1X)
222
                m_pos = op - 1;
223
                m_pos -= (t >> 2) & 7;
224
                m_pos -= *ip++ << 3;
225
                t = (t >> 5) - 1;
226
#elif defined(LZO1Y)
227
                m_pos = op - 1;
228
                m_pos -= (t >> 2) & 3;
229
                m_pos -= *ip++ << 2;
230
                t = (t >> 4) - 3;
231
#elif defined(LZO1Z)
232
                {
233
384k
                    lzo_uint off = t & 0x1f;
234
384k
                    m_pos = op;
235
384k
                    if (off >= 0x1c)
236
19.5k
                    {
237
19.5k
                        assert(last_m_off > 0);
238
19.5k
                        m_pos -= last_m_off;
239
19.5k
                    }
240
365k
                    else
241
365k
                    {
242
365k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
365k
                        m_pos -= off;
244
365k
                        last_m_off = off;
245
365k
                    }
246
384k
                }
247
384k
                t = (t >> 5) - 1;
248
384k
#endif
249
384k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
384k
                goto copy_match;
251
384k
#endif /* COPY_DICT */
252
384k
            }
253
823k
            else if (t >= 32)           /* a M3 match */
254
291k
            {
255
291k
                t &= 31;
256
291k
                if (t == 0)
257
48.2k
                {
258
85.4k
                    while (*ip == 0)
259
37.1k
                    {
260
37.1k
                        t += 255;
261
37.1k
                        ip++;
262
37.1k
                        TEST_OV(t);
263
37.1k
                        NEED_IP(1);
264
37.1k
                    }
265
48.2k
                    t += 31 + *ip++;
266
48.2k
                    NEED_IP(2);
267
48.2k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
291k
#if defined(LZO1Z)
277
291k
                {
278
291k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
291k
                    m_pos = op - off;
280
291k
                    last_m_off = off;
281
291k
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
                m_pos = op - 1;
284
                m_pos -= UA_GET_LE16(ip) >> 2;
285
#else
286
                m_pos = op - 1;
287
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
288
#endif
289
291k
#endif /* COPY_DICT */
290
291k
                ip += 2;
291
291k
            }
292
532k
            else if (t >= 16)           /* a M4 match */
293
181k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
181k
                m_pos = op;
298
181k
                m_pos -= (t & 8) << 11;
299
181k
#endif /* COPY_DICT */
300
181k
                t &= 7;
301
181k
                if (t == 0)
302
46.0k
                {
303
55.4k
                    while (*ip == 0)
304
9.36k
                    {
305
9.36k
                        t += 255;
306
9.36k
                        ip++;
307
9.36k
                        TEST_OV(t);
308
9.36k
                        NEED_IP(1);
309
9.36k
                    }
310
46.0k
                    t += 7 + *ip++;
311
46.0k
                    NEED_IP(2);
312
46.0k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
181k
#if defined(LZO1Z)
328
181k
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
181k
                ip += 2;
335
181k
                if (m_pos == op)
336
1.69k
                    goto eof_found;
337
180k
                m_pos -= 0x4000;
338
180k
#if defined(LZO1Z)
339
180k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
180k
#endif
341
180k
#endif /* COPY_DICT */
342
180k
            }
343
350k
            else                            /* a M1 match */
344
350k
            {
345
#if defined(COPY_DICT)
346
#if defined(LZO1Z)
347
                m_off = 1 + (t << 6) + (*ip++ >> 2);
348
                last_m_off = m_off;
349
#else
350
                m_off = 1 + (t >> 2) + (*ip++ << 2);
351
#endif
352
                NEED_OP(2);
353
                t = 2; COPY_DICT(t,m_off)
354
#else /* !COPY_DICT */
355
350k
#if defined(LZO1Z)
356
350k
                t = 1 + (t << 6) + (*ip++ >> 2);
357
350k
                m_pos = op - t;
358
350k
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
350k
                TEST_LB(m_pos); NEED_OP(2);
365
350k
                *op++ = *m_pos++; *op++ = *m_pos;
366
350k
#endif /* COPY_DICT */
367
350k
                goto match_done;
368
350k
            }
369
370
            /* copy match */
371
#if defined(COPY_DICT)
372
373
            NEED_OP(t+3-1);
374
            t += 3-1; COPY_DICT(t,m_off)
375
376
#else /* !COPY_DICT */
377
378
471k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
471k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
471k
            if (op - m_pos >= 8)
381
455k
            {
382
455k
                t += (3 - 1);
383
455k
                if (t >= 8) do
384
1.66M
                {
385
1.66M
                    UA_COPY8(op,m_pos);
386
1.66M
                    op += 8; m_pos += 8; t -= 8;
387
1.66M
                } while (t >= 8);
388
455k
                if (t >= 4)
389
182k
                {
390
182k
                    UA_COPY4(op,m_pos);
391
182k
                    op += 4; m_pos += 4; t -= 4;
392
182k
                }
393
455k
                if (t > 0)
394
360k
                {
395
360k
                    *op++ = m_pos[0];
396
360k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
360k
                }
398
455k
            }
399
16.3k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
16.3k
            {
420
401k
copy_match:
421
401k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
7.09M
                do *op++ = *m_pos++; while (--t > 0);
423
401k
            }
424
425
471k
#endif /* COPY_DICT */
426
427
1.21M
match_done:
428
1.21M
#if defined(LZO1Z)
429
1.21M
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
1.21M
            if (t == 0)
434
381k
                break;
435
436
            /* copy literals */
437
831k
match_next:
438
831k
            assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
439
#if 0
440
            do *op++ = *ip++; while (--t > 0);
441
#else
442
831k
            *op++ = *ip++;
443
831k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
831k
#endif
445
831k
            t = *ip++;
446
831k
        }
447
0
    }
448
449
1.69k
eof_found:
450
1.69k
    *out_len = pd(op, out);
451
1.69k
    return (ip == ip_end ? LZO_E_OK :
452
1.69k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
#if defined(HAVE_NEED_IP)
456
input_overrun:
457
    *out_len = pd(op, out);
458
    return LZO_E_INPUT_OVERRUN;
459
#endif
460
461
#if defined(HAVE_NEED_OP)
462
output_overrun:
463
    *out_len = pd(op, out);
464
    return LZO_E_OUTPUT_OVERRUN;
465
#endif
466
467
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
lookbehind_overrun:
469
    *out_len = pd(op, out);
470
    return LZO_E_LOOKBEHIND_OVERRUN;
471
#endif
472
54
}
lzo1x_decompress_safe
Line
Count
Source
42
571
{
43
571
    lzo_bytep op;
44
571
    const lzo_bytep ip;
45
571
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
571
    const lzo_bytep m_pos;
51
571
#endif
52
53
571
    const lzo_bytep const ip_end = in + in_len;
54
571
#if defined(HAVE_ANY_OP)
55
571
    lzo_bytep const op_end = out + *out_len;
56
571
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
571
    LZO_UNUSED(wrkmem);
62
63
#if defined(COPY_DICT)
64
    if (dict)
65
    {
66
        if (dict_len > M4_MAX_OFFSET)
67
        {
68
            dict += dict_len - M4_MAX_OFFSET;
69
            dict_len = M4_MAX_OFFSET;
70
        }
71
        dict_end = dict + dict_len;
72
    }
73
    else
74
    {
75
        dict_len = 0;
76
        dict_end = NULL;
77
    }
78
#endif /* COPY_DICT */
79
80
571
    *out_len = 0;
81
82
571
    op = out;
83
571
    ip = in;
84
85
571
    NEED_IP(1);
86
571
    if (*ip > 17)
87
320
    {
88
320
        t = *ip++ - 17;
89
320
        if (t < 4)
90
232
            goto match_next;
91
320
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
2.01k
        do *op++ = *ip++; while (--t > 0);
93
77
        goto first_literal_run;
94
88
    }
95
96
251
    for (;;)
97
84.4k
    {
98
84.4k
        NEED_IP(3);
99
84.4k
        t = *ip++;
100
84.4k
        if (t >= 16)
101
67.4k
            goto match;
102
        /* a literal run */
103
16.9k
        if (t == 0)
104
9.54k
        {
105
4.09M
            while (*ip == 0)
106
4.08M
            {
107
4.08M
                t += 255;
108
4.08M
                ip++;
109
4.08M
                TEST_IV(t);
110
4.08M
                NEED_IP(1);
111
4.08M
            }
112
9.51k
            t += 15 + *ip++;
113
9.51k
        }
114
        /* copy literals */
115
16.9k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
16.8k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
16.8k
        t += 3;
118
16.8k
        if (t >= 8) do
119
296k
        {
120
296k
            UA_COPY8(op,ip);
121
296k
            op += 8; ip += 8; t -= 8;
122
296k
        } while (t >= 8);
123
16.8k
        if (t >= 4)
124
9.28k
        {
125
9.28k
            UA_COPY4(op,ip);
126
9.28k
            op += 4; ip += 4; t -= 4;
127
9.28k
        }
128
16.8k
        if (t > 0)
129
13.1k
        {
130
13.1k
            *op++ = *ip++;
131
13.1k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
13.1k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
16.8k
first_literal_run:
167
168
169
16.8k
        t = *ip++;
170
16.8k
        if (t >= 16)
171
7.31k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
9.58k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
9.58k
        m_pos -= t >> 2;
189
9.58k
        m_pos -= *ip++ << 2;
190
9.58k
#endif
191
9.58k
        TEST_LB(m_pos); NEED_OP(3);
192
9.55k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
9.55k
#endif /* COPY_DICT */
194
9.55k
        goto match_done;
195
196
197
        /* handle matches */
198
110k
        for (;;) {
199
185k
match:
200
185k
            if (t >= 64)                /* a M2 match */
201
98.8k
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
98.8k
#if defined(LZO1X)
222
98.8k
                m_pos = op - 1;
223
98.8k
                m_pos -= (t >> 2) & 7;
224
98.8k
                m_pos -= *ip++ << 3;
225
98.8k
                t = (t >> 5) - 1;
226
#elif defined(LZO1Y)
227
                m_pos = op - 1;
228
                m_pos -= (t >> 2) & 3;
229
                m_pos -= *ip++ << 2;
230
                t = (t >> 4) - 3;
231
#elif defined(LZO1Z)
232
                {
233
                    lzo_uint off = t & 0x1f;
234
                    m_pos = op;
235
                    if (off >= 0x1c)
236
                    {
237
                        assert(last_m_off > 0);
238
                        m_pos -= last_m_off;
239
                    }
240
                    else
241
                    {
242
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
                        m_pos -= off;
244
                        last_m_off = off;
245
                    }
246
                }
247
                t = (t >> 5) - 1;
248
#endif
249
98.8k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
98.7k
                goto copy_match;
251
98.7k
#endif /* COPY_DICT */
252
98.7k
            }
253
86.7k
            else if (t >= 32)           /* a M3 match */
254
40.1k
            {
255
40.1k
                t &= 31;
256
40.1k
                if (t == 0)
257
3.29k
                {
258
1.45M
                    while (*ip == 0)
259
1.45M
                    {
260
1.45M
                        t += 255;
261
1.45M
                        ip++;
262
1.45M
                        TEST_OV(t);
263
1.45M
                        NEED_IP(1);
264
1.45M
                    }
265
3.28k
                    t += 31 + *ip++;
266
3.28k
                    NEED_IP(2);
267
3.28k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
                {
278
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
                    m_pos = op - off;
280
                    last_m_off = off;
281
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
40.1k
                m_pos = op - 1;
284
40.1k
                m_pos -= UA_GET_LE16(ip) >> 2;
285
#else
286
                m_pos = op - 1;
287
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
288
#endif
289
40.1k
#endif /* COPY_DICT */
290
40.1k
                ip += 2;
291
40.1k
            }
292
46.5k
            else if (t >= 16)           /* a M4 match */
293
10.5k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
10.5k
                m_pos = op;
298
10.5k
                m_pos -= (t & 8) << 11;
299
10.5k
#endif /* COPY_DICT */
300
10.5k
                t &= 7;
301
10.5k
                if (t == 0)
302
2.78k
                {
303
1.84M
                    while (*ip == 0)
304
1.83M
                    {
305
1.83M
                        t += 255;
306
1.83M
                        ip++;
307
1.83M
                        TEST_OV(t);
308
1.83M
                        NEED_IP(1);
309
1.83M
                    }
310
2.77k
                    t += 7 + *ip++;
311
2.77k
                    NEED_IP(2);
312
2.77k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
10.5k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
10.5k
                ip += 2;
335
10.5k
                if (m_pos == op)
336
17
                    goto eof_found;
337
10.5k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
10.5k
#endif /* COPY_DICT */
342
10.5k
            }
343
36.0k
            else                            /* a M1 match */
344
36.0k
            {
345
#if defined(COPY_DICT)
346
#if defined(LZO1Z)
347
                m_off = 1 + (t << 6) + (*ip++ >> 2);
348
                last_m_off = m_off;
349
#else
350
                m_off = 1 + (t >> 2) + (*ip++ << 2);
351
#endif
352
                NEED_OP(2);
353
                t = 2; COPY_DICT(t,m_off)
354
#else /* !COPY_DICT */
355
#if defined(LZO1Z)
356
                t = 1 + (t << 6) + (*ip++ >> 2);
357
                m_pos = op - t;
358
                last_m_off = t;
359
#else
360
36.0k
                m_pos = op - 1;
361
36.0k
                m_pos -= t >> 2;
362
36.0k
                m_pos -= *ip++ << 2;
363
36.0k
#endif
364
36.0k
                TEST_LB(m_pos); NEED_OP(2);
365
36.0k
                *op++ = *m_pos++; *op++ = *m_pos;
366
36.0k
#endif /* COPY_DICT */
367
36.0k
                goto match_done;
368
36.0k
            }
369
370
            /* copy match */
371
#if defined(COPY_DICT)
372
373
            NEED_OP(t+3-1);
374
            t += 3-1; COPY_DICT(t,m_off)
375
376
#else /* !COPY_DICT */
377
378
50.6k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
50.5k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
50.5k
            if (op - m_pos >= 8)
381
47.4k
            {
382
47.4k
                t += (3 - 1);
383
47.4k
                if (t >= 8) do
384
699k
                {
385
699k
                    UA_COPY8(op,m_pos);
386
699k
                    op += 8; m_pos += 8; t -= 8;
387
699k
                } while (t >= 8);
388
47.4k
                if (t >= 4)
389
30.0k
                {
390
30.0k
                    UA_COPY4(op,m_pos);
391
30.0k
                    op += 4; m_pos += 4; t -= 4;
392
30.0k
                }
393
47.4k
                if (t > 0)
394
37.4k
                {
395
37.4k
                    *op++ = m_pos[0];
396
37.4k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
37.4k
                }
398
47.4k
            }
399
3.15k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
3.15k
            {
420
101k
copy_match:
421
101k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
11.9M
                do *op++ = *m_pos++; while (--t > 0);
423
101k
            }
424
425
50.5k
#endif /* COPY_DICT */
426
427
194k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
194k
            t = ip[-2] & 3;
432
194k
#endif
433
194k
            if (t == 0)
434
84.2k
                break;
435
436
            /* copy literals */
437
110k
match_next:
438
110k
            assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
439
#if 0
440
            do *op++ = *ip++; while (--t > 0);
441
#else
442
110k
            *op++ = *ip++;
443
110k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
110k
#endif
445
110k
            t = *ip++;
446
110k
        }
447
0
    }
448
449
17
eof_found:
450
17
    *out_len = pd(op, out);
451
17
    return (ip == ip_end ? LZO_E_OK :
452
17
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
365
input_overrun:
457
365
    *out_len = pd(op, out);
458
365
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
63
output_overrun:
463
63
    *out_len = pd(op, out);
464
63
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
126
lookbehind_overrun:
469
126
    *out_len = pd(op, out);
470
126
    return LZO_E_LOOKBEHIND_OVERRUN;
471
251
#endif
472
251
}
lzo1y_decompress_safe
Line
Count
Source
42
569
{
43
569
    lzo_bytep op;
44
569
    const lzo_bytep ip;
45
569
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
569
    const lzo_bytep m_pos;
51
569
#endif
52
53
569
    const lzo_bytep const ip_end = in + in_len;
54
569
#if defined(HAVE_ANY_OP)
55
569
    lzo_bytep const op_end = out + *out_len;
56
569
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
569
    LZO_UNUSED(wrkmem);
62
63
#if defined(COPY_DICT)
64
    if (dict)
65
    {
66
        if (dict_len > M4_MAX_OFFSET)
67
        {
68
            dict += dict_len - M4_MAX_OFFSET;
69
            dict_len = M4_MAX_OFFSET;
70
        }
71
        dict_end = dict + dict_len;
72
    }
73
    else
74
    {
75
        dict_len = 0;
76
        dict_end = NULL;
77
    }
78
#endif /* COPY_DICT */
79
80
569
    *out_len = 0;
81
82
569
    op = out;
83
569
    ip = in;
84
85
569
    NEED_IP(1);
86
569
    if (*ip > 17)
87
318
    {
88
318
        t = *ip++ - 17;
89
318
        if (t < 4)
90
203
            goto match_next;
91
318
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
1.59k
        do *op++ = *ip++; while (--t > 0);
93
102
        goto first_literal_run;
94
115
    }
95
96
251
    for (;;)
97
82.2k
    {
98
82.2k
        NEED_IP(3);
99
82.2k
        t = *ip++;
100
82.2k
        if (t >= 16)
101
59.5k
            goto match;
102
        /* a literal run */
103
22.6k
        if (t == 0)
104
10.9k
        {
105
20.4M
            while (*ip == 0)
106
20.4M
            {
107
20.4M
                t += 255;
108
20.4M
                ip++;
109
20.4M
                TEST_IV(t);
110
20.4M
                NEED_IP(1);
111
20.4M
            }
112
10.9k
            t += 15 + *ip++;
113
10.9k
        }
114
        /* copy literals */
115
22.6k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
22.5k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
22.5k
        t += 3;
118
22.5k
        if (t >= 8) do
119
622k
        {
120
622k
            UA_COPY8(op,ip);
121
622k
            op += 8; ip += 8; t -= 8;
122
622k
        } while (t >= 8);
123
22.5k
        if (t >= 4)
124
14.1k
        {
125
14.1k
            UA_COPY4(op,ip);
126
14.1k
            op += 4; ip += 4; t -= 4;
127
14.1k
        }
128
22.5k
        if (t > 0)
129
16.8k
        {
130
16.8k
            *op++ = *ip++;
131
16.8k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
16.8k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
22.6k
first_literal_run:
167
168
169
22.6k
        t = *ip++;
170
22.6k
        if (t >= 16)
171
11.1k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
11.4k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
11.4k
        m_pos -= t >> 2;
189
11.4k
        m_pos -= *ip++ << 2;
190
11.4k
#endif
191
11.4k
        TEST_LB(m_pos); NEED_OP(3);
192
11.4k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
11.4k
#endif /* COPY_DICT */
194
11.4k
        goto match_done;
195
196
197
        /* handle matches */
198
119k
        for (;;) {
199
189k
match:
200
189k
            if (t >= 64)                /* a M2 match */
201
98.1k
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
#if defined(LZO1X)
222
                m_pos = op - 1;
223
                m_pos -= (t >> 2) & 7;
224
                m_pos -= *ip++ << 3;
225
                t = (t >> 5) - 1;
226
#elif defined(LZO1Y)
227
                m_pos = op - 1;
228
98.1k
                m_pos -= (t >> 2) & 3;
229
98.1k
                m_pos -= *ip++ << 2;
230
98.1k
                t = (t >> 4) - 3;
231
#elif defined(LZO1Z)
232
                {
233
                    lzo_uint off = t & 0x1f;
234
                    m_pos = op;
235
                    if (off >= 0x1c)
236
                    {
237
                        assert(last_m_off > 0);
238
                        m_pos -= last_m_off;
239
                    }
240
                    else
241
                    {
242
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
                        m_pos -= off;
244
                        last_m_off = off;
245
                    }
246
                }
247
                t = (t >> 5) - 1;
248
#endif
249
98.1k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
98.0k
                goto copy_match;
251
98.0k
#endif /* COPY_DICT */
252
98.0k
            }
253
91.5k
            else if (t >= 32)           /* a M3 match */
254
32.7k
            {
255
32.7k
                t &= 31;
256
32.7k
                if (t == 0)
257
3.40k
                {
258
15.7M
                    while (*ip == 0)
259
15.7M
                    {
260
15.7M
                        t += 255;
261
15.7M
                        ip++;
262
15.7M
                        TEST_OV(t);
263
15.7M
                        NEED_IP(1);
264
15.7M
                    }
265
3.38k
                    t += 31 + *ip++;
266
3.38k
                    NEED_IP(2);
267
3.38k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
                {
278
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
                    m_pos = op - off;
280
                    last_m_off = off;
281
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
32.6k
                m_pos = op - 1;
284
32.6k
                m_pos -= UA_GET_LE16(ip) >> 2;
285
#else
286
                m_pos = op - 1;
287
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
288
#endif
289
32.6k
#endif /* COPY_DICT */
290
32.6k
                ip += 2;
291
32.6k
            }
292
58.8k
            else if (t >= 16)           /* a M4 match */
293
11.7k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
11.7k
                m_pos = op;
298
11.7k
                m_pos -= (t & 8) << 11;
299
11.7k
#endif /* COPY_DICT */
300
11.7k
                t &= 7;
301
11.7k
                if (t == 0)
302
3.50k
                {
303
4.98M
                    while (*ip == 0)
304
4.98M
                    {
305
4.98M
                        t += 255;
306
4.98M
                        ip++;
307
4.98M
                        TEST_OV(t);
308
4.98M
                        NEED_IP(1);
309
4.98M
                    }
310
3.48k
                    t += 7 + *ip++;
311
3.48k
                    NEED_IP(2);
312
3.48k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
11.7k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
11.7k
                ip += 2;
335
11.7k
                if (m_pos == op)
336
11
                    goto eof_found;
337
11.7k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
11.7k
#endif /* COPY_DICT */
342
11.7k
            }
343
47.0k
            else                            /* a M1 match */
344
47.0k
            {
345
#if defined(COPY_DICT)
346
#if defined(LZO1Z)
347
                m_off = 1 + (t << 6) + (*ip++ >> 2);
348
                last_m_off = m_off;
349
#else
350
                m_off = 1 + (t >> 2) + (*ip++ << 2);
351
#endif
352
                NEED_OP(2);
353
                t = 2; COPY_DICT(t,m_off)
354
#else /* !COPY_DICT */
355
#if defined(LZO1Z)
356
                t = 1 + (t << 6) + (*ip++ >> 2);
357
                m_pos = op - t;
358
                last_m_off = t;
359
#else
360
47.0k
                m_pos = op - 1;
361
47.0k
                m_pos -= t >> 2;
362
47.0k
                m_pos -= *ip++ << 2;
363
47.0k
#endif
364
47.0k
                TEST_LB(m_pos); NEED_OP(2);
365
47.0k
                *op++ = *m_pos++; *op++ = *m_pos;
366
47.0k
#endif /* COPY_DICT */
367
47.0k
                goto match_done;
368
47.0k
            }
369
370
            /* copy match */
371
#if defined(COPY_DICT)
372
373
            NEED_OP(t+3-1);
374
            t += 3-1; COPY_DICT(t,m_off)
375
376
#else /* !COPY_DICT */
377
378
44.4k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
44.3k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
44.3k
            if (op - m_pos >= 8)
381
40.8k
            {
382
40.8k
                t += (3 - 1);
383
40.8k
                if (t >= 8) do
384
469k
                {
385
469k
                    UA_COPY8(op,m_pos);
386
469k
                    op += 8; m_pos += 8; t -= 8;
387
469k
                } while (t >= 8);
388
40.8k
                if (t >= 4)
389
22.0k
                {
390
22.0k
                    UA_COPY4(op,m_pos);
391
22.0k
                    op += 4; m_pos += 4; t -= 4;
392
22.0k
                }
393
40.8k
                if (t > 0)
394
32.5k
                {
395
32.5k
                    *op++ = m_pos[0];
396
32.5k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
32.5k
                }
398
40.8k
            }
399
3.48k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
3.48k
            {
420
101k
copy_match:
421
101k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
11.6M
                do *op++ = *m_pos++; while (--t > 0);
423
101k
            }
424
425
44.3k
#endif /* COPY_DICT */
426
427
200k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
200k
            t = ip[-2] & 3;
432
200k
#endif
433
200k
            if (t == 0)
434
82.0k
                break;
435
436
            /* copy literals */
437
119k
match_next:
438
119k
            assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
439
#if 0
440
            do *op++ = *ip++; while (--t > 0);
441
#else
442
119k
            *op++ = *ip++;
443
119k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
119k
#endif
445
119k
            t = *ip++;
446
119k
        }
447
0
    }
448
449
11
eof_found:
450
11
    *out_len = pd(op, out);
451
11
    return (ip == ip_end ? LZO_E_OK :
452
11
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
348
input_overrun:
457
348
    *out_len = pd(op, out);
458
348
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
64
output_overrun:
463
64
    *out_len = pd(op, out);
464
64
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
146
lookbehind_overrun:
469
146
    *out_len = pd(op, out);
470
146
    return LZO_E_LOOKBEHIND_OVERRUN;
471
251
#endif
472
251
}
lzo1z_decompress_safe
Line
Count
Source
42
560
{
43
560
    lzo_bytep op;
44
560
    const lzo_bytep ip;
45
560
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
560
    const lzo_bytep m_pos;
51
560
#endif
52
53
560
    const lzo_bytep const ip_end = in + in_len;
54
560
#if defined(HAVE_ANY_OP)
55
560
    lzo_bytep const op_end = out + *out_len;
56
560
#endif
57
560
#if defined(LZO1Z)
58
560
    lzo_uint last_m_off = 0;
59
560
#endif
60
61
560
    LZO_UNUSED(wrkmem);
62
63
#if defined(COPY_DICT)
64
    if (dict)
65
    {
66
        if (dict_len > M4_MAX_OFFSET)
67
        {
68
            dict += dict_len - M4_MAX_OFFSET;
69
            dict_len = M4_MAX_OFFSET;
70
        }
71
        dict_end = dict + dict_len;
72
    }
73
    else
74
    {
75
        dict_len = 0;
76
        dict_end = NULL;
77
    }
78
#endif /* COPY_DICT */
79
80
560
    *out_len = 0;
81
82
560
    op = out;
83
560
    ip = in;
84
85
560
    NEED_IP(1);
86
560
    if (*ip > 17)
87
378
    {
88
378
        t = *ip++ - 17;
89
378
        if (t < 4)
90
265
            goto match_next;
91
378
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
2.36k
        do *op++ = *ip++; while (--t > 0);
93
102
        goto first_literal_run;
94
113
    }
95
96
182
    for (;;)
97
49.4k
    {
98
49.4k
        NEED_IP(3);
99
49.4k
        t = *ip++;
100
49.4k
        if (t >= 16)
101
31.6k
            goto match;
102
        /* a literal run */
103
17.8k
        if (t == 0)
104
7.54k
        {
105
2.61M
            while (*ip == 0)
106
2.60M
            {
107
2.60M
                t += 255;
108
2.60M
                ip++;
109
2.60M
                TEST_IV(t);
110
2.60M
                NEED_IP(1);
111
2.60M
            }
112
7.52k
            t += 15 + *ip++;
113
7.52k
        }
114
        /* copy literals */
115
17.8k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
17.6k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
17.6k
        t += 3;
118
17.6k
        if (t >= 8) do
119
361k
        {
120
361k
            UA_COPY8(op,ip);
121
361k
            op += 8; ip += 8; t -= 8;
122
361k
        } while (t >= 8);
123
17.6k
        if (t >= 4)
124
9.33k
        {
125
9.33k
            UA_COPY4(op,ip);
126
9.33k
            op += 4; ip += 4; t -= 4;
127
9.33k
        }
128
17.6k
        if (t > 0)
129
10.4k
        {
130
10.4k
            *op++ = *ip++;
131
10.4k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
10.4k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
17.7k
first_literal_run:
167
168
169
17.7k
        t = *ip++;
170
17.7k
        if (t >= 16)
171
9.65k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
8.08k
#if defined(LZO1Z)
183
8.08k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
8.08k
        m_pos = op - t;
185
8.08k
        last_m_off = t;
186
#else
187
        m_pos = op - (1 + M2_MAX_OFFSET);
188
        m_pos -= t >> 2;
189
        m_pos -= *ip++ << 2;
190
#endif
191
8.08k
        TEST_LB(m_pos); NEED_OP(3);
192
8.04k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
8.04k
#endif /* COPY_DICT */
194
8.04k
        goto match_done;
195
196
197
        /* handle matches */
198
64.4k
        for (;;) {
199
105k
match:
200
105k
            if (t >= 64)                /* a M2 match */
201
63.4k
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
#if defined(LZO1X)
222
                m_pos = op - 1;
223
                m_pos -= (t >> 2) & 7;
224
                m_pos -= *ip++ << 3;
225
                t = (t >> 5) - 1;
226
#elif defined(LZO1Y)
227
                m_pos = op - 1;
228
                m_pos -= (t >> 2) & 3;
229
                m_pos -= *ip++ << 2;
230
                t = (t >> 4) - 3;
231
#elif defined(LZO1Z)
232
                {
233
63.4k
                    lzo_uint off = t & 0x1f;
234
63.4k
                    m_pos = op;
235
63.4k
                    if (off >= 0x1c)
236
10.3k
                    {
237
10.3k
                        assert(last_m_off > 0);
238
10.3k
                        m_pos -= last_m_off;
239
10.3k
                    }
240
53.1k
                    else
241
53.1k
                    {
242
53.1k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
53.1k
                        m_pos -= off;
244
53.1k
                        last_m_off = off;
245
53.1k
                    }
246
63.4k
                }
247
63.4k
                t = (t >> 5) - 1;
248
63.4k
#endif
249
63.4k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
63.4k
                goto copy_match;
251
63.4k
#endif /* COPY_DICT */
252
63.4k
            }
253
42.2k
            else if (t >= 32)           /* a M3 match */
254
23.2k
            {
255
23.2k
                t &= 31;
256
23.2k
                if (t == 0)
257
3.05k
                {
258
1.81M
                    while (*ip == 0)
259
1.81M
                    {
260
1.81M
                        t += 255;
261
1.81M
                        ip++;
262
1.81M
                        TEST_OV(t);
263
1.81M
                        NEED_IP(1);
264
1.81M
                    }
265
3.04k
                    t += 31 + *ip++;
266
3.04k
                    NEED_IP(2);
267
3.04k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
23.2k
#if defined(LZO1Z)
277
23.2k
                {
278
23.2k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
23.2k
                    m_pos = op - off;
280
23.2k
                    last_m_off = off;
281
23.2k
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
                m_pos = op - 1;
284
                m_pos -= UA_GET_LE16(ip) >> 2;
285
#else
286
                m_pos = op - 1;
287
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
288
#endif
289
23.2k
#endif /* COPY_DICT */
290
23.2k
                ip += 2;
291
23.2k
            }
292
18.9k
            else if (t >= 16)           /* a M4 match */
293
7.34k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
7.34k
                m_pos = op;
298
7.34k
                m_pos -= (t & 8) << 11;
299
7.34k
#endif /* COPY_DICT */
300
7.34k
                t &= 7;
301
7.34k
                if (t == 0)
302
2.74k
                {
303
3.86k
                    while (*ip == 0)
304
1.12k
                    {
305
1.12k
                        t += 255;
306
1.12k
                        ip++;
307
1.12k
                        TEST_OV(t);
308
1.12k
                        NEED_IP(1);
309
1.12k
                    }
310
2.74k
                    t += 7 + *ip++;
311
2.74k
                    NEED_IP(2);
312
2.74k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
7.33k
#if defined(LZO1Z)
328
7.33k
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
7.33k
                ip += 2;
335
7.33k
                if (m_pos == op)
336
12
                    goto eof_found;
337
7.32k
                m_pos -= 0x4000;
338
7.32k
#if defined(LZO1Z)
339
7.32k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
7.32k
#endif
341
7.32k
#endif /* COPY_DICT */
342
7.32k
            }
343
11.6k
            else                            /* a M1 match */
344
11.6k
            {
345
#if defined(COPY_DICT)
346
#if defined(LZO1Z)
347
                m_off = 1 + (t << 6) + (*ip++ >> 2);
348
                last_m_off = m_off;
349
#else
350
                m_off = 1 + (t >> 2) + (*ip++ << 2);
351
#endif
352
                NEED_OP(2);
353
                t = 2; COPY_DICT(t,m_off)
354
#else /* !COPY_DICT */
355
11.6k
#if defined(LZO1Z)
356
11.6k
                t = 1 + (t << 6) + (*ip++ >> 2);
357
11.6k
                m_pos = op - t;
358
11.6k
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
11.6k
                TEST_LB(m_pos); NEED_OP(2);
365
11.6k
                *op++ = *m_pos++; *op++ = *m_pos;
366
11.6k
#endif /* COPY_DICT */
367
11.6k
                goto match_done;
368
11.6k
            }
369
370
            /* copy match */
371
#if defined(COPY_DICT)
372
373
            NEED_OP(t+3-1);
374
            t += 3-1; COPY_DICT(t,m_off)
375
376
#else /* !COPY_DICT */
377
378
30.5k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
30.4k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
30.4k
            if (op - m_pos >= 8)
381
28.4k
            {
382
28.4k
                t += (3 - 1);
383
28.4k
                if (t >= 8) do
384
860k
                {
385
860k
                    UA_COPY8(op,m_pos);
386
860k
                    op += 8; m_pos += 8; t -= 8;
387
860k
                } while (t >= 8);
388
28.4k
                if (t >= 4)
389
13.8k
                {
390
13.8k
                    UA_COPY4(op,m_pos);
391
13.8k
                    op += 4; m_pos += 4; t -= 4;
392
13.8k
                }
393
28.4k
                if (t > 0)
394
21.7k
                {
395
21.7k
                    *op++ = m_pos[0];
396
21.7k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
21.7k
                }
398
28.4k
            }
399
2.02k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
2.02k
            {
420
65.4k
copy_match:
421
65.4k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
6.96M
                do *op++ = *m_pos++; while (--t > 0);
423
65.4k
            }
424
425
30.4k
#endif /* COPY_DICT */
426
427
113k
match_done:
428
113k
#if defined(LZO1Z)
429
113k
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
113k
            if (t == 0)
434
49.2k
                break;
435
436
            /* copy literals */
437
64.5k
match_next:
438
64.5k
            assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
439
#if 0
440
            do *op++ = *ip++; while (--t > 0);
441
#else
442
64.4k
            *op++ = *ip++;
443
64.4k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
64.4k
#endif
445
64.4k
            t = *ip++;
446
64.4k
        }
447
0
    }
448
449
12
eof_found:
450
12
    *out_len = pd(op, out);
451
12
    return (ip == ip_end ? LZO_E_OK :
452
12
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
357
input_overrun:
457
357
    *out_len = pd(op, out);
458
357
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
55
output_overrun:
463
55
    *out_len = pd(op, out);
464
55
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
136
lookbehind_overrun:
469
136
    *out_len = pd(op, out);
470
136
    return LZO_E_LOOKBEHIND_OVERRUN;
471
182
#endif
472
182
}
473
474
475
/* vim:set ts=4 sw=4 et: */