Coverage Report

Created: 2026-06-22 06:20

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
8.58k
{
43
8.58k
    lzo_bytep op;
44
8.58k
    const lzo_bytep ip;
45
8.58k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
8.58k
    const lzo_bytep m_pos;
51
8.58k
#endif
52
53
8.58k
    const lzo_bytep const ip_end = in + in_len;
54
#if defined(HAVE_ANY_OP)
55
1.89k
    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
8.58k
    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
8.58k
    *out_len = 0;
81
82
8.58k
    op = out;
83
8.58k
    ip = in;
84
85
8.58k
    NEED_IP(1);
86
8.58k
    if (*ip > 17)
87
5.61k
    {
88
5.61k
        t = *ip++ - 17;
89
5.61k
        if (t < 4)
90
2.76k
            goto match_next;
91
5.61k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
57.9k
        do *op++ = *ip++; while (--t > 0);
93
276
        goto first_literal_run;
94
314
    }
95
96
2.97k
    for (;;)
97
1.37M
    {
98
1.37M
        NEED_IP(3);
99
191k
        t = *ip++;
100
1.37M
        if (t >= 16)
101
1.02M
            goto match;
102
        /* a literal run */
103
341k
        if (t == 0)
104
125k
        {
105
26.2M
            while (*ip == 0)
106
26.1M
            {
107
26.1M
                t += 255;
108
26.1M
                ip++;
109
26.1M
                TEST_IV(t);
110
26.1M
                NEED_IP(1);
111
25.5M
            }
112
30.0k
            t += 15 + *ip++;
113
30.0k
        }
114
        /* copy literals */
115
341k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
52.0k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
52.0k
        t += 3;
118
341k
        if (t >= 8) do
119
19.4M
        {
120
19.4M
            UA_COPY8(op,ip);
121
19.4M
            op += 8; ip += 8; t -= 8;
122
19.4M
        } while (t >= 8);
123
341k
        if (t >= 4)
124
211k
        {
125
211k
            UA_COPY4(op,ip);
126
211k
            op += 4; ip += 4; t -= 4;
127
211k
        }
128
341k
        if (t > 0)
129
231k
        {
130
231k
            *op++ = *ip++;
131
231k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
231k
        }
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
344k
first_literal_run:
167
168
169
344k
        t = *ip++;
170
344k
        if (t >= 16)
171
304k
            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
9.93k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
3.15k
        m_pos = op - t;
185
3.15k
        last_m_off = t;
186
#else
187
29.8k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
        m_pos -= t >> 2;
189
        m_pos -= *ip++ << 2;
190
#endif
191
39.7k
        TEST_LB(m_pos); NEED_OP(3);
192
29.6k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
29.6k
#endif /* COPY_DICT */
194
29.6k
        goto match_done;
195
196
197
        /* handle matches */
198
2.20M
        for (;;) {
199
3.53M
match:
200
3.53M
            if (t >= 64)                /* a M2 match */
201
1.34M
            {
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
361k
                    if (off >= 0x1c)
236
25.0k
                    {
237
25.0k
                        assert(last_m_off > 0);
238
25.0k
                        m_pos -= last_m_off;
239
25.0k
                    }
240
336k
                    else
241
336k
                    {
242
336k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
336k
                        m_pos -= off;
244
336k
                        last_m_off = off;
245
336k
                    }
246
                }
247
                t = (t >> 5) - 1;
248
#endif
249
1.34M
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
245k
                goto copy_match;
251
245k
#endif /* COPY_DICT */
252
245k
            }
253
2.18M
            else if (t >= 32)           /* a M3 match */
254
931k
            {
255
931k
                t &= 31;
256
931k
                if (t == 0)
257
203k
                {
258
19.5M
                    while (*ip == 0)
259
19.3M
                    {
260
19.3M
                        t += 255;
261
19.3M
                        ip++;
262
19.3M
                        TEST_OV(t);
263
19.3M
                        NEED_IP(1);
264
19.1M
                    }
265
10.0k
                    t += 31 + *ip++;
266
203k
                    NEED_IP(2);
267
10.0k
                }
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
20.2k
                {
278
20.2k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
20.2k
                    m_pos = op - off;
280
20.2k
                    last_m_off = off;
281
20.2k
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
66.8k
                m_pos = op - 1;
284
701k
                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
66.8k
#endif /* COPY_DICT */
290
66.8k
                ip += 2;
291
66.8k
            }
292
1.25M
            else if (t >= 16)           /* a M4 match */
293
189k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
189k
                m_pos = op;
298
189k
                m_pos -= (t & 8) << 11;
299
189k
#endif /* COPY_DICT */
300
189k
                t &= 7;
301
189k
                if (t == 0)
302
63.9k
                {
303
8.04M
                    while (*ip == 0)
304
7.98M
                    {
305
7.98M
                        t += 255;
306
7.98M
                        ip++;
307
7.98M
                        TEST_OV(t);
308
7.98M
                        NEED_IP(1);
309
7.94M
                    }
310
7.64k
                    t += 7 + *ip++;
311
63.8k
                    NEED_IP(2);
312
7.64k
                }
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
6.35k
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
138k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
18.5k
                ip += 2;
335
189k
                if (m_pos == op)
336
6.74k
                    goto eof_found;
337
182k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
49.4k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
182k
#endif /* COPY_DICT */
342
182k
            }
343
1.06M
            else                            /* a M1 match */
344
1.06M
            {
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.06M
                TEST_LB(m_pos); NEED_OP(2);
365
119k
                *op++ = *m_pos++; *op++ = *m_pos;
366
119k
#endif /* COPY_DICT */
367
119k
                goto match_done;
368
119k
            }
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.11M
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
111k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
1.11M
            if (op - m_pos >= 8)
381
1.04M
            {
382
1.04M
                t += (3 - 1);
383
1.04M
                if (t >= 8) do
384
8.37M
                {
385
8.37M
                    UA_COPY8(op,m_pos);
386
8.37M
                    op += 8; m_pos += 8; t -= 8;
387
8.37M
                } while (t >= 8);
388
1.04M
                if (t >= 4)
389
516k
                {
390
516k
                    UA_COPY4(op,m_pos);
391
516k
                    op += 4; m_pos += 4; t -= 4;
392
516k
                }
393
1.04M
                if (t > 0)
394
755k
                {
395
755k
                    *op++ = m_pos[0];
396
755k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
755k
                }
398
1.04M
            }
399
69.9k
            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
69.9k
            {
420
1.41M
copy_match:
421
1.41M
                *op++ = *m_pos++; *op++ = *m_pos++;
422
65.1M
                do *op++ = *m_pos++; while (--t > 0);
423
1.41M
            }
424
425
111k
#endif /* COPY_DICT */
426
427
3.56M
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
3.56M
            if (t == 0)
434
1.36M
                break;
435
436
            /* copy literals */
437
2.20M
match_next:
438
2.20M
            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
315k
            *op++ = *ip++;
443
2.20M
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
315k
#endif
445
315k
            t = *ip++;
446
315k
        }
447
0
    }
448
449
6.74k
eof_found:
450
6.74k
    *out_len = pd(op, out);
451
6.74k
    return (ip == ip_end ? LZO_E_OK :
452
6.74k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
#if defined(HAVE_NEED_IP)
456
1.17k
input_overrun:
457
1.17k
    *out_len = pd(op, out);
458
1.17k
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
#if defined(HAVE_NEED_OP)
462
191
output_overrun:
463
191
    *out_len = pd(op, out);
464
191
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
476
lookbehind_overrun:
469
476
    *out_len = pd(op, out);
470
476
    return LZO_E_LOOKBEHIND_OVERRUN;
471
#endif
472
2.97k
}
lzo1x_decompress
Line
Count
Source
42
3.19k
{
43
3.19k
    lzo_bytep op;
44
3.19k
    const lzo_bytep ip;
45
3.19k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
3.19k
    const lzo_bytep m_pos;
51
3.19k
#endif
52
53
3.19k
    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.19k
    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.19k
    *out_len = 0;
81
82
3.19k
    op = out;
83
3.19k
    ip = in;
84
85
3.19k
    NEED_IP(1);
86
3.19k
    if (*ip > 17)
87
1.44k
    {
88
1.44k
        t = *ip++ - 17;
89
1.44k
        if (t < 4)
90
608
            goto match_next;
91
1.44k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
20.6k
        do *op++ = *ip++; while (--t > 0);
93
833
        goto first_literal_run;
94
1.44k
    }
95
96
1.75k
    for (;;)
97
573k
    {
98
573k
        NEED_IP(3);
99
573k
        t = *ip++;
100
573k
        if (t >= 16)
101
421k
            goto match;
102
        /* a literal run */
103
151k
        if (t == 0)
104
48.5k
        {
105
426k
            while (*ip == 0)
106
378k
            {
107
378k
                t += 255;
108
378k
                ip++;
109
378k
                TEST_IV(t);
110
378k
                NEED_IP(1);
111
378k
            }
112
48.5k
            t += 15 + *ip++;
113
48.5k
        }
114
        /* copy literals */
115
151k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
151k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
151k
        t += 3;
118
151k
        if (t >= 8) do
119
12.4M
        {
120
12.4M
            UA_COPY8(op,ip);
121
12.4M
            op += 8; ip += 8; t -= 8;
122
12.4M
        } while (t >= 8);
123
151k
        if (t >= 4)
124
96.2k
        {
125
96.2k
            UA_COPY4(op,ip);
126
96.2k
            op += 4; ip += 4; t -= 4;
127
96.2k
        }
128
151k
        if (t > 0)
129
98.8k
        {
130
98.8k
            *op++ = *ip++;
131
98.8k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
98.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
152k
first_literal_run:
167
168
169
152k
        t = *ip++;
170
152k
        if (t >= 16)
171
149k
            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
2.97k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
2.97k
        m_pos -= t >> 2;
189
2.97k
        m_pos -= *ip++ << 2;
190
2.97k
#endif
191
2.97k
        TEST_LB(m_pos); NEED_OP(3);
192
2.97k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
2.97k
#endif /* COPY_DICT */
194
2.97k
        goto match_done;
195
196
197
        /* handle matches */
198
617k
        for (;;) {
199
1.18M
match:
200
1.18M
            if (t >= 64)                /* a M2 match */
201
497k
            {
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
497k
#if defined(LZO1X)
222
497k
                m_pos = op - 1;
223
497k
                m_pos -= (t >> 2) & 7;
224
497k
                m_pos -= *ip++ << 3;
225
497k
                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
497k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
497k
                goto copy_match;
251
497k
#endif /* COPY_DICT */
252
497k
            }
253
691k
            else if (t >= 32)           /* a M3 match */
254
373k
            {
255
373k
                t &= 31;
256
373k
                if (t == 0)
257
87.1k
                {
258
187k
                    while (*ip == 0)
259
100k
                    {
260
100k
                        t += 255;
261
100k
                        ip++;
262
100k
                        TEST_OV(t);
263
100k
                        NEED_IP(1);
264
100k
                    }
265
87.1k
                    t += 31 + *ip++;
266
87.1k
                    NEED_IP(2);
267
87.1k
                }
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
373k
                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
373k
#endif /* COPY_DICT */
290
373k
                ip += 2;
291
373k
            }
292
317k
            else if (t >= 16)           /* a M4 match */
293
60.1k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
60.1k
                m_pos = op;
298
60.1k
                m_pos -= (t & 8) << 11;
299
60.1k
#endif /* COPY_DICT */
300
60.1k
                t &= 7;
301
60.1k
                if (t == 0)
302
23.7k
                {
303
41.1k
                    while (*ip == 0)
304
17.3k
                    {
305
17.3k
                        t += 255;
306
17.3k
                        ip++;
307
17.3k
                        TEST_OV(t);
308
17.3k
                        NEED_IP(1);
309
17.3k
                    }
310
23.7k
                    t += 7 + *ip++;
311
23.7k
                    NEED_IP(2);
312
23.7k
                }
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
60.1k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
60.1k
                ip += 2;
335
60.1k
                if (m_pos == op)
336
3.19k
                    goto eof_found;
337
56.9k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
56.9k
#endif /* COPY_DICT */
342
56.9k
            }
343
257k
            else                            /* a M1 match */
344
257k
            {
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
257k
                m_pos = op - 1;
361
257k
                m_pos -= t >> 2;
362
257k
                m_pos -= *ip++ << 2;
363
257k
#endif
364
257k
                TEST_LB(m_pos); NEED_OP(2);
365
257k
                *op++ = *m_pos++; *op++ = *m_pos;
366
257k
#endif /* COPY_DICT */
367
257k
                goto match_done;
368
257k
            }
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
430k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
430k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
430k
            if (op - m_pos >= 8)
381
401k
            {
382
401k
                t += (3 - 1);
383
401k
                if (t >= 8) do
384
3.18M
                {
385
3.18M
                    UA_COPY8(op,m_pos);
386
3.18M
                    op += 8; m_pos += 8; t -= 8;
387
3.18M
                } while (t >= 8);
388
401k
                if (t >= 4)
389
203k
                {
390
203k
                    UA_COPY4(op,m_pos);
391
203k
                    op += 4; m_pos += 4; t -= 4;
392
203k
                }
393
401k
                if (t > 0)
394
288k
                {
395
288k
                    *op++ = m_pos[0];
396
288k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
288k
                }
398
401k
            }
399
29.1k
            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
29.1k
            {
420
526k
copy_match:
421
526k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
17.2M
                do *op++ = *m_pos++; while (--t > 0);
423
526k
            }
424
425
430k
#endif /* COPY_DICT */
426
427
1.18M
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
1.18M
            t = ip[-2] & 3;
432
1.18M
#endif
433
1.18M
            if (t == 0)
434
571k
                break;
435
436
            /* copy literals */
437
617k
match_next:
438
617k
            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
617k
            *op++ = *ip++;
443
617k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
617k
#endif
445
617k
            t = *ip++;
446
617k
        }
447
0
    }
448
449
3.19k
eof_found:
450
3.19k
    *out_len = pd(op, out);
451
3.19k
    return (ip == ip_end ? LZO_E_OK :
452
3.19k
           (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
1.75k
}
lzo1y_decompress
Line
Count
Source
42
1.84k
{
43
1.84k
    lzo_bytep op;
44
1.84k
    const lzo_bytep ip;
45
1.84k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
1.84k
    const lzo_bytep m_pos;
51
1.84k
#endif
52
53
1.84k
    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.84k
    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.84k
    *out_len = 0;
81
82
1.84k
    op = out;
83
1.84k
    ip = in;
84
85
1.84k
    NEED_IP(1);
86
1.84k
    if (*ip > 17)
87
1.39k
    {
88
1.39k
        t = *ip++ - 17;
89
1.39k
        if (t < 4)
90
573
            goto match_next;
91
1.39k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
13.7k
        do *op++ = *ip++; while (--t > 0);
93
818
        goto first_literal_run;
94
1.39k
    }
95
96
452
    for (;;)
97
351k
    {
98
351k
        NEED_IP(3);
99
351k
        t = *ip++;
100
351k
        if (t >= 16)
101
271k
            goto match;
102
        /* a literal run */
103
79.5k
        if (t == 0)
104
25.5k
        {
105
159k
            while (*ip == 0)
106
133k
            {
107
133k
                t += 255;
108
133k
                ip++;
109
133k
                TEST_IV(t);
110
133k
                NEED_IP(1);
111
133k
            }
112
25.5k
            t += 15 + *ip++;
113
25.5k
        }
114
        /* copy literals */
115
79.5k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
79.5k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
79.5k
        t += 3;
118
79.5k
        if (t >= 8) do
119
4.51M
        {
120
4.51M
            UA_COPY8(op,ip);
121
4.51M
            op += 8; ip += 8; t -= 8;
122
4.51M
        } while (t >= 8);
123
79.5k
        if (t >= 4)
124
50.7k
        {
125
50.7k
            UA_COPY4(op,ip);
126
50.7k
            op += 4; ip += 4; t -= 4;
127
50.7k
        }
128
79.5k
        if (t > 0)
129
51.9k
        {
130
51.9k
            *op++ = *ip++;
131
51.9k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
51.9k
        }
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
80.3k
first_literal_run:
167
168
169
80.3k
        t = *ip++;
170
80.3k
        if (t >= 16)
171
76.4k
            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
3.90k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
3.90k
        m_pos -= t >> 2;
189
3.90k
        m_pos -= *ip++ << 2;
190
3.90k
#endif
191
3.90k
        TEST_LB(m_pos); NEED_OP(3);
192
3.90k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
3.90k
#endif /* COPY_DICT */
194
3.90k
        goto match_done;
195
196
197
        /* handle matches */
198
583k
        for (;;) {
199
932k
match:
200
932k
            if (t >= 64)                /* a M2 match */
201
328k
            {
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
328k
                m_pos -= (t >> 2) & 3;
229
328k
                m_pos -= *ip++ << 2;
230
328k
                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
328k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
328k
                goto copy_match;
251
328k
#endif /* COPY_DICT */
252
328k
            }
253
603k
            else if (t >= 32)           /* a M3 match */
254
261k
            {
255
261k
                t &= 31;
256
261k
                if (t == 0)
257
64.4k
                {
258
112k
                    while (*ip == 0)
259
48.2k
                    {
260
48.2k
                        t += 255;
261
48.2k
                        ip++;
262
48.2k
                        TEST_OV(t);
263
48.2k
                        NEED_IP(1);
264
48.2k
                    }
265
64.4k
                    t += 31 + *ip++;
266
64.4k
                    NEED_IP(2);
267
64.4k
                }
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
261k
                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
261k
#endif /* COPY_DICT */
290
261k
                ip += 2;
291
261k
            }
292
342k
            else if (t >= 16)           /* a M4 match */
293
59.5k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
59.5k
                m_pos = op;
298
59.5k
                m_pos -= (t & 8) << 11;
299
59.5k
#endif /* COPY_DICT */
300
59.5k
                t &= 7;
301
59.5k
                if (t == 0)
302
17.1k
                {
303
28.0k
                    while (*ip == 0)
304
10.8k
                    {
305
10.8k
                        t += 255;
306
10.8k
                        ip++;
307
10.8k
                        TEST_OV(t);
308
10.8k
                        NEED_IP(1);
309
10.8k
                    }
310
17.1k
                    t += 7 + *ip++;
311
17.1k
                    NEED_IP(2);
312
17.1k
                }
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
59.5k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
59.5k
                ip += 2;
335
59.5k
                if (m_pos == op)
336
1.84k
                    goto eof_found;
337
57.6k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
57.6k
#endif /* COPY_DICT */
342
57.6k
            }
343
282k
            else                            /* a M1 match */
344
282k
            {
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
282k
                m_pos = op - 1;
361
282k
                m_pos -= t >> 2;
362
282k
                m_pos -= *ip++ << 2;
363
282k
#endif
364
282k
                TEST_LB(m_pos); NEED_OP(2);
365
282k
                *op++ = *m_pos++; *op++ = *m_pos;
366
282k
#endif /* COPY_DICT */
367
282k
                goto match_done;
368
282k
            }
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
318k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
318k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
318k
            if (op - m_pos >= 8)
381
304k
            {
382
304k
                t += (3 - 1);
383
304k
                if (t >= 8) do
384
1.72M
                {
385
1.72M
                    UA_COPY8(op,m_pos);
386
1.72M
                    op += 8; m_pos += 8; t -= 8;
387
1.72M
                } while (t >= 8);
388
304k
                if (t >= 4)
389
162k
                {
390
162k
                    UA_COPY4(op,m_pos);
391
162k
                    op += 4; m_pos += 4; t -= 4;
392
162k
                }
393
304k
                if (t > 0)
394
206k
                {
395
206k
                    *op++ = m_pos[0];
396
206k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
206k
                }
398
304k
            }
399
14.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
14.0k
            {
420
342k
copy_match:
421
342k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
9.64M
                do *op++ = *m_pos++; while (--t > 0);
423
342k
            }
424
425
318k
#endif /* COPY_DICT */
426
427
934k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
934k
            t = ip[-2] & 3;
432
934k
#endif
433
934k
            if (t == 0)
434
350k
                break;
435
436
            /* copy literals */
437
583k
match_next:
438
583k
            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
583k
            *op++ = *ip++;
443
583k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
583k
#endif
445
583k
            t = *ip++;
446
583k
        }
447
0
    }
448
449
1.84k
eof_found:
450
1.84k
    *out_len = pd(op, out);
451
1.84k
    return (ip == ip_end ? LZO_E_OK :
452
1.84k
           (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
452
}
lzo1z_decompress
Line
Count
Source
42
1.66k
{
43
1.66k
    lzo_bytep op;
44
1.66k
    const lzo_bytep ip;
45
1.66k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
1.66k
    const lzo_bytep m_pos;
51
1.66k
#endif
52
53
1.66k
    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.66k
#if defined(LZO1Z)
58
1.66k
    lzo_uint last_m_off = 0;
59
1.66k
#endif
60
61
1.66k
    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.66k
    *out_len = 0;
81
82
1.66k
    op = out;
83
1.66k
    ip = in;
84
85
1.66k
    NEED_IP(1);
86
1.66k
    if (*ip > 17)
87
1.60k
    {
88
1.60k
        t = *ip++ - 17;
89
1.60k
        if (t < 4)
90
724
            goto match_next;
91
1.60k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
17.6k
        do *op++ = *ip++; while (--t > 0);
93
882
        goto first_literal_run;
94
1.60k
    }
95
96
54
    for (;;)
97
254k
    {
98
254k
        NEED_IP(3);
99
254k
        t = *ip++;
100
254k
        if (t >= 16)
101
196k
            goto match;
102
        /* a literal run */
103
58.1k
        if (t == 0)
104
21.4k
        {
105
49.6k
            while (*ip == 0)
106
28.1k
            {
107
28.1k
                t += 255;
108
28.1k
                ip++;
109
28.1k
                TEST_IV(t);
110
28.1k
                NEED_IP(1);
111
28.1k
            }
112
21.4k
            t += 15 + *ip++;
113
21.4k
        }
114
        /* copy literals */
115
58.1k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
58.1k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
58.1k
        t += 3;
118
58.1k
        if (t >= 8) do
119
1.11M
        {
120
1.11M
            UA_COPY8(op,ip);
121
1.11M
            op += 8; ip += 8; t -= 8;
122
1.11M
        } while (t >= 8);
123
58.1k
        if (t >= 4)
124
36.2k
        {
125
36.2k
            UA_COPY4(op,ip);
126
36.2k
            op += 4; ip += 4; t -= 4;
127
36.2k
        }
128
58.1k
        if (t > 0)
129
40.1k
        {
130
40.1k
            *op++ = *ip++;
131
40.1k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
40.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
59.0k
first_literal_run:
167
168
169
59.0k
        t = *ip++;
170
59.0k
        if (t >= 16)
171
55.8k
            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
3.15k
#if defined(LZO1Z)
183
3.15k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
3.15k
        m_pos = op - t;
185
3.15k
        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
3.15k
        TEST_LB(m_pos); NEED_OP(3);
192
3.15k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
3.15k
#endif /* COPY_DICT */
194
3.15k
        goto match_done;
195
196
197
        /* handle matches */
198
686k
        for (;;) {
199
938k
match:
200
938k
            if (t >= 64)                /* a M2 match */
201
275k
            {
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
275k
                    lzo_uint off = t & 0x1f;
234
275k
                    m_pos = op;
235
275k
                    if (off >= 0x1c)
236
12.7k
                    {
237
12.7k
                        assert(last_m_off > 0);
238
12.7k
                        m_pos -= last_m_off;
239
12.7k
                    }
240
263k
                    else
241
263k
                    {
242
263k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
263k
                        m_pos -= off;
244
263k
                        last_m_off = off;
245
263k
                    }
246
275k
                }
247
275k
                t = (t >> 5) - 1;
248
275k
#endif
249
275k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
275k
                goto copy_match;
251
275k
#endif /* COPY_DICT */
252
275k
            }
253
662k
            else if (t >= 32)           /* a M3 match */
254
209k
            {
255
209k
                t &= 31;
256
209k
                if (t == 0)
257
41.9k
                {
258
79.8k
                    while (*ip == 0)
259
37.9k
                    {
260
37.9k
                        t += 255;
261
37.9k
                        ip++;
262
37.9k
                        TEST_OV(t);
263
37.9k
                        NEED_IP(1);
264
37.9k
                    }
265
41.9k
                    t += 31 + *ip++;
266
41.9k
                    NEED_IP(2);
267
41.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
209k
#if defined(LZO1Z)
277
209k
                {
278
209k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
209k
                    m_pos = op - off;
280
209k
                    last_m_off = off;
281
209k
                }
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
209k
#endif /* COPY_DICT */
290
209k
                ip += 2;
291
209k
            }
292
453k
            else if (t >= 16)           /* a M4 match */
293
44.7k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
44.7k
                m_pos = op;
298
44.7k
                m_pos -= (t & 8) << 11;
299
44.7k
#endif /* COPY_DICT */
300
44.7k
                t &= 7;
301
44.7k
                if (t == 0)
302
15.3k
                {
303
22.9k
                    while (*ip == 0)
304
7.59k
                    {
305
7.59k
                        t += 255;
306
7.59k
                        ip++;
307
7.59k
                        TEST_OV(t);
308
7.59k
                        NEED_IP(1);
309
7.59k
                    }
310
15.3k
                    t += 7 + *ip++;
311
15.3k
                    NEED_IP(2);
312
15.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
44.7k
#if defined(LZO1Z)
328
44.7k
                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
44.7k
                ip += 2;
335
44.7k
                if (m_pos == op)
336
1.66k
                    goto eof_found;
337
43.0k
                m_pos -= 0x4000;
338
43.0k
#if defined(LZO1Z)
339
43.0k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
43.0k
#endif
341
43.0k
#endif /* COPY_DICT */
342
43.0k
            }
343
408k
            else                            /* a M1 match */
344
408k
            {
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
408k
#if defined(LZO1Z)
356
408k
                t = 1 + (t << 6) + (*ip++ >> 2);
357
408k
                m_pos = op - t;
358
408k
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
408k
                TEST_LB(m_pos); NEED_OP(2);
365
408k
                *op++ = *m_pos++; *op++ = *m_pos;
366
408k
#endif /* COPY_DICT */
367
408k
                goto match_done;
368
408k
            }
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
252k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
252k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
252k
            if (op - m_pos >= 8)
381
235k
            {
382
235k
                t += (3 - 1);
383
235k
                if (t >= 8) do
384
1.31M
                {
385
1.31M
                    UA_COPY8(op,m_pos);
386
1.31M
                    op += 8; m_pos += 8; t -= 8;
387
1.31M
                } while (t >= 8);
388
235k
                if (t >= 4)
389
93.0k
                {
390
93.0k
                    UA_COPY4(op,m_pos);
391
93.0k
                    op += 4; m_pos += 4; t -= 4;
392
93.0k
                }
393
235k
                if (t > 0)
394
183k
                {
395
183k
                    *op++ = m_pos[0];
396
183k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
183k
                }
398
235k
            }
399
17.2k
            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
17.2k
            {
420
293k
copy_match:
421
293k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
8.03M
                do *op++ = *m_pos++; while (--t > 0);
423
293k
            }
424
425
252k
#endif /* COPY_DICT */
426
427
940k
match_done:
428
940k
#if defined(LZO1Z)
429
940k
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
940k
            if (t == 0)
434
254k
                break;
435
436
            /* copy literals */
437
686k
match_next:
438
686k
            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
686k
            *op++ = *ip++;
443
686k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
686k
#endif
445
686k
            t = *ip++;
446
686k
        }
447
0
    }
448
449
1.66k
eof_found:
450
1.66k
    *out_len = pd(op, out);
451
1.66k
    return (ip == ip_end ? LZO_E_OK :
452
1.66k
           (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
623
{
43
623
    lzo_bytep op;
44
623
    const lzo_bytep ip;
45
623
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
623
    const lzo_bytep m_pos;
51
623
#endif
52
53
623
    const lzo_bytep const ip_end = in + in_len;
54
623
#if defined(HAVE_ANY_OP)
55
623
    lzo_bytep const op_end = out + *out_len;
56
623
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
623
    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
623
    *out_len = 0;
81
82
623
    op = out;
83
623
    ip = in;
84
85
623
    NEED_IP(1);
86
623
    if (*ip > 17)
87
375
    {
88
375
        t = *ip++ - 17;
89
375
        if (t < 4)
90
277
            goto match_next;
91
375
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
1.67k
        do *op++ = *ip++; while (--t > 0);
93
86
        goto first_literal_run;
94
98
    }
95
96
248
    for (;;)
97
50.1k
    {
98
50.1k
        NEED_IP(3);
99
50.1k
        t = *ip++;
100
50.1k
        if (t >= 16)
101
35.6k
            goto match;
102
        /* a literal run */
103
14.4k
        if (t == 0)
104
9.20k
        {
105
4.11M
            while (*ip == 0)
106
4.10M
            {
107
4.10M
                t += 255;
108
4.10M
                ip++;
109
4.10M
                TEST_IV(t);
110
4.10M
                NEED_IP(1);
111
4.10M
            }
112
9.18k
            t += 15 + *ip++;
113
9.18k
        }
114
        /* copy literals */
115
14.4k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
14.2k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
14.2k
        t += 3;
118
14.2k
        if (t >= 8) do
119
287k
        {
120
287k
            UA_COPY8(op,ip);
121
287k
            op += 8; ip += 8; t -= 8;
122
287k
        } while (t >= 8);
123
14.2k
        if (t >= 4)
124
7.07k
        {
125
7.07k
            UA_COPY4(op,ip);
126
7.07k
            op += 4; ip += 4; t -= 4;
127
7.07k
        }
128
14.2k
        if (t > 0)
129
11.7k
        {
130
11.7k
            *op++ = *ip++;
131
11.7k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
11.7k
        }
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
14.3k
first_literal_run:
167
168
169
14.3k
        t = *ip++;
170
14.3k
        if (t >= 16)
171
5.18k
            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.14k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
9.14k
        m_pos -= t >> 2;
189
9.14k
        m_pos -= *ip++ << 2;
190
9.14k
#endif
191
9.14k
        TEST_LB(m_pos); NEED_OP(3);
192
9.10k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
9.10k
#endif /* COPY_DICT */
194
9.10k
        goto match_done;
195
196
197
        /* handle matches */
198
86.1k
        for (;;) {
199
127k
match:
200
127k
            if (t >= 64)                /* a M2 match */
201
61.7k
            {
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
61.7k
#if defined(LZO1X)
222
61.7k
                m_pos = op - 1;
223
61.7k
                m_pos -= (t >> 2) & 7;
224
61.7k
                m_pos -= *ip++ << 3;
225
61.7k
                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
61.7k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
61.7k
                goto copy_match;
251
61.7k
#endif /* COPY_DICT */
252
61.7k
            }
253
65.3k
            else if (t >= 32)           /* a M3 match */
254
31.8k
            {
255
31.8k
                t &= 31;
256
31.8k
                if (t == 0)
257
3.54k
                {
258
1.31M
                    while (*ip == 0)
259
1.31M
                    {
260
1.31M
                        t += 255;
261
1.31M
                        ip++;
262
1.31M
                        TEST_OV(t);
263
1.31M
                        NEED_IP(1);
264
1.31M
                    }
265
3.52k
                    t += 31 + *ip++;
266
3.52k
                    NEED_IP(2);
267
3.52k
                }
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
31.8k
                m_pos = op - 1;
284
31.8k
                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
31.8k
#endif /* COPY_DICT */
290
31.8k
                ip += 2;
291
31.8k
            }
292
33.4k
            else if (t >= 16)           /* a M4 match */
293
8.18k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
8.18k
                m_pos = op;
298
8.18k
                m_pos -= (t & 8) << 11;
299
8.18k
#endif /* COPY_DICT */
300
8.18k
                t &= 7;
301
8.18k
                if (t == 0)
302
2.49k
                {
303
1.83M
                    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.47k
                    t += 7 + *ip++;
311
2.47k
                    NEED_IP(2);
312
2.47k
                }
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
8.14k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
8.14k
                ip += 2;
335
8.14k
                if (m_pos == op)
336
13
                    goto eof_found;
337
8.13k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
8.13k
#endif /* COPY_DICT */
342
8.13k
            }
343
25.2k
            else                            /* a M1 match */
344
25.2k
            {
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
25.2k
                m_pos = op - 1;
361
25.2k
                m_pos -= t >> 2;
362
25.2k
                m_pos -= *ip++ << 2;
363
25.2k
#endif
364
25.2k
                TEST_LB(m_pos); NEED_OP(2);
365
25.2k
                *op++ = *m_pos++; *op++ = *m_pos;
366
25.2k
#endif /* COPY_DICT */
367
25.2k
                goto match_done;
368
25.2k
            }
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
39.9k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
39.8k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
39.8k
            if (op - m_pos >= 8)
381
36.7k
            {
382
36.7k
                t += (3 - 1);
383
36.7k
                if (t >= 8) do
384
589k
                {
385
589k
                    UA_COPY8(op,m_pos);
386
589k
                    op += 8; m_pos += 8; t -= 8;
387
589k
                } while (t >= 8);
388
36.7k
                if (t >= 4)
389
22.2k
                {
390
22.2k
                    UA_COPY4(op,m_pos);
391
22.2k
                    op += 4; m_pos += 4; t -= 4;
392
22.2k
                }
393
36.7k
                if (t > 0)
394
28.2k
                {
395
28.2k
                    *op++ = m_pos[0];
396
28.2k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
28.2k
                }
398
36.7k
            }
399
3.14k
            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.14k
            {
420
64.8k
copy_match:
421
64.8k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
11.9M
                do *op++ = *m_pos++; while (--t > 0);
423
64.8k
            }
424
425
39.8k
#endif /* COPY_DICT */
426
427
135k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
135k
            t = ip[-2] & 3;
432
135k
#endif
433
135k
            if (t == 0)
434
49.9k
                break;
435
436
            /* copy literals */
437
86.2k
match_next:
438
86.2k
            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
86.1k
            *op++ = *ip++;
443
86.1k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
86.1k
#endif
445
86.1k
            t = *ip++;
446
86.1k
        }
447
0
    }
448
449
13
eof_found:
450
13
    *out_len = pd(op, out);
451
13
    return (ip == ip_end ? LZO_E_OK :
452
13
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
398
input_overrun:
457
398
    *out_len = pd(op, out);
458
398
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
66
output_overrun:
463
66
    *out_len = pd(op, out);
464
66
    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
248
#endif
472
248
}
lzo1y_decompress_safe
Line
Count
Source
42
636
{
43
636
    lzo_bytep op;
44
636
    const lzo_bytep ip;
45
636
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
636
    const lzo_bytep m_pos;
51
636
#endif
52
53
636
    const lzo_bytep const ip_end = in + in_len;
54
636
#if defined(HAVE_ANY_OP)
55
636
    lzo_bytep const op_end = out + *out_len;
56
636
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
636
    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
636
    *out_len = 0;
81
82
636
    op = out;
83
636
    ip = in;
84
85
636
    NEED_IP(1);
86
636
    if (*ip > 17)
87
369
    {
88
369
        t = *ip++ - 17;
89
369
        if (t < 4)
90
264
            goto match_next;
91
369
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
2.44k
        do *op++ = *ip++; while (--t > 0);
93
92
        goto first_literal_run;
94
105
    }
95
96
267
    for (;;)
97
93.4k
    {
98
93.4k
        NEED_IP(3);
99
93.3k
        t = *ip++;
100
93.3k
        if (t >= 16)
101
68.5k
            goto match;
102
        /* a literal run */
103
24.8k
        if (t == 0)
104
14.9k
        {
105
18.5M
            while (*ip == 0)
106
18.4M
            {
107
18.4M
                t += 255;
108
18.4M
                ip++;
109
18.4M
                TEST_IV(t);
110
18.4M
                NEED_IP(1);
111
18.4M
            }
112
14.9k
            t += 15 + *ip++;
113
14.9k
        }
114
        /* copy literals */
115
24.8k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
24.6k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
24.6k
        t += 3;
118
24.6k
        if (t >= 8) do
119
602k
        {
120
602k
            UA_COPY8(op,ip);
121
602k
            op += 8; ip += 8; t -= 8;
122
602k
        } while (t >= 8);
123
24.6k
        if (t >= 4)
124
13.3k
        {
125
13.3k
            UA_COPY4(op,ip);
126
13.3k
            op += 4; ip += 4; t -= 4;
127
13.3k
        }
128
24.6k
        if (t > 0)
129
19.4k
        {
130
19.4k
            *op++ = *ip++;
131
19.4k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
19.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
24.7k
first_literal_run:
167
168
169
24.7k
        t = *ip++;
170
24.7k
        if (t >= 16)
171
11.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
13.7k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
13.7k
        m_pos -= t >> 2;
189
13.7k
        m_pos -= *ip++ << 2;
190
13.7k
#endif
191
13.7k
        TEST_LB(m_pos); NEED_OP(3);
192
13.7k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
13.7k
#endif /* COPY_DICT */
194
13.7k
        goto match_done;
195
196
197
        /* handle matches */
198
121k
        for (;;) {
199
200k
match:
200
200k
            if (t >= 64)                /* a M2 match */
201
97.7k
            {
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
97.7k
                m_pos -= (t >> 2) & 3;
229
97.7k
                m_pos -= *ip++ << 2;
230
97.7k
                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
97.7k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
97.6k
                goto copy_match;
251
97.7k
#endif /* COPY_DICT */
252
97.7k
            }
253
102k
            else if (t >= 32)           /* a M3 match */
254
35.0k
            {
255
35.0k
                t &= 31;
256
35.0k
                if (t == 0)
257
2.96k
                {
258
16.1M
                    while (*ip == 0)
259
16.1M
                    {
260
16.1M
                        t += 255;
261
16.1M
                        ip++;
262
16.1M
                        TEST_OV(t);
263
16.1M
                        NEED_IP(1);
264
16.1M
                    }
265
2.94k
                    t += 31 + *ip++;
266
2.94k
                    NEED_IP(2);
267
2.94k
                }
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
35.0k
                m_pos = op - 1;
284
35.0k
                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
35.0k
#endif /* COPY_DICT */
290
35.0k
                ip += 2;
291
35.0k
            }
292
67.7k
            else if (t >= 16)           /* a M4 match */
293
10.4k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
10.4k
                m_pos = op;
298
10.4k
                m_pos -= (t & 8) << 11;
299
10.4k
#endif /* COPY_DICT */
300
10.4k
                t &= 7;
301
10.4k
                if (t == 0)
302
2.75k
                {
303
6.03M
                    while (*ip == 0)
304
6.03M
                    {
305
6.03M
                        t += 255;
306
6.03M
                        ip++;
307
6.03M
                        TEST_OV(t);
308
6.03M
                        NEED_IP(1);
309
6.03M
                    }
310
2.73k
                    t += 7 + *ip++;
311
2.73k
                    NEED_IP(2);
312
2.73k
                }
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.3k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
10.3k
                ip += 2;
335
10.3k
                if (m_pos == op)
336
17
                    goto eof_found;
337
10.3k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
10.3k
#endif /* COPY_DICT */
342
10.3k
            }
343
57.3k
            else                            /* a M1 match */
344
57.3k
            {
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
57.3k
                m_pos = op - 1;
361
57.3k
                m_pos -= t >> 2;
362
57.3k
                m_pos -= *ip++ << 2;
363
57.3k
#endif
364
57.3k
                TEST_LB(m_pos); NEED_OP(2);
365
57.3k
                *op++ = *m_pos++; *op++ = *m_pos;
366
57.3k
#endif /* COPY_DICT */
367
57.3k
                goto match_done;
368
57.3k
            }
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
45.4k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
45.3k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
45.3k
            if (op - m_pos >= 8)
381
41.5k
            {
382
41.5k
                t += (3 - 1);
383
41.5k
                if (t >= 8) do
384
472k
                {
385
472k
                    UA_COPY8(op,m_pos);
386
472k
                    op += 8; m_pos += 8; t -= 8;
387
472k
                } while (t >= 8);
388
41.5k
                if (t >= 4)
389
22.6k
                {
390
22.6k
                    UA_COPY4(op,m_pos);
391
22.6k
                    op += 4; m_pos += 4; t -= 4;
392
22.6k
                }
393
41.5k
                if (t > 0)
394
30.3k
                {
395
30.3k
                    *op++ = m_pos[0];
396
30.3k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
30.3k
                }
398
41.5k
            }
399
3.71k
            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.71k
            {
420
101k
copy_match:
421
101k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
11.3M
                do *op++ = *m_pos++; while (--t > 0);
423
101k
            }
424
425
45.3k
#endif /* COPY_DICT */
426
427
214k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
214k
            t = ip[-2] & 3;
432
214k
#endif
433
214k
            if (t == 0)
434
93.1k
                break;
435
436
            /* copy literals */
437
121k
match_next:
438
121k
            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
121k
            *op++ = *ip++;
443
121k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
121k
#endif
445
121k
            t = *ip++;
446
121k
        }
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
378
input_overrun:
457
378
    *out_len = pd(op, out);
458
378
    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
177
lookbehind_overrun:
469
177
    *out_len = pd(op, out);
470
177
    return LZO_E_LOOKBEHIND_OVERRUN;
471
267
#endif
472
267
}
lzo1z_decompress_safe
Line
Count
Source
42
631
{
43
631
    lzo_bytep op;
44
631
    const lzo_bytep ip;
45
631
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
631
    const lzo_bytep m_pos;
51
631
#endif
52
53
631
    const lzo_bytep const ip_end = in + in_len;
54
631
#if defined(HAVE_ANY_OP)
55
631
    lzo_bytep const op_end = out + *out_len;
56
631
#endif
57
631
#if defined(LZO1Z)
58
631
    lzo_uint last_m_off = 0;
59
631
#endif
60
61
631
    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
631
    *out_len = 0;
81
82
631
    op = out;
83
631
    ip = in;
84
85
631
    NEED_IP(1);
86
631
    if (*ip > 17)
87
431
    {
88
431
        t = *ip++ - 17;
89
431
        if (t < 4)
90
320
            goto match_next;
91
431
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
1.76k
        do *op++ = *ip++; while (--t > 0);
93
98
        goto first_literal_run;
94
111
    }
95
96
200
    for (;;)
97
47.6k
    {
98
47.6k
        NEED_IP(3);
99
47.6k
        t = *ip++;
100
47.6k
        if (t >= 16)
101
34.3k
            goto match;
102
        /* a literal run */
103
13.3k
        if (t == 0)
104
5.91k
        {
105
3.00M
            while (*ip == 0)
106
2.99M
            {
107
2.99M
                t += 255;
108
2.99M
                ip++;
109
2.99M
                TEST_IV(t);
110
2.99M
                NEED_IP(1);
111
2.99M
            }
112
5.89k
            t += 15 + *ip++;
113
5.89k
        }
114
        /* copy literals */
115
13.3k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
13.1k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
13.1k
        t += 3;
118
13.1k
        if (t >= 8) do
119
443k
        {
120
443k
            UA_COPY8(op,ip);
121
443k
            op += 8; ip += 8; t -= 8;
122
443k
        } while (t >= 8);
123
13.1k
        if (t >= 4)
124
7.47k
        {
125
7.47k
            UA_COPY4(op,ip);
126
7.47k
            op += 4; ip += 4; t -= 4;
127
7.47k
        }
128
13.1k
        if (t > 0)
129
9.02k
        {
130
9.02k
            *op++ = *ip++;
131
9.02k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
9.02k
        }
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
13.2k
first_literal_run:
167
168
169
13.2k
        t = *ip++;
170
13.2k
        if (t >= 16)
171
6.43k
            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
6.78k
#if defined(LZO1Z)
183
6.78k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
6.78k
        m_pos = op - t;
185
6.78k
        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
6.78k
        TEST_LB(m_pos); NEED_OP(3);
192
6.75k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
6.75k
#endif /* COPY_DICT */
194
6.75k
        goto match_done;
195
196
197
        /* handle matches */
198
108k
        for (;;) {
199
149k
match:
200
149k
            if (t >= 64)                /* a M2 match */
201
85.6k
            {
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
85.6k
                    lzo_uint off = t & 0x1f;
234
85.6k
                    m_pos = op;
235
85.6k
                    if (off >= 0x1c)
236
12.3k
                    {
237
12.3k
                        assert(last_m_off > 0);
238
12.3k
                        m_pos -= last_m_off;
239
12.3k
                    }
240
73.3k
                    else
241
73.3k
                    {
242
73.3k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
73.3k
                        m_pos -= off;
244
73.3k
                        last_m_off = off;
245
73.3k
                    }
246
85.6k
                }
247
85.6k
                t = (t >> 5) - 1;
248
85.6k
#endif
249
85.6k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
85.6k
                goto copy_match;
251
85.6k
#endif /* COPY_DICT */
252
85.6k
            }
253
63.6k
            else if (t >= 32)           /* a M3 match */
254
20.3k
            {
255
20.3k
                t &= 31;
256
20.3k
                if (t == 0)
257
3.59k
                {
258
1.68M
                    while (*ip == 0)
259
1.68M
                    {
260
1.68M
                        t += 255;
261
1.68M
                        ip++;
262
1.68M
                        TEST_OV(t);
263
1.68M
                        NEED_IP(1);
264
1.68M
                    }
265
3.57k
                    t += 31 + *ip++;
266
3.57k
                    NEED_IP(2);
267
3.57k
                }
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
20.2k
#if defined(LZO1Z)
277
20.2k
                {
278
20.2k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
20.2k
                    m_pos = op - off;
280
20.2k
                    last_m_off = off;
281
20.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
20.2k
#endif /* COPY_DICT */
290
20.2k
                ip += 2;
291
20.2k
            }
292
43.3k
            else if (t >= 16)           /* a M4 match */
293
6.36k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
6.36k
                m_pos = op;
298
6.36k
                m_pos -= (t & 8) << 11;
299
6.36k
#endif /* COPY_DICT */
300
6.36k
                t &= 7;
301
6.36k
                if (t == 0)
302
2.44k
                {
303
80.6k
                    while (*ip == 0)
304
78.2k
                    {
305
78.2k
                        t += 255;
306
78.2k
                        ip++;
307
78.2k
                        TEST_OV(t);
308
78.2k
                        NEED_IP(1);
309
78.2k
                    }
310
2.43k
                    t += 7 + *ip++;
311
2.43k
                    NEED_IP(2);
312
2.43k
                }
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
6.35k
#if defined(LZO1Z)
328
6.35k
                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
6.35k
                ip += 2;
335
6.35k
                if (m_pos == op)
336
16
                    goto eof_found;
337
6.33k
                m_pos -= 0x4000;
338
6.33k
#if defined(LZO1Z)
339
6.33k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
6.33k
#endif
341
6.33k
#endif /* COPY_DICT */
342
6.33k
            }
343
36.9k
            else                            /* a M1 match */
344
36.9k
            {
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
36.9k
#if defined(LZO1Z)
356
36.9k
                t = 1 + (t << 6) + (*ip++ >> 2);
357
36.9k
                m_pos = op - t;
358
36.9k
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
36.9k
                TEST_LB(m_pos); NEED_OP(2);
365
36.9k
                *op++ = *m_pos++; *op++ = *m_pos;
366
36.9k
#endif /* COPY_DICT */
367
36.9k
                goto match_done;
368
36.9k
            }
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
26.6k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
26.5k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
26.5k
            if (op - m_pos >= 8)
381
23.8k
            {
382
23.8k
                t += (3 - 1);
383
23.8k
                if (t >= 8) do
384
1.09M
                {
385
1.09M
                    UA_COPY8(op,m_pos);
386
1.09M
                    op += 8; m_pos += 8; t -= 8;
387
1.09M
                } while (t >= 8);
388
23.8k
                if (t >= 4)
389
12.5k
                {
390
12.5k
                    UA_COPY4(op,m_pos);
391
12.5k
                    op += 4; m_pos += 4; t -= 4;
392
12.5k
                }
393
23.8k
                if (t > 0)
394
19.7k
                {
395
19.7k
                    *op++ = m_pos[0];
396
19.7k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
19.7k
                }
398
23.8k
            }
399
2.67k
            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.67k
            {
420
88.3k
copy_match:
421
88.3k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
6.91M
                do *op++ = *m_pos++; while (--t > 0);
423
88.3k
            }
424
425
26.5k
#endif /* COPY_DICT */
426
427
155k
match_done:
428
155k
#if defined(LZO1Z)
429
155k
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
155k
            if (t == 0)
434
47.4k
                break;
435
436
            /* copy literals */
437
108k
match_next:
438
108k
            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
108k
            *op++ = *ip++;
443
108k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
108k
#endif
445
108k
            t = *ip++;
446
108k
        }
447
0
    }
448
449
16
eof_found:
450
16
    *out_len = pd(op, out);
451
16
    return (ip == ip_end ? LZO_E_OK :
452
16
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
401
input_overrun:
457
401
    *out_len = pd(op, out);
458
401
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
61
output_overrun:
463
61
    *out_len = pd(op, out);
464
61
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
153
lookbehind_overrun:
469
153
    *out_len = pd(op, out);
470
153
    return LZO_E_LOOKBEHIND_OVERRUN;
471
200
#endif
472
200
}
473
474
475
/* vim:set ts=4 sw=4 et: */