Coverage Report

Created: 2025-11-24 06:26

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
7.50k
{
43
7.50k
    lzo_bytep op;
44
7.50k
    const lzo_bytep ip;
45
7.50k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
7.50k
    const lzo_bytep m_pos;
51
7.50k
#endif
52
53
7.50k
    const lzo_bytep const ip_end = in + in_len;
54
#if defined(HAVE_ANY_OP)
55
1.66k
    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
7.50k
    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
7.50k
    *out_len = 0;
81
82
7.50k
    op = out;
83
7.50k
    ip = in;
84
85
7.50k
    NEED_IP(1);
86
7.50k
    if (*ip > 17)
87
4.49k
    {
88
4.49k
        t = *ip++ - 17;
89
4.49k
        if (t < 4)
90
2.35k
            goto match_next;
91
4.49k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
34.5k
        do *op++ = *ip++; while (--t > 0);
93
302
        goto first_literal_run;
94
336
    }
95
96
3.01k
    for (;;)
97
1.88M
    {
98
1.88M
        NEED_IP(3);
99
158k
        t = *ip++;
100
1.88M
        if (t >= 16)
101
1.44M
            goto match;
102
        /* a literal run */
103
436k
        if (t == 0)
104
108k
        {
105
18.2M
            while (*ip == 0)
106
18.1M
            {
107
18.1M
                t += 255;
108
18.1M
                ip++;
109
18.1M
                TEST_IV(t);
110
18.1M
                NEED_IP(1);
111
17.7M
            }
112
17.4k
            t += 15 + *ip++;
113
17.4k
        }
114
        /* copy literals */
115
436k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
48.8k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
48.8k
        t += 3;
118
436k
        if (t >= 8) do
119
13.7M
        {
120
13.7M
            UA_COPY8(op,ip);
121
13.7M
            op += 8; ip += 8; t -= 8;
122
13.7M
        } while (t >= 8);
123
436k
        if (t >= 4)
124
294k
        {
125
294k
            UA_COPY4(op,ip);
126
294k
            op += 4; ip += 4; t -= 4;
127
294k
        }
128
436k
        if (t > 0)
129
284k
        {
130
284k
            *op++ = *ip++;
131
284k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
284k
        }
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
438k
first_literal_run:
167
168
169
438k
        t = *ip++;
170
438k
        if (t >= 16)
171
410k
            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.20k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
2.35k
        m_pos = op - t;
185
2.35k
        last_m_off = t;
186
#else
187
18.7k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
        m_pos -= t >> 2;
189
        m_pos -= *ip++ << 2;
190
#endif
191
27.9k
        TEST_LB(m_pos); NEED_OP(3);
192
22.0k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
22.0k
#endif /* COPY_DICT */
194
22.0k
        goto match_done;
195
196
197
        /* handle matches */
198
1.80M
        for (;;) {
199
3.66M
match:
200
3.66M
            if (t >= 64)                /* a M2 match */
201
1.64M
            {
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
332k
                    if (off >= 0x1c)
236
24.6k
                    {
237
24.6k
                        assert(last_m_off > 0);
238
24.6k
                        m_pos -= last_m_off;
239
24.6k
                    }
240
307k
                    else
241
307k
                    {
242
307k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
307k
                        m_pos -= off;
244
307k
                        last_m_off = off;
245
307k
                    }
246
                }
247
                t = (t >> 5) - 1;
248
#endif
249
1.64M
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
195k
                goto copy_match;
251
195k
#endif /* COPY_DICT */
252
195k
            }
253
2.01M
            else if (t >= 32)           /* a M3 match */
254
1.33M
            {
255
1.33M
                t &= 31;
256
1.33M
                if (t == 0)
257
298k
                {
258
5.03M
                    while (*ip == 0)
259
4.73M
                    {
260
4.73M
                        t += 255;
261
4.73M
                        ip++;
262
4.73M
                        TEST_OV(t);
263
4.73M
                        NEED_IP(1);
264
4.52M
                    }
265
17.9k
                    t += 31 + *ip++;
266
297k
                    NEED_IP(2);
267
17.9k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
23.2k
                {
278
23.2k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
23.2k
                    m_pos = op - off;
280
23.2k
                    last_m_off = off;
281
23.2k
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
106k
                m_pos = op - 1;
284
1.04M
                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
106k
#endif /* COPY_DICT */
290
106k
                ip += 2;
291
106k
            }
292
687k
            else if (t >= 16)           /* a M4 match */
293
317k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
317k
                m_pos = op;
298
317k
                m_pos -= (t & 8) << 11;
299
317k
#endif /* COPY_DICT */
300
317k
                t &= 7;
301
317k
                if (t == 0)
302
143k
                {
303
3.90M
                    while (*ip == 0)
304
3.76M
                    {
305
3.76M
                        t += 255;
306
3.76M
                        ip++;
307
3.76M
                        TEST_OV(t);
308
3.76M
                        NEED_IP(1);
309
3.69M
                    }
310
11.5k
                    t += 7 + *ip++;
311
143k
                    NEED_IP(2);
312
11.5k
                }
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
9.00k
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
239k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
31.7k
                ip += 2;
335
317k
                if (m_pos == op)
336
5.88k
                    goto eof_found;
337
311k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
76.4k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
311k
#endif /* COPY_DICT */
342
311k
            }
343
370k
            else                            /* a M1 match */
344
370k
            {
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
370k
                TEST_LB(m_pos); NEED_OP(2);
365
53.2k
                *op++ = *m_pos++; *op++ = *m_pos;
366
53.2k
#endif /* COPY_DICT */
367
53.2k
                goto match_done;
368
53.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
1.64M
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
170k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
1.64M
            if (op - m_pos >= 8)
381
1.51M
            {
382
1.51M
                t += (3 - 1);
383
1.51M
                if (t >= 8) do
384
12.5M
                {
385
12.5M
                    UA_COPY8(op,m_pos);
386
12.5M
                    op += 8; m_pos += 8; t -= 8;
387
12.5M
                } while (t >= 8);
388
1.51M
                if (t >= 4)
389
786k
                {
390
786k
                    UA_COPY4(op,m_pos);
391
786k
                    op += 4; m_pos += 4; t -= 4;
392
786k
                }
393
1.51M
                if (t > 0)
394
1.10M
                {
395
1.10M
                    *op++ = m_pos[0];
396
1.10M
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
1.10M
                }
398
1.51M
            }
399
122k
            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
122k
            {
420
1.76M
copy_match:
421
1.76M
                *op++ = *m_pos++; *op++ = *m_pos++;
422
54.5M
                do *op++ = *m_pos++; while (--t > 0);
423
1.76M
            }
424
425
170k
#endif /* COPY_DICT */
426
427
3.68M
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
3.68M
            if (t == 0)
434
1.87M
                break;
435
436
            /* copy literals */
437
1.80M
match_next:
438
1.80M
            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
283k
            *op++ = *ip++;
443
1.80M
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
283k
#endif
445
283k
            t = *ip++;
446
283k
        }
447
0
    }
448
449
5.88k
eof_found:
450
5.88k
    *out_len = pd(op, out);
451
5.88k
    return (ip == ip_end ? LZO_E_OK :
452
5.88k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
#if defined(HAVE_NEED_IP)
456
1.00k
input_overrun:
457
1.00k
    *out_len = pd(op, out);
458
1.00k
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
#if defined(HAVE_NEED_OP)
462
166
output_overrun:
463
166
    *out_len = pd(op, out);
464
166
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
458
lookbehind_overrun:
469
458
    *out_len = pd(op, out);
470
458
    return LZO_E_LOOKBEHIND_OVERRUN;
471
#endif
472
3.01k
}
lzo1x_decompress
Line
Count
Source
42
3.06k
{
43
3.06k
    lzo_bytep op;
44
3.06k
    const lzo_bytep ip;
45
3.06k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
3.06k
    const lzo_bytep m_pos;
51
3.06k
#endif
52
53
3.06k
    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.06k
    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.06k
    *out_len = 0;
81
82
3.06k
    op = out;
83
3.06k
    ip = in;
84
85
3.06k
    NEED_IP(1);
86
3.06k
    if (*ip > 17)
87
1.13k
    {
88
1.13k
        t = *ip++ - 17;
89
1.13k
        if (t < 4)
90
545
            goto match_next;
91
1.13k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
11.3k
        do *op++ = *ip++; while (--t > 0);
93
591
        goto first_literal_run;
94
1.13k
    }
95
96
1.92k
    for (;;)
97
983k
    {
98
983k
        NEED_IP(3);
99
983k
        t = *ip++;
100
983k
        if (t >= 16)
101
735k
            goto match;
102
        /* a literal run */
103
248k
        if (t == 0)
104
57.4k
        {
105
288k
            while (*ip == 0)
106
231k
            {
107
231k
                t += 255;
108
231k
                ip++;
109
231k
                TEST_IV(t);
110
231k
                NEED_IP(1);
111
231k
            }
112
57.4k
            t += 15 + *ip++;
113
57.4k
        }
114
        /* copy literals */
115
248k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
248k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
248k
        t += 3;
118
248k
        if (t >= 8) do
119
7.97M
        {
120
7.97M
            UA_COPY8(op,ip);
121
7.97M
            op += 8; ip += 8; t -= 8;
122
7.97M
        } while (t >= 8);
123
248k
        if (t >= 4)
124
168k
        {
125
168k
            UA_COPY4(op,ip);
126
168k
            op += 4; ip += 4; t -= 4;
127
168k
        }
128
248k
        if (t > 0)
129
160k
        {
130
160k
            *op++ = *ip++;
131
160k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
160k
        }
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
248k
first_literal_run:
167
168
169
248k
        t = *ip++;
170
248k
        if (t >= 16)
171
247k
            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
1.43k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
1.43k
        m_pos -= t >> 2;
189
1.43k
        m_pos -= *ip++ << 2;
190
1.43k
#endif
191
1.43k
        TEST_LB(m_pos); NEED_OP(3);
192
1.43k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
1.43k
#endif /* COPY_DICT */
194
1.43k
        goto match_done;
195
196
197
        /* handle matches */
198
625k
        for (;;) {
199
1.60M
match:
200
1.60M
            if (t >= 64)                /* a M2 match */
201
742k
            {
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
742k
#if defined(LZO1X)
222
742k
                m_pos = op - 1;
223
742k
                m_pos -= (t >> 2) & 7;
224
742k
                m_pos -= *ip++ << 3;
225
742k
                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
742k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
742k
                goto copy_match;
251
742k
#endif /* COPY_DICT */
252
742k
            }
253
865k
            else if (t >= 32)           /* a M3 match */
254
649k
            {
255
649k
                t &= 31;
256
649k
                if (t == 0)
257
165k
                {
258
280k
                    while (*ip == 0)
259
115k
                    {
260
115k
                        t += 255;
261
115k
                        ip++;
262
115k
                        TEST_OV(t);
263
115k
                        NEED_IP(1);
264
115k
                    }
265
165k
                    t += 31 + *ip++;
266
165k
                    NEED_IP(2);
267
165k
                }
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
649k
                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
649k
#endif /* COPY_DICT */
290
649k
                ip += 2;
291
649k
            }
292
216k
            else if (t >= 16)           /* a M4 match */
293
132k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
132k
                m_pos = op;
298
132k
                m_pos -= (t & 8) << 11;
299
132k
#endif /* COPY_DICT */
300
132k
                t &= 7;
301
132k
                if (t == 0)
302
71.7k
                {
303
105k
                    while (*ip == 0)
304
33.3k
                    {
305
33.3k
                        t += 255;
306
33.3k
                        ip++;
307
33.3k
                        TEST_OV(t);
308
33.3k
                        NEED_IP(1);
309
33.3k
                    }
310
71.7k
                    t += 7 + *ip++;
311
71.7k
                    NEED_IP(2);
312
71.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
132k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
132k
                ip += 2;
335
132k
                if (m_pos == op)
336
3.06k
                    goto eof_found;
337
129k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
129k
#endif /* COPY_DICT */
342
129k
            }
343
83.5k
            else                            /* a M1 match */
344
83.5k
            {
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
83.5k
                m_pos = op - 1;
361
83.5k
                m_pos -= t >> 2;
362
83.5k
                m_pos -= *ip++ << 2;
363
83.5k
#endif
364
83.5k
                TEST_LB(m_pos); NEED_OP(2);
365
83.5k
                *op++ = *m_pos++; *op++ = *m_pos;
366
83.5k
#endif /* COPY_DICT */
367
83.5k
                goto match_done;
368
83.5k
            }
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
778k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
778k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
778k
            if (op - m_pos >= 8)
381
711k
            {
382
711k
                t += (3 - 1);
383
711k
                if (t >= 8) do
384
5.79M
                {
385
5.79M
                    UA_COPY8(op,m_pos);
386
5.79M
                    op += 8; m_pos += 8; t -= 8;
387
5.79M
                } while (t >= 8);
388
711k
                if (t >= 4)
389
371k
                {
390
371k
                    UA_COPY4(op,m_pos);
391
371k
                    op += 4; m_pos += 4; t -= 4;
392
371k
                }
393
711k
                if (t > 0)
394
508k
                {
395
508k
                    *op++ = m_pos[0];
396
508k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
508k
                }
398
711k
            }
399
67.5k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
67.5k
            {
420
810k
copy_match:
421
810k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
15.6M
                do *op++ = *m_pos++; while (--t > 0);
423
810k
            }
424
425
778k
#endif /* COPY_DICT */
426
427
1.60M
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
1.60M
            t = ip[-2] & 3;
432
1.60M
#endif
433
1.60M
            if (t == 0)
434
981k
                break;
435
436
            /* copy literals */
437
625k
match_next:
438
625k
            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
625k
            *op++ = *ip++;
443
625k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
625k
#endif
445
625k
            t = *ip++;
446
625k
        }
447
0
    }
448
449
3.06k
eof_found:
450
3.06k
    *out_len = pd(op, out);
451
3.06k
    return (ip == ip_end ? LZO_E_OK :
452
3.06k
           (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.92k
}
lzo1y_decompress
Line
Count
Source
42
1.46k
{
43
1.46k
    lzo_bytep op;
44
1.46k
    const lzo_bytep ip;
45
1.46k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
1.46k
    const lzo_bytep m_pos;
51
1.46k
#endif
52
53
1.46k
    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.46k
    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.46k
    *out_len = 0;
81
82
1.46k
    op = out;
83
1.46k
    ip = in;
84
85
1.46k
    NEED_IP(1);
86
1.46k
    if (*ip > 17)
87
1.05k
    {
88
1.05k
        t = *ip++ - 17;
89
1.05k
        if (t < 4)
90
498
            goto match_next;
91
1.05k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
7.44k
        do *op++ = *ip++; while (--t > 0);
93
553
        goto first_literal_run;
94
1.05k
    }
95
96
412
    for (;;)
97
459k
    {
98
459k
        NEED_IP(3);
99
459k
        t = *ip++;
100
459k
        if (t >= 16)
101
369k
            goto match;
102
        /* a literal run */
103
89.9k
        if (t == 0)
104
20.1k
        {
105
119k
            while (*ip == 0)
106
99.5k
            {
107
99.5k
                t += 255;
108
99.5k
                ip++;
109
99.5k
                TEST_IV(t);
110
99.5k
                NEED_IP(1);
111
99.5k
            }
112
20.1k
            t += 15 + *ip++;
113
20.1k
        }
114
        /* copy literals */
115
89.9k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
89.9k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
89.9k
        t += 3;
118
89.9k
        if (t >= 8) do
119
3.39M
        {
120
3.39M
            UA_COPY8(op,ip);
121
3.39M
            op += 8; ip += 8; t -= 8;
122
3.39M
        } while (t >= 8);
123
89.9k
        if (t >= 4)
124
61.0k
        {
125
61.0k
            UA_COPY4(op,ip);
126
61.0k
            op += 4; ip += 4; t -= 4;
127
61.0k
        }
128
89.9k
        if (t > 0)
129
56.2k
        {
130
56.2k
            *op++ = *ip++;
131
56.2k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
56.2k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
90.4k
first_literal_run:
167
168
169
90.4k
        t = *ip++;
170
90.4k
        if (t >= 16)
171
88.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
2.06k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
2.06k
        m_pos -= t >> 2;
189
2.06k
        m_pos -= *ip++ << 2;
190
2.06k
#endif
191
2.06k
        TEST_LB(m_pos); NEED_OP(3);
192
2.06k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
2.06k
#endif /* COPY_DICT */
194
2.06k
        goto match_done;
195
196
197
        /* handle matches */
198
408k
        for (;;) {
199
866k
match:
200
866k
            if (t >= 64)                /* a M2 match */
201
425k
            {
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
425k
                m_pos -= (t >> 2) & 3;
229
425k
                m_pos -= *ip++ << 2;
230
425k
                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
425k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
425k
                goto copy_match;
251
425k
#endif /* COPY_DICT */
252
425k
            }
253
440k
            else if (t >= 32)           /* a M3 match */
254
291k
            {
255
291k
                t &= 31;
256
291k
                if (t == 0)
257
67.2k
                {
258
120k
                    while (*ip == 0)
259
53.7k
                    {
260
53.7k
                        t += 255;
261
53.7k
                        ip++;
262
53.7k
                        TEST_OV(t);
263
53.7k
                        NEED_IP(1);
264
53.7k
                    }
265
67.2k
                    t += 31 + *ip++;
266
67.2k
                    NEED_IP(2);
267
67.2k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#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
291k
                m_pos -= UA_GET_LE16(ip) >> 2;
285
#else
286
                m_pos = op - 1;
287
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
288
#endif
289
291k
#endif /* COPY_DICT */
290
291k
                ip += 2;
291
291k
            }
292
149k
            else if (t >= 16)           /* a M4 match */
293
75.0k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
75.0k
                m_pos = op;
298
75.0k
                m_pos -= (t & 8) << 11;
299
75.0k
#endif /* COPY_DICT */
300
75.0k
                t &= 7;
301
75.0k
                if (t == 0)
302
33.3k
                {
303
50.1k
                    while (*ip == 0)
304
16.7k
                    {
305
16.7k
                        t += 255;
306
16.7k
                        ip++;
307
16.7k
                        TEST_OV(t);
308
16.7k
                        NEED_IP(1);
309
16.7k
                    }
310
33.3k
                    t += 7 + *ip++;
311
33.3k
                    NEED_IP(2);
312
33.3k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
75.0k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
75.0k
                ip += 2;
335
75.0k
                if (m_pos == op)
336
1.46k
                    goto eof_found;
337
73.5k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
73.5k
#endif /* COPY_DICT */
342
73.5k
            }
343
74.7k
            else                            /* a M1 match */
344
74.7k
            {
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
74.7k
                m_pos = op - 1;
361
74.7k
                m_pos -= t >> 2;
362
74.7k
                m_pos -= *ip++ << 2;
363
74.7k
#endif
364
74.7k
                TEST_LB(m_pos); NEED_OP(2);
365
74.7k
                *op++ = *m_pos++; *op++ = *m_pos;
366
74.7k
#endif /* COPY_DICT */
367
74.7k
                goto match_done;
368
74.7k
            }
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
364k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
364k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
364k
            if (op - m_pos >= 8)
381
342k
            {
382
342k
                t += (3 - 1);
383
342k
                if (t >= 8) do
384
2.81M
                {
385
2.81M
                    UA_COPY8(op,m_pos);
386
2.81M
                    op += 8; m_pos += 8; t -= 8;
387
2.81M
                } while (t >= 8);
388
342k
                if (t >= 4)
389
188k
                {
390
188k
                    UA_COPY4(op,m_pos);
391
188k
                    op += 4; m_pos += 4; t -= 4;
392
188k
                }
393
342k
                if (t > 0)
394
240k
                {
395
240k
                    *op++ = m_pos[0];
396
240k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
240k
                }
398
342k
            }
399
21.6k
            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
21.6k
            {
420
447k
copy_match:
421
447k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
7.16M
                do *op++ = *m_pos++; while (--t > 0);
423
447k
            }
424
425
364k
#endif /* COPY_DICT */
426
427
866k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
866k
            t = ip[-2] & 3;
432
866k
#endif
433
866k
            if (t == 0)
434
458k
                break;
435
436
            /* copy literals */
437
408k
match_next:
438
408k
            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
408k
            *op++ = *ip++;
443
408k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
408k
#endif
445
408k
            t = *ip++;
446
408k
        }
447
0
    }
448
449
1.46k
eof_found:
450
1.46k
    *out_len = pd(op, out);
451
1.46k
    return (ip == ip_end ? LZO_E_OK :
452
1.46k
           (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
412
}
lzo1z_decompress
Line
Count
Source
42
1.32k
{
43
1.32k
    lzo_bytep op;
44
1.32k
    const lzo_bytep ip;
45
1.32k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
1.32k
    const lzo_bytep m_pos;
51
1.32k
#endif
52
53
1.32k
    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.32k
#if defined(LZO1Z)
58
1.32k
    lzo_uint last_m_off = 0;
59
1.32k
#endif
60
61
1.32k
    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.32k
    *out_len = 0;
81
82
1.32k
    op = out;
83
1.32k
    ip = in;
84
85
1.32k
    NEED_IP(1);
86
1.32k
    if (*ip > 17)
87
1.29k
    {
88
1.29k
        t = *ip++ - 17;
89
1.29k
        if (t < 4)
90
637
            goto match_next;
91
1.29k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
9.27k
        do *op++ = *ip++; while (--t > 0);
93
660
        goto first_literal_run;
94
1.29k
    }
95
96
24
    for (;;)
97
281k
    {
98
281k
        NEED_IP(3);
99
281k
        t = *ip++;
100
281k
        if (t >= 16)
101
232k
            goto match;
102
        /* a literal run */
103
49.1k
        if (t == 0)
104
13.5k
        {
105
49.8k
            while (*ip == 0)
106
36.2k
            {
107
36.2k
                t += 255;
108
36.2k
                ip++;
109
36.2k
                TEST_IV(t);
110
36.2k
                NEED_IP(1);
111
36.2k
            }
112
13.5k
            t += 15 + *ip++;
113
13.5k
        }
114
        /* copy literals */
115
49.1k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
49.1k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
49.1k
        t += 3;
118
49.1k
        if (t >= 8) do
119
1.31M
        {
120
1.31M
            UA_COPY8(op,ip);
121
1.31M
            op += 8; ip += 8; t -= 8;
122
1.31M
        } while (t >= 8);
123
49.1k
        if (t >= 4)
124
33.6k
        {
125
33.6k
            UA_COPY4(op,ip);
126
33.6k
            op += 4; ip += 4; t -= 4;
127
33.6k
        }
128
49.1k
        if (t > 0)
129
31.3k
        {
130
31.3k
            *op++ = *ip++;
131
31.3k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
31.3k
        }
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
49.7k
first_literal_run:
167
168
169
49.7k
        t = *ip++;
170
49.7k
        if (t >= 16)
171
47.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
2.35k
#if defined(LZO1Z)
183
2.35k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
2.35k
        m_pos = op - t;
185
2.35k
        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
2.35k
        TEST_LB(m_pos); NEED_OP(3);
192
2.35k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
2.35k
#endif /* COPY_DICT */
194
2.35k
        goto match_done;
195
196
197
        /* handle matches */
198
490k
        for (;;) {
199
770k
match:
200
770k
            if (t >= 64)                /* a M2 match */
201
282k
            {
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
282k
                    lzo_uint off = t & 0x1f;
234
282k
                    m_pos = op;
235
282k
                    if (off >= 0x1c)
236
17.0k
                    {
237
17.0k
                        assert(last_m_off > 0);
238
17.0k
                        m_pos -= last_m_off;
239
17.0k
                    }
240
265k
                    else
241
265k
                    {
242
265k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
265k
                        m_pos -= off;
244
265k
                        last_m_off = off;
245
265k
                    }
246
282k
                }
247
282k
                t = (t >> 5) - 1;
248
282k
#endif
249
282k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
282k
                goto copy_match;
251
282k
#endif /* COPY_DICT */
252
282k
            }
253
488k
            else if (t >= 32)           /* a M3 match */
254
260k
            {
255
260k
                t &= 31;
256
260k
                if (t == 0)
257
47.5k
                {
258
88.6k
                    while (*ip == 0)
259
41.1k
                    {
260
41.1k
                        t += 255;
261
41.1k
                        ip++;
262
41.1k
                        TEST_OV(t);
263
41.1k
                        NEED_IP(1);
264
41.1k
                    }
265
47.5k
                    t += 31 + *ip++;
266
47.5k
                    NEED_IP(2);
267
47.5k
                }
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
260k
#if defined(LZO1Z)
277
260k
                {
278
260k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
260k
                    m_pos = op - off;
280
260k
                    last_m_off = off;
281
260k
                }
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
260k
#endif /* COPY_DICT */
290
260k
                ip += 2;
291
260k
            }
292
227k
            else if (t >= 16)           /* a M4 match */
293
68.7k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
68.7k
                m_pos = op;
298
68.7k
                m_pos -= (t & 8) << 11;
299
68.7k
#endif /* COPY_DICT */
300
68.7k
                t &= 7;
301
68.7k
                if (t == 0)
302
26.8k
                {
303
40.5k
                    while (*ip == 0)
304
13.7k
                    {
305
13.7k
                        t += 255;
306
13.7k
                        ip++;
307
13.7k
                        TEST_OV(t);
308
13.7k
                        NEED_IP(1);
309
13.7k
                    }
310
26.8k
                    t += 7 + *ip++;
311
26.8k
                    NEED_IP(2);
312
26.8k
                }
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
68.7k
#if defined(LZO1Z)
328
68.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
68.7k
                ip += 2;
335
68.7k
                if (m_pos == op)
336
1.32k
                    goto eof_found;
337
67.4k
                m_pos -= 0x4000;
338
67.4k
#if defined(LZO1Z)
339
67.4k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
67.4k
#endif
341
67.4k
#endif /* COPY_DICT */
342
67.4k
            }
343
158k
            else                            /* a M1 match */
344
158k
            {
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
158k
#if defined(LZO1Z)
356
158k
                t = 1 + (t << 6) + (*ip++ >> 2);
357
158k
                m_pos = op - t;
358
158k
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
158k
                TEST_LB(m_pos); NEED_OP(2);
365
158k
                *op++ = *m_pos++; *op++ = *m_pos;
366
158k
#endif /* COPY_DICT */
367
158k
                goto match_done;
368
158k
            }
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
328k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
328k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
328k
            if (op - m_pos >= 8)
381
305k
            {
382
305k
                t += (3 - 1);
383
305k
                if (t >= 8) do
384
2.20M
                {
385
2.20M
                    UA_COPY8(op,m_pos);
386
2.20M
                    op += 8; m_pos += 8; t -= 8;
387
2.20M
                } while (t >= 8);
388
305k
                if (t >= 4)
389
135k
                {
390
135k
                    UA_COPY4(op,m_pos);
391
135k
                    op += 4; m_pos += 4; t -= 4;
392
135k
                }
393
305k
                if (t > 0)
394
228k
                {
395
228k
                    *op++ = m_pos[0];
396
228k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
228k
                }
398
305k
            }
399
22.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
22.1k
            {
420
304k
copy_match:
421
304k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
5.37M
                do *op++ = *m_pos++; while (--t > 0);
423
304k
            }
424
425
328k
#endif /* COPY_DICT */
426
427
771k
match_done:
428
771k
#if defined(LZO1Z)
429
771k
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
771k
            if (t == 0)
434
281k
                break;
435
436
            /* copy literals */
437
490k
match_next:
438
490k
            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
490k
            *op++ = *ip++;
443
490k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
490k
#endif
445
490k
            t = *ip++;
446
490k
        }
447
0
    }
448
449
1.32k
eof_found:
450
1.32k
    *out_len = pd(op, out);
451
1.32k
    return (ip == ip_end ? LZO_E_OK :
452
1.32k
           (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
24
}
lzo1x_decompress_safe
Line
Count
Source
42
556
{
43
556
    lzo_bytep op;
44
556
    const lzo_bytep ip;
45
556
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
556
    const lzo_bytep m_pos;
51
556
#endif
52
53
556
    const lzo_bytep const ip_end = in + in_len;
54
556
#if defined(HAVE_ANY_OP)
55
556
    lzo_bytep const op_end = out + *out_len;
56
556
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
556
    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
556
    *out_len = 0;
81
82
556
    op = out;
83
556
    ip = in;
84
85
556
    NEED_IP(1);
86
556
    if (*ip > 17)
87
335
    {
88
335
        t = *ip++ - 17;
89
335
        if (t < 4)
90
228
            goto match_next;
91
335
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
1.45k
        do *op++ = *ip++; while (--t > 0);
93
96
        goto first_literal_run;
94
107
    }
95
96
221
    for (;;)
97
59.1k
    {
98
59.1k
        NEED_IP(3);
99
59.1k
        t = *ip++;
100
59.1k
        if (t >= 16)
101
41.8k
            goto match;
102
        /* a literal run */
103
17.2k
        if (t == 0)
104
4.95k
        {
105
4.08M
            while (*ip == 0)
106
4.08M
            {
107
4.08M
                t += 255;
108
4.08M
                ip++;
109
4.08M
                TEST_IV(t);
110
4.08M
                NEED_IP(1);
111
4.08M
            }
112
4.93k
            t += 15 + *ip++;
113
4.93k
        }
114
        /* copy literals */
115
17.2k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
17.0k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
17.0k
        t += 3;
118
17.0k
        if (t >= 8) do
119
273k
        {
120
273k
            UA_COPY8(op,ip);
121
273k
            op += 8; ip += 8; t -= 8;
122
273k
        } while (t >= 8);
123
17.0k
        if (t >= 4)
124
11.5k
        {
125
11.5k
            UA_COPY4(op,ip);
126
11.5k
            op += 4; ip += 4; t -= 4;
127
11.5k
        }
128
17.0k
        if (t > 0)
129
13.1k
        {
130
13.1k
            *op++ = *ip++;
131
13.1k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
13.1k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
17.1k
first_literal_run:
167
168
169
17.1k
        t = *ip++;
170
17.1k
        if (t >= 16)
171
10.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
6.74k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
6.74k
        m_pos -= t >> 2;
189
6.74k
        m_pos -= *ip++ << 2;
190
6.74k
#endif
191
6.74k
        TEST_LB(m_pos); NEED_OP(3);
192
6.70k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
6.70k
#endif /* COPY_DICT */
194
6.70k
        goto match_done;
195
196
197
        /* handle matches */
198
122k
        for (;;) {
199
174k
match:
200
174k
            if (t >= 64)                /* a M2 match */
201
75.0k
            {
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
75.0k
#if defined(LZO1X)
222
75.0k
                m_pos = op - 1;
223
75.0k
                m_pos -= (t >> 2) & 7;
224
75.0k
                m_pos -= *ip++ << 3;
225
75.0k
                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
75.0k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
75.0k
                goto copy_match;
251
75.0k
#endif /* COPY_DICT */
252
75.0k
            }
253
99.3k
            else if (t >= 32)           /* a M3 match */
254
59.3k
            {
255
59.3k
                t &= 31;
256
59.3k
                if (t == 0)
257
5.74k
                {
258
1.29M
                    while (*ip == 0)
259
1.28M
                    {
260
1.28M
                        t += 255;
261
1.28M
                        ip++;
262
1.28M
                        TEST_OV(t);
263
1.28M
                        NEED_IP(1);
264
1.28M
                    }
265
5.73k
                    t += 31 + *ip++;
266
5.73k
                    NEED_IP(2);
267
5.73k
                }
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
59.3k
                m_pos = op - 1;
284
59.3k
                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
59.3k
#endif /* COPY_DICT */
290
59.3k
                ip += 2;
291
59.3k
            }
292
40.0k
            else if (t >= 16)           /* a M4 match */
293
17.6k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
17.6k
                m_pos = op;
298
17.6k
                m_pos -= (t & 8) << 11;
299
17.6k
#endif /* COPY_DICT */
300
17.6k
                t &= 7;
301
17.6k
                if (t == 0)
302
4.04k
                {
303
1.84M
                    while (*ip == 0)
304
1.83M
                    {
305
1.83M
                        t += 255;
306
1.83M
                        ip++;
307
1.83M
                        TEST_OV(t);
308
1.83M
                        NEED_IP(1);
309
1.83M
                    }
310
4.01k
                    t += 7 + *ip++;
311
4.01k
                    NEED_IP(2);
312
4.01k
                }
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
17.6k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
17.6k
                ip += 2;
335
17.6k
                if (m_pos == op)
336
10
                    goto eof_found;
337
17.6k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
17.6k
#endif /* COPY_DICT */
342
17.6k
            }
343
22.3k
            else                            /* a M1 match */
344
22.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
22.3k
                m_pos = op - 1;
361
22.3k
                m_pos -= t >> 2;
362
22.3k
                m_pos -= *ip++ << 2;
363
22.3k
#endif
364
22.3k
                TEST_LB(m_pos); NEED_OP(2);
365
22.3k
                *op++ = *m_pos++; *op++ = *m_pos;
366
22.3k
#endif /* COPY_DICT */
367
22.3k
                goto match_done;
368
22.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
76.9k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
76.8k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
76.8k
            if (op - m_pos >= 8)
381
72.8k
            {
382
72.8k
                t += (3 - 1);
383
72.8k
                if (t >= 8) do
384
616k
                {
385
616k
                    UA_COPY8(op,m_pos);
386
616k
                    op += 8; m_pos += 8; t -= 8;
387
616k
                } while (t >= 8);
388
72.8k
                if (t >= 4)
389
43.7k
                {
390
43.7k
                    UA_COPY4(op,m_pos);
391
43.7k
                    op += 4; m_pos += 4; t -= 4;
392
43.7k
                }
393
72.8k
                if (t > 0)
394
55.4k
                {
395
55.4k
                    *op++ = m_pos[0];
396
55.4k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
55.4k
                }
398
72.8k
            }
399
4.05k
            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
4.05k
            {
420
79.0k
copy_match:
421
79.0k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
10.6M
                do *op++ = *m_pos++; while (--t > 0);
423
79.0k
            }
424
425
76.8k
#endif /* COPY_DICT */
426
427
180k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
180k
            t = ip[-2] & 3;
432
180k
#endif
433
180k
            if (t == 0)
434
58.9k
                break;
435
436
            /* copy literals */
437
122k
match_next:
438
122k
            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
122k
            *op++ = *ip++;
443
122k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
122k
#endif
445
122k
            t = *ip++;
446
122k
        }
447
0
    }
448
449
10
eof_found:
450
10
    *out_len = pd(op, out);
451
10
    return (ip == ip_end ? LZO_E_OK :
452
10
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
340
input_overrun:
457
340
    *out_len = pd(op, out);
458
340
    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
145
lookbehind_overrun:
469
145
    *out_len = pd(op, out);
470
145
    return LZO_E_LOOKBEHIND_OVERRUN;
471
221
#endif
472
221
}
lzo1y_decompress_safe
Line
Count
Source
42
564
{
43
564
    lzo_bytep op;
44
564
    const lzo_bytep ip;
45
564
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
564
    const lzo_bytep m_pos;
51
564
#endif
52
53
564
    const lzo_bytep const ip_end = in + in_len;
54
564
#if defined(HAVE_ANY_OP)
55
564
    lzo_bytep const op_end = out + *out_len;
56
564
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
564
    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
564
    *out_len = 0;
81
82
564
    op = out;
83
564
    ip = in;
84
85
564
    NEED_IP(1);
86
564
    if (*ip > 17)
87
321
    {
88
321
        t = *ip++ - 17;
89
321
        if (t < 4)
90
201
            goto match_next;
91
321
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
2.98k
        do *op++ = *ip++; while (--t > 0);
93
109
        goto first_literal_run;
94
120
    }
95
96
243
    for (;;)
97
56.5k
    {
98
56.5k
        NEED_IP(3);
99
56.4k
        t = *ip++;
100
56.4k
        if (t >= 16)
101
38.2k
            goto match;
102
        /* a literal run */
103
18.2k
        if (t == 0)
104
7.24k
        {
105
10.8M
            while (*ip == 0)
106
10.8M
            {
107
10.8M
                t += 255;
108
10.8M
                ip++;
109
10.8M
                TEST_IV(t);
110
10.8M
                NEED_IP(1);
111
10.8M
            }
112
7.21k
            t += 15 + *ip++;
113
7.21k
        }
114
        /* copy literals */
115
18.2k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
18.0k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
18.0k
        t += 3;
118
18.0k
        if (t >= 8) do
119
550k
        {
120
550k
            UA_COPY8(op,ip);
121
550k
            op += 8; ip += 8; t -= 8;
122
550k
        } while (t >= 8);
123
18.0k
        if (t >= 4)
124
12.0k
        {
125
12.0k
            UA_COPY4(op,ip);
126
12.0k
            op += 4; ip += 4; t -= 4;
127
12.0k
        }
128
18.0k
        if (t > 0)
129
13.6k
        {
130
13.6k
            *op++ = *ip++;
131
13.6k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
13.6k
        }
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
18.1k
first_literal_run:
167
168
169
18.1k
        t = *ip++;
170
18.1k
        if (t >= 16)
171
9.61k
            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
8.53k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
8.53k
        m_pos -= t >> 2;
189
8.53k
        m_pos -= *ip++ << 2;
190
8.53k
#endif
191
8.53k
        TEST_LB(m_pos); NEED_OP(3);
192
8.49k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
8.49k
#endif /* COPY_DICT */
194
8.49k
        goto match_done;
195
196
197
        /* handle matches */
198
107k
        for (;;) {
199
155k
match:
200
155k
            if (t >= 64)                /* a M2 match */
201
70.2k
            {
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
70.2k
                m_pos -= (t >> 2) & 3;
229
70.2k
                m_pos -= *ip++ << 2;
230
70.2k
                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
70.2k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
70.2k
                goto copy_match;
251
70.2k
#endif /* COPY_DICT */
252
70.2k
            }
253
85.5k
            else if (t >= 32)           /* a M3 match */
254
47.4k
            {
255
47.4k
                t &= 31;
256
47.4k
                if (t == 0)
257
8.53k
                {
258
1.60M
                    while (*ip == 0)
259
1.59M
                    {
260
1.59M
                        t += 255;
261
1.59M
                        ip++;
262
1.59M
                        TEST_OV(t);
263
1.59M
                        NEED_IP(1);
264
1.59M
                    }
265
8.52k
                    t += 31 + *ip++;
266
8.52k
                    NEED_IP(2);
267
8.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
47.4k
                m_pos = op - 1;
284
47.4k
                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
47.4k
#endif /* COPY_DICT */
290
47.4k
                ip += 2;
291
47.4k
            }
292
38.1k
            else if (t >= 16)           /* a M4 match */
293
14.1k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
14.1k
                m_pos = op;
298
14.1k
                m_pos -= (t & 8) << 11;
299
14.1k
#endif /* COPY_DICT */
300
14.1k
                t &= 7;
301
14.1k
                if (t == 0)
302
3.42k
                {
303
1.86M
                    while (*ip == 0)
304
1.85M
                    {
305
1.85M
                        t += 255;
306
1.85M
                        ip++;
307
1.85M
                        TEST_OV(t);
308
1.85M
                        NEED_IP(1);
309
1.85M
                    }
310
3.40k
                    t += 7 + *ip++;
311
3.40k
                    NEED_IP(2);
312
3.40k
                }
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
14.1k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
14.1k
                ip += 2;
335
14.1k
                if (m_pos == op)
336
14
                    goto eof_found;
337
14.1k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
14.1k
#endif /* COPY_DICT */
342
14.1k
            }
343
23.9k
            else                            /* a M1 match */
344
23.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
#if defined(LZO1Z)
356
                t = 1 + (t << 6) + (*ip++ >> 2);
357
                m_pos = op - t;
358
                last_m_off = t;
359
#else
360
23.9k
                m_pos = op - 1;
361
23.9k
                m_pos -= t >> 2;
362
23.9k
                m_pos -= *ip++ << 2;
363
23.9k
#endif
364
23.9k
                TEST_LB(m_pos); NEED_OP(2);
365
23.9k
                *op++ = *m_pos++; *op++ = *m_pos;
366
23.9k
#endif /* COPY_DICT */
367
23.9k
                goto match_done;
368
23.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
61.5k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
61.4k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
61.4k
            if (op - m_pos >= 8)
381
57.2k
            {
382
57.2k
                t += (3 - 1);
383
57.2k
                if (t >= 8) do
384
455k
                {
385
455k
                    UA_COPY8(op,m_pos);
386
455k
                    op += 8; m_pos += 8; t -= 8;
387
455k
                } while (t >= 8);
388
57.2k
                if (t >= 4)
389
33.1k
                {
390
33.1k
                    UA_COPY4(op,m_pos);
391
33.1k
                    op += 4; m_pos += 4; t -= 4;
392
33.1k
                }
393
57.2k
                if (t > 0)
394
45.5k
                {
395
45.5k
                    *op++ = m_pos[0];
396
45.5k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
45.5k
                }
398
57.2k
            }
399
4.16k
            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
4.16k
            {
420
74.4k
copy_match:
421
74.4k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
8.89M
                do *op++ = *m_pos++; while (--t > 0);
423
74.4k
            }
424
425
61.4k
#endif /* COPY_DICT */
426
427
164k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
164k
            t = ip[-2] & 3;
432
164k
#endif
433
164k
            if (t == 0)
434
56.2k
                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
107k
            *op++ = *ip++;
443
107k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
107k
#endif
445
107k
            t = *ip++;
446
107k
        }
447
0
    }
448
449
14
eof_found:
450
14
    *out_len = pd(op, out);
451
14
    return (ip == ip_end ? LZO_E_OK :
452
14
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
320
input_overrun:
457
320
    *out_len = pd(op, out);
458
320
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
59
output_overrun:
463
59
    *out_len = pd(op, out);
464
59
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
171
lookbehind_overrun:
469
171
    *out_len = pd(op, out);
470
171
    return LZO_E_LOOKBEHIND_OVERRUN;
471
243
#endif
472
243
}
lzo1z_decompress_safe
Line
Count
Source
42
540
{
43
540
    lzo_bytep op;
44
540
    const lzo_bytep ip;
45
540
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
540
    const lzo_bytep m_pos;
51
540
#endif
52
53
540
    const lzo_bytep const ip_end = in + in_len;
54
540
#if defined(HAVE_ANY_OP)
55
540
    lzo_bytep const op_end = out + *out_len;
56
540
#endif
57
540
#if defined(LZO1Z)
58
540
    lzo_uint last_m_off = 0;
59
540
#endif
60
61
540
    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
540
    *out_len = 0;
81
82
540
    op = out;
83
540
    ip = in;
84
85
540
    NEED_IP(1);
86
540
    if (*ip > 17)
87
353
    {
88
353
        t = *ip++ - 17;
89
353
        if (t < 4)
90
244
            goto match_next;
91
353
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
2.03k
        do *op++ = *ip++; while (--t > 0);
93
97
        goto first_literal_run;
94
109
    }
95
96
187
    for (;;)
97
42.4k
    {
98
42.4k
        NEED_IP(3);
99
42.4k
        t = *ip++;
100
42.4k
        if (t >= 16)
101
28.5k
            goto match;
102
        /* a literal run */
103
13.8k
        if (t == 0)
104
5.34k
        {
105
2.84M
            while (*ip == 0)
106
2.83M
            {
107
2.83M
                t += 255;
108
2.83M
                ip++;
109
2.83M
                TEST_IV(t);
110
2.83M
                NEED_IP(1);
111
2.83M
            }
112
5.31k
            t += 15 + *ip++;
113
5.31k
        }
114
        /* copy literals */
115
13.8k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
13.6k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
13.6k
        t += 3;
118
13.6k
        if (t >= 8) do
119
265k
        {
120
265k
            UA_COPY8(op,ip);
121
265k
            op += 8; ip += 8; t -= 8;
122
265k
        } while (t >= 8);
123
13.6k
        if (t >= 4)
124
7.85k
        {
125
7.85k
            UA_COPY4(op,ip);
126
7.85k
            op += 4; ip += 4; t -= 4;
127
7.85k
        }
128
13.6k
        if (t > 0)
129
8.64k
        {
130
8.64k
            *op++ = *ip++;
131
8.64k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
8.64k
        }
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.7k
first_literal_run:
167
168
169
13.7k
        t = *ip++;
170
13.7k
        if (t >= 16)
171
6.94k
            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.84k
#if defined(LZO1Z)
183
6.84k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
6.84k
        m_pos = op - t;
185
6.84k
        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.84k
        TEST_LB(m_pos); NEED_OP(3);
192
6.81k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
6.81k
#endif /* COPY_DICT */
194
6.81k
        goto match_done;
195
196
197
        /* handle matches */
198
53.5k
        for (;;) {
199
89.0k
match:
200
89.0k
            if (t >= 64)                /* a M2 match */
201
49.8k
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
#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
49.8k
                    lzo_uint off = t & 0x1f;
234
49.8k
                    m_pos = op;
235
49.8k
                    if (off >= 0x1c)
236
7.56k
                    {
237
7.56k
                        assert(last_m_off > 0);
238
7.56k
                        m_pos -= last_m_off;
239
7.56k
                    }
240
42.2k
                    else
241
42.2k
                    {
242
42.2k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
42.2k
                        m_pos -= off;
244
42.2k
                        last_m_off = off;
245
42.2k
                    }
246
49.8k
                }
247
49.8k
                t = (t >> 5) - 1;
248
49.8k
#endif
249
49.8k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
49.8k
                goto copy_match;
251
49.8k
#endif /* COPY_DICT */
252
49.8k
            }
253
39.2k
            else if (t >= 32)           /* a M3 match */
254
23.2k
            {
255
23.2k
                t &= 31;
256
23.2k
                if (t == 0)
257
3.74k
                {
258
1.65M
                    while (*ip == 0)
259
1.64M
                    {
260
1.64M
                        t += 255;
261
1.64M
                        ip++;
262
1.64M
                        TEST_OV(t);
263
1.64M
                        NEED_IP(1);
264
1.64M
                    }
265
3.73k
                    t += 31 + *ip++;
266
3.73k
                    NEED_IP(2);
267
3.73k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
23.2k
#if defined(LZO1Z)
277
23.2k
                {
278
23.2k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
23.2k
                    m_pos = op - off;
280
23.2k
                    last_m_off = off;
281
23.2k
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
                m_pos = op - 1;
284
                m_pos -= UA_GET_LE16(ip) >> 2;
285
#else
286
                m_pos = op - 1;
287
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
288
#endif
289
23.2k
#endif /* COPY_DICT */
290
23.2k
                ip += 2;
291
23.2k
            }
292
16.0k
            else if (t >= 16)           /* a M4 match */
293
9.01k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
9.01k
                m_pos = op;
298
9.01k
                m_pos -= (t & 8) << 11;
299
9.01k
#endif /* COPY_DICT */
300
9.01k
                t &= 7;
301
9.01k
                if (t == 0)
302
4.09k
                {
303
5.06k
                    while (*ip == 0)
304
972
                    {
305
972
                        t += 255;
306
972
                        ip++;
307
972
                        TEST_OV(t);
308
972
                        NEED_IP(1);
309
972
                    }
310
4.08k
                    t += 7 + *ip++;
311
4.08k
                    NEED_IP(2);
312
4.08k
                }
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
9.00k
#if defined(LZO1Z)
328
9.00k
                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
9.00k
                ip += 2;
335
9.00k
                if (m_pos == op)
336
10
                    goto eof_found;
337
8.99k
                m_pos -= 0x4000;
338
8.99k
#if defined(LZO1Z)
339
8.99k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
8.99k
#endif
341
8.99k
#endif /* COPY_DICT */
342
8.99k
            }
343
6.98k
            else                            /* a M1 match */
344
6.98k
            {
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
6.98k
#if defined(LZO1Z)
356
6.98k
                t = 1 + (t << 6) + (*ip++ >> 2);
357
6.98k
                m_pos = op - t;
358
6.98k
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
6.98k
                TEST_LB(m_pos); NEED_OP(2);
365
6.98k
                *op++ = *m_pos++; *op++ = *m_pos;
366
6.98k
#endif /* COPY_DICT */
367
6.98k
                goto match_done;
368
6.98k
            }
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
32.2k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
32.1k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
32.1k
            if (op - m_pos >= 8)
381
28.9k
            {
382
28.9k
                t += (3 - 1);
383
28.9k
                if (t >= 8) do
384
679k
                {
385
679k
                    UA_COPY8(op,m_pos);
386
679k
                    op += 8; m_pos += 8; t -= 8;
387
679k
                } while (t >= 8);
388
28.9k
                if (t >= 4)
389
14.5k
                {
390
14.5k
                    UA_COPY4(op,m_pos);
391
14.5k
                    op += 4; m_pos += 4; t -= 4;
392
14.5k
                }
393
28.9k
                if (t > 0)
394
23.4k
                {
395
23.4k
                    *op++ = m_pos[0];
396
23.4k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
23.4k
                }
398
28.9k
            }
399
3.16k
            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.16k
            {
420
52.9k
copy_match:
421
52.9k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
6.84M
                do *op++ = *m_pos++; while (--t > 0);
423
52.9k
            }
424
425
32.1k
#endif /* COPY_DICT */
426
427
95.7k
match_done:
428
95.7k
#if defined(LZO1Z)
429
95.7k
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
95.7k
            if (t == 0)
434
42.3k
                break;
435
436
            /* copy literals */
437
53.6k
match_next:
438
53.6k
            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
53.5k
            *op++ = *ip++;
443
53.5k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
53.5k
#endif
445
53.5k
            t = *ip++;
446
53.5k
        }
447
0
    }
448
449
10
eof_found:
450
10
    *out_len = pd(op, out);
451
10
    return (ip == ip_end ? LZO_E_OK :
452
10
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
342
input_overrun:
457
342
    *out_len = pd(op, out);
458
342
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
46
output_overrun:
463
46
    *out_len = pd(op, out);
464
46
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
142
lookbehind_overrun:
469
142
    *out_len = pd(op, out);
470
142
    return LZO_E_LOOKBEHIND_OVERRUN;
471
187
#endif
472
187
}
473
474
475
/* vim:set ts=4 sw=4 et: */