Coverage Report

Created: 2026-08-13 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/lzo-2.10/src/lzo1x_d.ch
Line
Count
Source
1
/* lzo1x_d.ch -- implementation of the LZO1X decompression algorithm
2
3
   This file is part of the LZO real-time data compression library.
4
5
   Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
6
   All Rights Reserved.
7
8
   The LZO library is free software; you can redistribute it and/or
9
   modify it under the terms of the GNU General Public License as
10
   published by the Free Software Foundation; either version 2 of
11
   the License, or (at your option) any later version.
12
13
   The LZO library is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with the LZO library; see the file COPYING.
20
   If not, write to the Free Software Foundation, Inc.,
21
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22
23
   Markus F.X.J. Oberhumer
24
   <markus@oberhumer.com>
25
   http://www.oberhumer.com/opensource/lzo/
26
 */
27
28
29
#include "lzo1_d.ch"
30
31
32
/***********************************************************************
33
// decompress a block of data.
34
************************************************************************/
35
36
#if defined(DO_DECOMPRESS)
37
LZO_PUBLIC(int)
38
DO_DECOMPRESS  ( const lzo_bytep in , lzo_uint  in_len,
39
                       lzo_bytep out, lzo_uintp out_len,
40
                       lzo_voidp wrkmem )
41
#endif
42
9.25k
{
43
9.25k
    lzo_bytep op;
44
9.25k
    const lzo_bytep ip;
45
9.25k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
9.25k
    const lzo_bytep m_pos;
51
9.25k
#endif
52
53
9.25k
    const lzo_bytep const ip_end = in + in_len;
54
#if defined(HAVE_ANY_OP)
55
1.84k
    lzo_bytep const op_end = out + *out_len;
56
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
9.25k
    LZO_UNUSED(wrkmem);
62
63
#if defined(COPY_DICT)
64
    if (dict)
65
    {
66
        if (dict_len > M4_MAX_OFFSET)
67
        {
68
            dict += dict_len - M4_MAX_OFFSET;
69
            dict_len = M4_MAX_OFFSET;
70
        }
71
        dict_end = dict + dict_len;
72
    }
73
    else
74
    {
75
        dict_len = 0;
76
        dict_end = NULL;
77
    }
78
#endif /* COPY_DICT */
79
80
9.25k
    *out_len = 0;
81
82
9.25k
    op = out;
83
9.25k
    ip = in;
84
85
9.25k
    NEED_IP(1);
86
9.25k
    if (*ip > 17)
87
5.65k
    {
88
5.65k
        t = *ip++ - 17;
89
5.65k
        if (t < 4)
90
2.72k
            goto match_next;
91
5.65k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
60.4k
        do *op++ = *ip++; while (--t > 0);
93
294
        goto first_literal_run;
94
334
    }
95
96
3.60k
    for (;;)
97
1.67M
    {
98
1.67M
        NEED_IP(3);
99
171k
        t = *ip++;
100
1.67M
        if (t >= 16)
101
1.27M
            goto match;
102
        /* a literal run */
103
401k
        if (t == 0)
104
141k
        {
105
26.7M
            while (*ip == 0)
106
26.5M
            {
107
26.5M
                t += 255;
108
26.5M
                ip++;
109
26.5M
                TEST_IV(t);
110
26.5M
                NEED_IP(1);
111
25.8M
            }
112
28.6k
            t += 15 + *ip++;
113
28.6k
        }
114
        /* copy literals */
115
401k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
52.7k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
52.7k
        t += 3;
118
400k
        if (t >= 8) do
119
23.8M
        {
120
23.8M
            UA_COPY8(op,ip);
121
23.8M
            op += 8; ip += 8; t -= 8;
122
23.8M
        } while (t >= 8);
123
400k
        if (t >= 4)
124
251k
        {
125
251k
            UA_COPY4(op,ip);
126
251k
            op += 4; ip += 4; t -= 4;
127
251k
        }
128
400k
        if (t > 0)
129
268k
        {
130
268k
            *op++ = *ip++;
131
268k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
268k
        }
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
403k
first_literal_run:
167
168
169
403k
        t = *ip++;
170
403k
        if (t >= 16)
171
360k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
13.7k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
5.29k
        m_pos = op - t;
185
5.29k
        last_m_off = t;
186
#else
187
29.0k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
        m_pos -= t >> 2;
189
        m_pos -= *ip++ << 2;
190
#endif
191
42.8k
        TEST_LB(m_pos); NEED_OP(3);
192
29.6k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
29.6k
#endif /* COPY_DICT */
194
29.6k
        goto match_done;
195
196
197
        /* handle matches */
198
2.27M
        for (;;) {
199
3.90M
match:
200
3.90M
            if (t >= 64)                /* a M2 match */
201
1.59M
            {
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
396k
                    if (off >= 0x1c)
236
30.6k
                    {
237
30.6k
                        assert(last_m_off > 0);
238
30.6k
                        m_pos -= last_m_off;
239
30.6k
                    }
240
366k
                    else
241
366k
                    {
242
366k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
366k
                        m_pos -= off;
244
366k
                        last_m_off = off;
245
366k
                    }
246
                }
247
                t = (t >> 5) - 1;
248
#endif
249
1.59M
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
203k
                goto copy_match;
251
203k
#endif /* COPY_DICT */
252
203k
            }
253
2.30M
            else if (t >= 32)           /* a M3 match */
254
1.03M
            {
255
1.03M
                t &= 31;
256
1.03M
                if (t == 0)
257
208k
                {
258
21.3M
                    while (*ip == 0)
259
21.1M
                    {
260
21.1M
                        t += 255;
261
21.1M
                        ip++;
262
21.1M
                        TEST_OV(t);
263
21.1M
                        NEED_IP(1);
264
20.9M
                    }
265
8.57k
                    t += 31 + *ip++;
266
208k
                    NEED_IP(2);
267
8.57k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
19.2k
                {
278
19.2k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
19.2k
                    m_pos = op - off;
280
19.2k
                    last_m_off = off;
281
19.2k
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
60.1k
                m_pos = op - 1;
284
778k
                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
60.1k
#endif /* COPY_DICT */
290
60.1k
                ip += 2;
291
60.1k
            }
292
1.26M
            else if (t >= 16)           /* a M4 match */
293
197k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
197k
                m_pos = op;
298
197k
                m_pos -= (t & 8) << 11;
299
197k
#endif /* COPY_DICT */
300
197k
                t &= 7;
301
197k
                if (t == 0)
302
73.6k
                {
303
7.98M
                    while (*ip == 0)
304
7.91M
                    {
305
7.91M
                        t += 255;
306
7.91M
                        ip++;
307
7.91M
                        TEST_OV(t);
308
7.91M
                        NEED_IP(1);
309
7.87M
                    }
310
7.55k
                    t += 7 + *ip++;
311
73.5k
                    NEED_IP(2);
312
7.55k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
6.75k
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
138k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
17.6k
                ip += 2;
335
197k
                if (m_pos == op)
336
7.44k
                    goto eof_found;
337
190k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
57.4k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
190k
#endif /* COPY_DICT */
342
190k
            }
343
1.07M
            else                            /* a M1 match */
344
1.07M
            {
345
#if defined(COPY_DICT)
346
#if defined(LZO1Z)
347
                m_off = 1 + (t << 6) + (*ip++ >> 2);
348
                last_m_off = m_off;
349
#else
350
                m_off = 1 + (t >> 2) + (*ip++ << 2);
351
#endif
352
                NEED_OP(2);
353
                t = 2; COPY_DICT(t,m_off)
354
#else /* !COPY_DICT */
355
#if defined(LZO1Z)
356
                t = 1 + (t << 6) + (*ip++ >> 2);
357
                m_pos = op - t;
358
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
1.07M
                TEST_LB(m_pos); NEED_OP(2);
365
118k
                *op++ = *m_pos++; *op++ = *m_pos;
366
118k
#endif /* COPY_DICT */
367
118k
                goto match_done;
368
118k
            }
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.22M
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
103k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
1.22M
            if (op - m_pos >= 8)
381
1.15M
            {
382
1.15M
                t += (3 - 1);
383
1.15M
                if (t >= 8) do
384
9.24M
                {
385
9.24M
                    UA_COPY8(op,m_pos);
386
9.24M
                    op += 8; m_pos += 8; t -= 8;
387
9.24M
                } while (t >= 8);
388
1.15M
                if (t >= 4)
389
568k
                {
390
568k
                    UA_COPY4(op,m_pos);
391
568k
                    op += 4; m_pos += 4; t -= 4;
392
568k
                }
393
1.15M
                if (t > 0)
394
839k
                {
395
839k
                    *op++ = m_pos[0];
396
839k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
839k
                }
398
1.15M
            }
399
77.8k
            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
77.8k
            {
420
1.67M
copy_match:
421
1.67M
                *op++ = *m_pos++; *op++ = *m_pos++;
422
70.5M
                do *op++ = *m_pos++; while (--t > 0);
423
1.67M
            }
424
425
103k
#endif /* COPY_DICT */
426
427
3.94M
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
3.94M
            if (t == 0)
434
1.67M
                break;
435
436
            /* copy literals */
437
2.27M
match_next:
438
2.27M
            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
284k
            *op++ = *ip++;
443
2.27M
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
284k
#endif
445
284k
            t = *ip++;
446
284k
        }
447
0
    }
448
449
7.44k
eof_found:
450
7.44k
    *out_len = pd(op, out);
451
7.44k
    return (ip == ip_end ? LZO_E_OK :
452
7.44k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
#if defined(HAVE_NEED_IP)
456
1.14k
input_overrun:
457
1.14k
    *out_len = pd(op, out);
458
1.14k
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
#if defined(HAVE_NEED_OP)
462
179
output_overrun:
463
179
    *out_len = pd(op, out);
464
179
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
486
lookbehind_overrun:
469
486
    *out_len = pd(op, out);
470
486
    return LZO_E_LOOKBEHIND_OVERRUN;
471
#endif
472
3.60k
}
lzo1x_decompress
Line
Count
Source
42
3.85k
{
43
3.85k
    lzo_bytep op;
44
3.85k
    const lzo_bytep ip;
45
3.85k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
3.85k
    const lzo_bytep m_pos;
51
3.85k
#endif
52
53
3.85k
    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.85k
    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.85k
    *out_len = 0;
81
82
3.85k
    op = out;
83
3.85k
    ip = in;
84
85
3.85k
    NEED_IP(1);
86
3.85k
    if (*ip > 17)
87
1.47k
    {
88
1.47k
        t = *ip++ - 17;
89
1.47k
        if (t < 4)
90
611
            goto match_next;
91
1.47k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
22.2k
        do *op++ = *ip++; while (--t > 0);
93
859
        goto first_literal_run;
94
1.47k
    }
95
96
2.38k
    for (;;)
97
908k
    {
98
908k
        NEED_IP(3);
99
908k
        t = *ip++;
100
908k
        if (t >= 16)
101
698k
            goto match;
102
        /* a literal run */
103
210k
        if (t == 0)
104
62.5k
        {
105
559k
            while (*ip == 0)
106
496k
            {
107
496k
                t += 255;
108
496k
                ip++;
109
496k
                TEST_IV(t);
110
496k
                NEED_IP(1);
111
496k
            }
112
62.5k
            t += 15 + *ip++;
113
62.5k
        }
114
        /* copy literals */
115
210k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
210k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
210k
        t += 3;
118
210k
        if (t >= 8) do
119
16.4M
        {
120
16.4M
            UA_COPY8(op,ip);
121
16.4M
            op += 8; ip += 8; t -= 8;
122
16.4M
        } while (t >= 8);
123
210k
        if (t >= 4)
124
136k
        {
125
136k
            UA_COPY4(op,ip);
126
136k
            op += 4; ip += 4; t -= 4;
127
136k
        }
128
210k
        if (t > 0)
129
135k
        {
130
135k
            *op++ = *ip++;
131
135k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
135k
        }
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
211k
first_literal_run:
167
168
169
211k
        t = *ip++;
170
211k
        if (t >= 16)
171
208k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
3.20k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
3.20k
        m_pos -= t >> 2;
189
3.20k
        m_pos -= *ip++ << 2;
190
3.20k
#endif
191
3.20k
        TEST_LB(m_pos); NEED_OP(3);
192
3.20k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
3.20k
#endif /* COPY_DICT */
194
3.20k
        goto match_done;
195
196
197
        /* handle matches */
198
640k
        for (;;) {
199
1.54M
match:
200
1.54M
            if (t >= 64)                /* a M2 match */
201
782k
            {
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
782k
#if defined(LZO1X)
222
782k
                m_pos = op - 1;
223
782k
                m_pos -= (t >> 2) & 7;
224
782k
                m_pos -= *ip++ << 3;
225
782k
                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
782k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
782k
                goto copy_match;
251
782k
#endif /* COPY_DICT */
252
782k
            }
253
764k
            else if (t >= 32)           /* a M3 match */
254
492k
            {
255
492k
                t &= 31;
256
492k
                if (t == 0)
257
109k
                {
258
240k
                    while (*ip == 0)
259
130k
                    {
260
130k
                        t += 255;
261
130k
                        ip++;
262
130k
                        TEST_OV(t);
263
130k
                        NEED_IP(1);
264
130k
                    }
265
109k
                    t += 31 + *ip++;
266
109k
                    NEED_IP(2);
267
109k
                }
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
492k
                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
492k
#endif /* COPY_DICT */
290
492k
                ip += 2;
291
492k
            }
292
272k
            else if (t >= 16)           /* a M4 match */
293
79.5k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
79.5k
                m_pos = op;
298
79.5k
                m_pos -= (t & 8) << 11;
299
79.5k
#endif /* COPY_DICT */
300
79.5k
                t &= 7;
301
79.5k
                if (t == 0)
302
31.4k
                {
303
57.2k
                    while (*ip == 0)
304
25.7k
                    {
305
25.7k
                        t += 255;
306
25.7k
                        ip++;
307
25.7k
                        TEST_OV(t);
308
25.7k
                        NEED_IP(1);
309
25.7k
                    }
310
31.4k
                    t += 7 + *ip++;
311
31.4k
                    NEED_IP(2);
312
31.4k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
79.5k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
79.5k
                ip += 2;
335
79.5k
                if (m_pos == op)
336
3.85k
                    goto eof_found;
337
75.7k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
75.7k
#endif /* COPY_DICT */
342
75.7k
            }
343
192k
            else                            /* a M1 match */
344
192k
            {
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
192k
                m_pos = op - 1;
361
192k
                m_pos -= t >> 2;
362
192k
                m_pos -= *ip++ << 2;
363
192k
#endif
364
192k
                TEST_LB(m_pos); NEED_OP(2);
365
192k
                *op++ = *m_pos++; *op++ = *m_pos;
366
192k
#endif /* COPY_DICT */
367
192k
                goto match_done;
368
192k
            }
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
567k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
567k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
567k
            if (op - m_pos >= 8)
381
528k
            {
382
528k
                t += (3 - 1);
383
528k
                if (t >= 8) do
384
4.15M
                {
385
4.15M
                    UA_COPY8(op,m_pos);
386
4.15M
                    op += 8; m_pos += 8; t -= 8;
387
4.15M
                } while (t >= 8);
388
528k
                if (t >= 4)
389
278k
                {
390
278k
                    UA_COPY4(op,m_pos);
391
278k
                    op += 4; m_pos += 4; t -= 4;
392
278k
                }
393
528k
                if (t > 0)
394
370k
                {
395
370k
                    *op++ = m_pos[0];
396
370k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
370k
                }
398
528k
            }
399
39.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
39.6k
            {
420
821k
copy_match:
421
821k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
23.6M
                do *op++ = *m_pos++; while (--t > 0);
423
821k
            }
424
425
567k
#endif /* COPY_DICT */
426
427
1.54M
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
1.54M
            t = ip[-2] & 3;
432
1.54M
#endif
433
1.54M
            if (t == 0)
434
906k
                break;
435
436
            /* copy literals */
437
640k
match_next:
438
640k
            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
640k
            *op++ = *ip++;
443
640k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
640k
#endif
445
640k
            t = *ip++;
446
640k
        }
447
0
    }
448
449
3.85k
eof_found:
450
3.85k
    *out_len = pd(op, out);
451
3.85k
    return (ip == ip_end ? LZO_E_OK :
452
3.85k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
#if defined(HAVE_NEED_IP)
456
input_overrun:
457
    *out_len = pd(op, out);
458
    return LZO_E_INPUT_OVERRUN;
459
#endif
460
461
#if defined(HAVE_NEED_OP)
462
output_overrun:
463
    *out_len = pd(op, out);
464
    return LZO_E_OUTPUT_OVERRUN;
465
#endif
466
467
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
lookbehind_overrun:
469
    *out_len = pd(op, out);
470
    return LZO_E_LOOKBEHIND_OVERRUN;
471
#endif
472
2.38k
}
lzo1y_decompress
Line
Count
Source
42
1.86k
{
43
1.86k
    lzo_bytep op;
44
1.86k
    const lzo_bytep ip;
45
1.86k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
1.86k
    const lzo_bytep m_pos;
51
1.86k
#endif
52
53
1.86k
    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.86k
    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.86k
    *out_len = 0;
81
82
1.86k
    op = out;
83
1.86k
    ip = in;
84
85
1.86k
    NEED_IP(1);
86
1.86k
    if (*ip > 17)
87
1.38k
    {
88
1.38k
        t = *ip++ - 17;
89
1.38k
        if (t < 4)
90
557
            goto match_next;
91
1.38k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
14.2k
        do *op++ = *ip++; while (--t > 0);
93
832
        goto first_literal_run;
94
1.38k
    }
95
96
478
    for (;;)
97
299k
    {
98
299k
        NEED_IP(3);
99
299k
        t = *ip++;
100
299k
        if (t >= 16)
101
227k
            goto match;
102
        /* a literal run */
103
71.2k
        if (t == 0)
104
25.6k
        {
105
168k
            while (*ip == 0)
106
142k
            {
107
142k
                t += 255;
108
142k
                ip++;
109
142k
                TEST_IV(t);
110
142k
                NEED_IP(1);
111
142k
            }
112
25.6k
            t += 15 + *ip++;
113
25.6k
        }
114
        /* copy literals */
115
71.2k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
71.2k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
71.2k
        t += 3;
118
71.2k
        if (t >= 8) do
119
4.79M
        {
120
4.79M
            UA_COPY8(op,ip);
121
4.79M
            op += 8; ip += 8; t -= 8;
122
4.79M
        } while (t >= 8);
123
71.2k
        if (t >= 4)
124
44.5k
        {
125
44.5k
            UA_COPY4(op,ip);
126
44.5k
            op += 4; ip += 4; t -= 4;
127
44.5k
        }
128
71.2k
        if (t > 0)
129
47.2k
        {
130
47.2k
            *op++ = *ip++;
131
47.2k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
47.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
72.0k
first_literal_run:
167
168
169
72.0k
        t = *ip++;
170
72.0k
        if (t >= 16)
171
67.5k
            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
4.55k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
4.55k
        m_pos -= t >> 2;
189
4.55k
        m_pos -= *ip++ << 2;
190
4.55k
#endif
191
4.55k
        TEST_LB(m_pos); NEED_OP(3);
192
4.55k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
4.55k
#endif /* COPY_DICT */
194
4.55k
        goto match_done;
195
196
197
        /* handle matches */
198
603k
        for (;;) {
199
898k
match:
200
898k
            if (t >= 64)                /* a M2 match */
201
295k
            {
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
295k
                m_pos -= (t >> 2) & 3;
229
295k
                m_pos -= *ip++ << 2;
230
295k
                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
295k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
295k
                goto copy_match;
251
295k
#endif /* COPY_DICT */
252
295k
            }
253
603k
            else if (t >= 32)           /* a M3 match */
254
226k
            {
255
226k
                t &= 31;
256
226k
                if (t == 0)
257
49.7k
                {
258
95.5k
                    while (*ip == 0)
259
45.7k
                    {
260
45.7k
                        t += 255;
261
45.7k
                        ip++;
262
45.7k
                        TEST_OV(t);
263
45.7k
                        NEED_IP(1);
264
45.7k
                    }
265
49.7k
                    t += 31 + *ip++;
266
49.7k
                    NEED_IP(2);
267
49.7k
                }
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
226k
                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
226k
#endif /* COPY_DICT */
290
226k
                ip += 2;
291
226k
            }
292
376k
            else if (t >= 16)           /* a M4 match */
293
41.2k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
41.2k
                m_pos = op;
298
41.2k
                m_pos -= (t & 8) << 11;
299
41.2k
#endif /* COPY_DICT */
300
41.2k
                t &= 7;
301
41.2k
                if (t == 0)
302
15.8k
                {
303
25.7k
                    while (*ip == 0)
304
9.91k
                    {
305
9.91k
                        t += 255;
306
9.91k
                        ip++;
307
9.91k
                        TEST_OV(t);
308
9.91k
                        NEED_IP(1);
309
9.91k
                    }
310
15.8k
                    t += 7 + *ip++;
311
15.8k
                    NEED_IP(2);
312
15.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
#if defined(LZO1Z)
328
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
41.2k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
41.2k
                ip += 2;
335
41.2k
                if (m_pos == op)
336
1.86k
                    goto eof_found;
337
39.3k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
39.3k
#endif /* COPY_DICT */
342
39.3k
            }
343
335k
            else                            /* a M1 match */
344
335k
            {
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
335k
                m_pos = op - 1;
361
335k
                m_pos -= t >> 2;
362
335k
                m_pos -= *ip++ << 2;
363
335k
#endif
364
335k
                TEST_LB(m_pos); NEED_OP(2);
365
335k
                *op++ = *m_pos++; *op++ = *m_pos;
366
335k
#endif /* COPY_DICT */
367
335k
                goto match_done;
368
335k
            }
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
265k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
265k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
265k
            if (op - m_pos >= 8)
381
252k
            {
382
252k
                t += (3 - 1);
383
252k
                if (t >= 8) do
384
1.57M
                {
385
1.57M
                    UA_COPY8(op,m_pos);
386
1.57M
                    op += 8; m_pos += 8; t -= 8;
387
1.57M
                } while (t >= 8);
388
252k
                if (t >= 4)
389
129k
                {
390
129k
                    UA_COPY4(op,m_pos);
391
129k
                    op += 4; m_pos += 4; t -= 4;
392
129k
                }
393
252k
                if (t > 0)
394
178k
                {
395
178k
                    *op++ = m_pos[0];
396
178k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
178k
                }
398
252k
            }
399
12.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
12.5k
            {
420
308k
copy_match:
421
308k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
9.22M
                do *op++ = *m_pos++; while (--t > 0);
423
308k
            }
424
425
265k
#endif /* COPY_DICT */
426
427
901k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
901k
            t = ip[-2] & 3;
432
901k
#endif
433
901k
            if (t == 0)
434
298k
                break;
435
436
            /* copy literals */
437
603k
match_next:
438
603k
            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
603k
            *op++ = *ip++;
443
603k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
603k
#endif
445
603k
            t = *ip++;
446
603k
        }
447
0
    }
448
449
1.86k
eof_found:
450
1.86k
    *out_len = pd(op, out);
451
1.86k
    return (ip == ip_end ? LZO_E_OK :
452
1.86k
           (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
478
}
lzo1z_decompress
Line
Count
Source
42
1.68k
{
43
1.68k
    lzo_bytep op;
44
1.68k
    const lzo_bytep ip;
45
1.68k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
1.68k
    const lzo_bytep m_pos;
51
1.68k
#endif
52
53
1.68k
    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.68k
#if defined(LZO1Z)
58
1.68k
    lzo_uint last_m_off = 0;
59
1.68k
#endif
60
61
1.68k
    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.68k
    *out_len = 0;
81
82
1.68k
    op = out;
83
1.68k
    ip = in;
84
85
1.68k
    NEED_IP(1);
86
1.68k
    if (*ip > 17)
87
1.64k
    {
88
1.64k
        t = *ip++ - 17;
89
1.64k
        if (t < 4)
90
732
            goto match_next;
91
1.64k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
18.5k
        do *op++ = *ip++; while (--t > 0);
93
910
        goto first_literal_run;
94
1.64k
    }
95
96
45
    for (;;)
97
294k
    {
98
294k
        NEED_IP(3);
99
294k
        t = *ip++;
100
294k
        if (t >= 16)
101
227k
            goto match;
102
        /* a literal run */
103
66.2k
        if (t == 0)
104
24.0k
        {
105
53.2k
            while (*ip == 0)
106
29.2k
            {
107
29.2k
                t += 255;
108
29.2k
                ip++;
109
29.2k
                TEST_IV(t);
110
29.2k
                NEED_IP(1);
111
29.2k
            }
112
24.0k
            t += 15 + *ip++;
113
24.0k
        }
114
        /* copy literals */
115
66.2k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
66.2k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
66.2k
        t += 3;
118
66.2k
        if (t >= 8) do
119
1.16M
        {
120
1.16M
            UA_COPY8(op,ip);
121
1.16M
            op += 8; ip += 8; t -= 8;
122
1.16M
        } while (t >= 8);
123
66.2k
        if (t >= 4)
124
41.5k
        {
125
41.5k
            UA_COPY4(op,ip);
126
41.5k
            op += 4; ip += 4; t -= 4;
127
41.5k
        }
128
66.2k
        if (t > 0)
129
46.2k
        {
130
46.2k
            *op++ = *ip++;
131
46.2k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
46.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
67.1k
first_literal_run:
167
168
169
67.1k
        t = *ip++;
170
67.1k
        if (t >= 16)
171
61.8k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
5.29k
#if defined(LZO1Z)
183
5.29k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
5.29k
        m_pos = op - t;
185
5.29k
        last_m_off = t;
186
#else
187
        m_pos = op - (1 + M2_MAX_OFFSET);
188
        m_pos -= t >> 2;
189
        m_pos -= *ip++ << 2;
190
#endif
191
5.29k
        TEST_LB(m_pos); NEED_OP(3);
192
5.29k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
5.29k
#endif /* COPY_DICT */
194
5.29k
        goto match_done;
195
196
197
        /* handle matches */
198
745k
        for (;;) {
199
1.03M
match:
200
1.03M
            if (t >= 64)                /* a M2 match */
201
317k
            {
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
317k
                    lzo_uint off = t & 0x1f;
234
317k
                    m_pos = op;
235
317k
                    if (off >= 0x1c)
236
12.2k
                    {
237
12.2k
                        assert(last_m_off > 0);
238
12.2k
                        m_pos -= last_m_off;
239
12.2k
                    }
240
305k
                    else
241
305k
                    {
242
305k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
305k
                        m_pos -= off;
244
305k
                        last_m_off = off;
245
305k
                    }
246
317k
                }
247
317k
                t = (t >> 5) - 1;
248
317k
#endif
249
317k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
317k
                goto copy_match;
251
317k
#endif /* COPY_DICT */
252
317k
            }
253
717k
            else if (t >= 32)           /* a M3 match */
254
241k
            {
255
241k
                t &= 31;
256
241k
                if (t == 0)
257
39.9k
                {
258
83.3k
                    while (*ip == 0)
259
43.3k
                    {
260
43.3k
                        t += 255;
261
43.3k
                        ip++;
262
43.3k
                        TEST_OV(t);
263
43.3k
                        NEED_IP(1);
264
43.3k
                    }
265
39.9k
                    t += 31 + *ip++;
266
39.9k
                    NEED_IP(2);
267
39.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
241k
#if defined(LZO1Z)
277
241k
                {
278
241k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
241k
                    m_pos = op - off;
280
241k
                    last_m_off = off;
281
241k
                }
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
241k
#endif /* COPY_DICT */
290
241k
                ip += 2;
291
241k
            }
292
476k
            else if (t >= 16)           /* a M4 match */
293
52.4k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
52.4k
                m_pos = op;
298
52.4k
                m_pos -= (t & 8) << 11;
299
52.4k
#endif /* COPY_DICT */
300
52.4k
                t &= 7;
301
52.4k
                if (t == 0)
302
18.6k
                {
303
27.0k
                    while (*ip == 0)
304
8.35k
                    {
305
8.35k
                        t += 255;
306
8.35k
                        ip++;
307
8.35k
                        TEST_OV(t);
308
8.35k
                        NEED_IP(1);
309
8.35k
                    }
310
18.6k
                    t += 7 + *ip++;
311
18.6k
                    NEED_IP(2);
312
18.6k
                }
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
52.4k
#if defined(LZO1Z)
328
52.4k
                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
52.4k
                ip += 2;
335
52.4k
                if (m_pos == op)
336
1.68k
                    goto eof_found;
337
50.7k
                m_pos -= 0x4000;
338
50.7k
#if defined(LZO1Z)
339
50.7k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
50.7k
#endif
341
50.7k
#endif /* COPY_DICT */
342
50.7k
            }
343
423k
            else                            /* a M1 match */
344
423k
            {
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
423k
#if defined(LZO1Z)
356
423k
                t = 1 + (t << 6) + (*ip++ >> 2);
357
423k
                m_pos = op - t;
358
423k
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
423k
                TEST_LB(m_pos); NEED_OP(2);
365
423k
                *op++ = *m_pos++; *op++ = *m_pos;
366
423k
#endif /* COPY_DICT */
367
423k
                goto match_done;
368
423k
            }
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
292k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
292k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
292k
            if (op - m_pos >= 8)
381
274k
            {
382
274k
                t += (3 - 1);
383
274k
                if (t >= 8) do
384
1.43M
                {
385
1.43M
                    UA_COPY8(op,m_pos);
386
1.43M
                    op += 8; m_pos += 8; t -= 8;
387
1.43M
                } while (t >= 8);
388
274k
                if (t >= 4)
389
106k
                {
390
106k
                    UA_COPY4(op,m_pos);
391
106k
                    op += 4; m_pos += 4; t -= 4;
392
106k
                }
393
274k
                if (t > 0)
394
217k
                {
395
217k
                    *op++ = m_pos[0];
396
217k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
217k
                }
398
274k
            }
399
17.4k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
17.4k
            {
420
335k
copy_match:
421
335k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
9.13M
                do *op++ = *m_pos++; while (--t > 0);
423
335k
            }
424
425
292k
#endif /* COPY_DICT */
426
427
1.03M
match_done:
428
1.03M
#if defined(LZO1Z)
429
1.03M
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
1.03M
            if (t == 0)
434
294k
                break;
435
436
            /* copy literals */
437
745k
match_next:
438
745k
            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
745k
            *op++ = *ip++;
443
745k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
745k
#endif
445
745k
            t = *ip++;
446
745k
        }
447
0
    }
448
449
1.68k
eof_found:
450
1.68k
    *out_len = pd(op, out);
451
1.68k
    return (ip == ip_end ? LZO_E_OK :
452
1.68k
           (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
45
}
lzo1x_decompress_safe
Line
Count
Source
42
615
{
43
615
    lzo_bytep op;
44
615
    const lzo_bytep ip;
45
615
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
615
    const lzo_bytep m_pos;
51
615
#endif
52
53
615
    const lzo_bytep const ip_end = in + in_len;
54
615
#if defined(HAVE_ANY_OP)
55
615
    lzo_bytep const op_end = out + *out_len;
56
615
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
615
    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
615
    *out_len = 0;
81
82
615
    op = out;
83
615
    ip = in;
84
85
615
    NEED_IP(1);
86
615
    if (*ip > 17)
87
379
    {
88
379
        t = *ip++ - 17;
89
379
        if (t < 4)
90
274
            goto match_next;
91
379
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
1.66k
        do *op++ = *ip++; while (--t > 0);
93
90
        goto first_literal_run;
94
105
    }
95
96
236
    for (;;)
97
43.0k
    {
98
43.0k
        NEED_IP(3);
99
42.9k
        t = *ip++;
100
42.9k
        if (t >= 16)
101
26.4k
            goto match;
102
        /* a literal run */
103
16.4k
        if (t == 0)
104
9.99k
        {
105
3.80M
            while (*ip == 0)
106
3.79M
            {
107
3.79M
                t += 255;
108
3.79M
                ip++;
109
3.79M
                TEST_IV(t);
110
3.79M
                NEED_IP(1);
111
3.79M
            }
112
9.97k
            t += 15 + *ip++;
113
9.97k
        }
114
        /* copy literals */
115
16.4k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
16.3k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
16.3k
        t += 3;
118
16.3k
        if (t >= 8) do
119
385k
        {
120
385k
            UA_COPY8(op,ip);
121
385k
            op += 8; ip += 8; t -= 8;
122
385k
        } while (t >= 8);
123
16.3k
        if (t >= 4)
124
8.19k
        {
125
8.19k
            UA_COPY4(op,ip);
126
8.19k
            op += 4; ip += 4; t -= 4;
127
8.19k
        }
128
16.3k
        if (t > 0)
129
12.9k
        {
130
12.9k
            *op++ = *ip++;
131
12.9k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
12.9k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
16.3k
first_literal_run:
167
168
169
16.3k
        t = *ip++;
170
16.3k
        if (t >= 16)
171
6.15k
            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
10.2k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
10.2k
        m_pos -= t >> 2;
189
10.2k
        m_pos -= *ip++ << 2;
190
10.2k
#endif
191
10.2k
        TEST_LB(m_pos); NEED_OP(3);
192
10.1k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
10.1k
#endif /* COPY_DICT */
194
10.1k
        goto match_done;
195
196
197
        /* handle matches */
198
88.9k
        for (;;) {
199
121k
match:
200
121k
            if (t >= 64)                /* a M2 match */
201
41.4k
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
41.4k
#if defined(LZO1X)
222
41.4k
                m_pos = op - 1;
223
41.4k
                m_pos -= (t >> 2) & 7;
224
41.4k
                m_pos -= *ip++ << 3;
225
41.4k
                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
41.4k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
41.4k
                goto copy_match;
251
41.4k
#endif /* COPY_DICT */
252
41.4k
            }
253
80.0k
            else if (t >= 32)           /* a M3 match */
254
32.2k
            {
255
32.2k
                t &= 31;
256
32.2k
                if (t == 0)
257
2.81k
                {
258
1.23M
                    while (*ip == 0)
259
1.23M
                    {
260
1.23M
                        t += 255;
261
1.23M
                        ip++;
262
1.23M
                        TEST_OV(t);
263
1.23M
                        NEED_IP(1);
264
1.23M
                    }
265
2.79k
                    t += 31 + *ip++;
266
2.79k
                    NEED_IP(2);
267
2.79k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
                {
278
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
                    m_pos = op - off;
280
                    last_m_off = off;
281
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
32.1k
                m_pos = op - 1;
284
32.1k
                m_pos -= UA_GET_LE16(ip) >> 2;
285
#else
286
                m_pos = op - 1;
287
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
288
#endif
289
32.1k
#endif /* COPY_DICT */
290
32.1k
                ip += 2;
291
32.1k
            }
292
47.8k
            else if (t >= 16)           /* a M4 match */
293
9.02k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
9.02k
                m_pos = op;
298
9.02k
                m_pos -= (t & 8) << 11;
299
9.02k
#endif /* COPY_DICT */
300
9.02k
                t &= 7;
301
9.02k
                if (t == 0)
302
2.85k
                {
303
1.84M
                    while (*ip == 0)
304
1.83M
                    {
305
1.83M
                        t += 255;
306
1.83M
                        ip++;
307
1.83M
                        TEST_OV(t);
308
1.83M
                        NEED_IP(1);
309
1.83M
                    }
310
2.83k
                    t += 7 + *ip++;
311
2.83k
                    NEED_IP(2);
312
2.83k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
8.99k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
8.99k
                ip += 2;
335
8.99k
                if (m_pos == op)
336
14
                    goto eof_found;
337
8.98k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
8.98k
#endif /* COPY_DICT */
342
8.98k
            }
343
38.8k
            else                            /* a M1 match */
344
38.8k
            {
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
38.8k
                m_pos = op - 1;
361
38.8k
                m_pos -= t >> 2;
362
38.8k
                m_pos -= *ip++ << 2;
363
38.8k
#endif
364
38.8k
                TEST_LB(m_pos); NEED_OP(2);
365
38.8k
                *op++ = *m_pos++; *op++ = *m_pos;
366
38.8k
#endif /* COPY_DICT */
367
38.8k
                goto match_done;
368
38.8k
            }
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
41.1k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
41.0k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
41.0k
            if (op - m_pos >= 8)
381
38.1k
            {
382
38.1k
                t += (3 - 1);
383
38.1k
                if (t >= 8) do
384
699k
                {
385
699k
                    UA_COPY8(op,m_pos);
386
699k
                    op += 8; m_pos += 8; t -= 8;
387
699k
                } while (t >= 8);
388
38.1k
                if (t >= 4)
389
22.9k
                {
390
22.9k
                    UA_COPY4(op,m_pos);
391
22.9k
                    op += 4; m_pos += 4; t -= 4;
392
22.9k
                }
393
38.1k
                if (t > 0)
394
28.5k
                {
395
28.5k
                    *op++ = m_pos[0];
396
28.5k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
28.5k
                }
398
38.1k
            }
399
2.89k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
2.89k
            {
420
44.3k
copy_match:
421
44.3k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
10.6M
                do *op++ = *m_pos++; while (--t > 0);
423
44.3k
            }
424
425
41.0k
#endif /* COPY_DICT */
426
427
131k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
131k
            t = ip[-2] & 3;
432
131k
#endif
433
131k
            if (t == 0)
434
42.7k
                break;
435
436
            /* copy literals */
437
89.0k
match_next:
438
89.0k
            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
88.9k
            *op++ = *ip++;
443
88.9k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
88.9k
#endif
445
88.9k
            t = *ip++;
446
88.9k
        }
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
385
input_overrun:
457
385
    *out_len = pd(op, out);
458
385
    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
155
lookbehind_overrun:
469
155
    *out_len = pd(op, out);
470
155
    return LZO_E_LOOKBEHIND_OVERRUN;
471
236
#endif
472
236
}
lzo1y_decompress_safe
Line
Count
Source
42
627
{
43
627
    lzo_bytep op;
44
627
    const lzo_bytep ip;
45
627
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
627
    const lzo_bytep m_pos;
51
627
#endif
52
53
627
    const lzo_bytep const ip_end = in + in_len;
54
627
#if defined(HAVE_ANY_OP)
55
627
    lzo_bytep const op_end = out + *out_len;
56
627
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
627
    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
627
    *out_len = 0;
81
82
627
    op = out;
83
627
    ip = in;
84
85
627
    NEED_IP(1);
86
627
    if (*ip > 17)
87
365
    {
88
365
        t = *ip++ - 17;
89
365
        if (t < 4)
90
249
            goto match_next;
91
365
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
2.18k
        do *op++ = *ip++; while (--t > 0);
93
105
        goto first_literal_run;
94
116
    }
95
96
262
    for (;;)
97
78.5k
    {
98
78.5k
        NEED_IP(3);
99
78.5k
        t = *ip++;
100
78.5k
        if (t >= 16)
101
58.6k
            goto match;
102
        /* a literal run */
103
19.8k
        if (t == 0)
104
11.4k
        {
105
19.1M
            while (*ip == 0)
106
19.0M
            {
107
19.0M
                t += 255;
108
19.0M
                ip++;
109
19.0M
                TEST_IV(t);
110
19.0M
                NEED_IP(1);
111
19.0M
            }
112
11.4k
            t += 15 + *ip++;
113
11.4k
        }
114
        /* copy literals */
115
19.8k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
19.7k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
19.7k
        t += 3;
118
19.7k
        if (t >= 8) do
119
633k
        {
120
633k
            UA_COPY8(op,ip);
121
633k
            op += 8; ip += 8; t -= 8;
122
633k
        } while (t >= 8);
123
19.7k
        if (t >= 4)
124
11.1k
        {
125
11.1k
            UA_COPY4(op,ip);
126
11.1k
            op += 4; ip += 4; t -= 4;
127
11.1k
        }
128
19.7k
        if (t > 0)
129
15.4k
        {
130
15.4k
            *op++ = *ip++;
131
15.4k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
15.4k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
19.8k
first_literal_run:
167
168
169
19.8k
        t = *ip++;
170
19.8k
        if (t >= 16)
171
8.72k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
11.0k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
11.0k
        m_pos -= t >> 2;
189
11.0k
        m_pos -= *ip++ << 2;
190
11.0k
#endif
191
11.0k
        TEST_LB(m_pos); NEED_OP(3);
192
11.0k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
11.0k
#endif /* COPY_DICT */
194
11.0k
        goto match_done;
195
196
197
        /* handle matches */
198
102k
        for (;;) {
199
169k
match:
200
169k
            if (t >= 64)                /* a M2 match */
201
83.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
83.2k
                m_pos -= (t >> 2) & 3;
229
83.2k
                m_pos -= *ip++ << 2;
230
83.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
83.2k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
83.2k
                goto copy_match;
251
83.2k
#endif /* COPY_DICT */
252
83.2k
            }
253
86.5k
            else if (t >= 32)           /* a M3 match */
254
27.9k
            {
255
27.9k
                t &= 31;
256
27.9k
                if (t == 0)
257
2.98k
                {
258
18.0M
                    while (*ip == 0)
259
18.0M
                    {
260
18.0M
                        t += 255;
261
18.0M
                        ip++;
262
18.0M
                        TEST_OV(t);
263
18.0M
                        NEED_IP(1);
264
18.0M
                    }
265
2.95k
                    t += 31 + *ip++;
266
2.95k
                    NEED_IP(2);
267
2.95k
                }
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
27.9k
                m_pos = op - 1;
284
27.9k
                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
27.9k
#endif /* COPY_DICT */
290
27.9k
                ip += 2;
291
27.9k
            }
292
58.6k
            else if (t >= 16)           /* a M4 match */
293
8.64k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
8.64k
                m_pos = op;
298
8.64k
                m_pos -= (t & 8) << 11;
299
8.64k
#endif /* COPY_DICT */
300
8.64k
                t &= 7;
301
8.64k
                if (t == 0)
302
2.44k
                {
303
6.03M
                    while (*ip == 0)
304
6.03M
                    {
305
6.03M
                        t += 255;
306
6.03M
                        ip++;
307
6.03M
                        TEST_OV(t);
308
6.03M
                        NEED_IP(1);
309
6.03M
                    }
310
2.42k
                    t += 7 + *ip++;
311
2.42k
                    NEED_IP(2);
312
2.42k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
8.61k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
8.61k
                ip += 2;
335
8.61k
                if (m_pos == op)
336
10
                    goto eof_found;
337
8.60k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
8.60k
#endif /* COPY_DICT */
342
8.60k
            }
343
49.9k
            else                            /* a M1 match */
344
49.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
49.9k
                m_pos = op - 1;
361
49.9k
                m_pos -= t >> 2;
362
49.9k
                m_pos -= *ip++ << 2;
363
49.9k
#endif
364
49.9k
                TEST_LB(m_pos); NEED_OP(2);
365
49.9k
                *op++ = *m_pos++; *op++ = *m_pos;
366
49.9k
#endif /* COPY_DICT */
367
49.9k
                goto match_done;
368
49.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
36.5k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
36.4k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
36.4k
            if (op - m_pos >= 8)
381
33.0k
            {
382
33.0k
                t += (3 - 1);
383
33.0k
                if (t >= 8) do
384
425k
                {
385
425k
                    UA_COPY8(op,m_pos);
386
425k
                    op += 8; m_pos += 8; t -= 8;
387
425k
                } while (t >= 8);
388
33.0k
                if (t >= 4)
389
18.8k
                {
390
18.8k
                    UA_COPY4(op,m_pos);
391
18.8k
                    op += 4; m_pos += 4; t -= 4;
392
18.8k
                }
393
33.0k
                if (t > 0)
394
25.2k
                {
395
25.2k
                    *op++ = m_pos[0];
396
25.2k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
25.2k
                }
398
33.0k
            }
399
3.37k
            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.37k
            {
420
86.5k
copy_match:
421
86.5k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
10.9M
                do *op++ = *m_pos++; while (--t > 0);
423
86.5k
            }
424
425
36.4k
#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
78.3k
                break;
435
436
            /* copy literals */
437
102k
match_next:
438
102k
            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
102k
            *op++ = *ip++;
443
102k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
102k
#endif
445
102k
            t = *ip++;
446
102k
        }
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
372
input_overrun:
457
372
    *out_len = pd(op, out);
458
372
    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
184
lookbehind_overrun:
469
184
    *out_len = pd(op, out);
470
184
    return LZO_E_LOOKBEHIND_OVERRUN;
471
262
#endif
472
262
}
lzo1z_decompress_safe
Line
Count
Source
42
606
{
43
606
    lzo_bytep op;
44
606
    const lzo_bytep ip;
45
606
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
606
    const lzo_bytep m_pos;
51
606
#endif
52
53
606
    const lzo_bytep const ip_end = in + in_len;
54
606
#if defined(HAVE_ANY_OP)
55
606
    lzo_bytep const op_end = out + *out_len;
56
606
#endif
57
606
#if defined(LZO1Z)
58
606
    lzo_uint last_m_off = 0;
59
606
#endif
60
61
606
    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
606
    *out_len = 0;
81
82
606
    op = out;
83
606
    ip = in;
84
85
606
    NEED_IP(1);
86
606
    if (*ip > 17)
87
411
    {
88
411
        t = *ip++ - 17;
89
411
        if (t < 4)
90
298
            goto match_next;
91
411
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
1.54k
        do *op++ = *ip++; while (--t > 0);
93
99
        goto first_literal_run;
94
113
    }
95
96
195
    for (;;)
97
50.0k
    {
98
50.0k
        NEED_IP(3);
99
49.9k
        t = *ip++;
100
49.9k
        if (t >= 16)
101
33.0k
            goto match;
102
        /* a literal run */
103
16.9k
        if (t == 0)
104
7.22k
        {
105
3.00M
            while (*ip == 0)
106
3.00M
            {
107
3.00M
                t += 255;
108
3.00M
                ip++;
109
3.00M
                TEST_IV(t);
110
3.00M
                NEED_IP(1);
111
3.00M
            }
112
7.20k
            t += 15 + *ip++;
113
7.20k
        }
114
        /* copy literals */
115
16.9k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
16.7k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
16.7k
        t += 3;
118
16.7k
        if (t >= 8) do
119
427k
        {
120
427k
            UA_COPY8(op,ip);
121
427k
            op += 8; ip += 8; t -= 8;
122
427k
        } while (t >= 8);
123
16.7k
        if (t >= 4)
124
9.01k
        {
125
9.01k
            UA_COPY4(op,ip);
126
9.01k
            op += 4; ip += 4; t -= 4;
127
9.01k
        }
128
16.7k
        if (t > 0)
129
10.7k
        {
130
10.7k
            *op++ = *ip++;
131
10.7k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
10.7k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
16.8k
first_literal_run:
167
168
169
16.8k
        t = *ip++;
170
16.8k
        if (t >= 16)
171
8.42k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
8.43k
#if defined(LZO1Z)
183
8.43k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
8.43k
        m_pos = op - t;
185
8.43k
        last_m_off = t;
186
#else
187
        m_pos = op - (1 + M2_MAX_OFFSET);
188
        m_pos -= t >> 2;
189
        m_pos -= *ip++ << 2;
190
#endif
191
8.43k
        TEST_LB(m_pos); NEED_OP(3);
192
8.41k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
8.41k
#endif /* COPY_DICT */
194
8.41k
        goto match_done;
195
196
197
        /* handle matches */
198
93.1k
        for (;;) {
199
134k
match:
200
134k
            if (t >= 64)                /* a M2 match */
201
79.1k
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
#if defined(LZO1X)
222
                m_pos = op - 1;
223
                m_pos -= (t >> 2) & 7;
224
                m_pos -= *ip++ << 3;
225
                t = (t >> 5) - 1;
226
#elif defined(LZO1Y)
227
                m_pos = op - 1;
228
                m_pos -= (t >> 2) & 3;
229
                m_pos -= *ip++ << 2;
230
                t = (t >> 4) - 3;
231
#elif defined(LZO1Z)
232
                {
233
79.1k
                    lzo_uint off = t & 0x1f;
234
79.1k
                    m_pos = op;
235
79.1k
                    if (off >= 0x1c)
236
18.4k
                    {
237
18.4k
                        assert(last_m_off > 0);
238
18.4k
                        m_pos -= last_m_off;
239
18.4k
                    }
240
60.6k
                    else
241
60.6k
                    {
242
60.6k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
60.6k
                        m_pos -= off;
244
60.6k
                        last_m_off = off;
245
60.6k
                    }
246
79.1k
                }
247
79.1k
                t = (t >> 5) - 1;
248
79.1k
#endif
249
79.1k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
79.1k
                goto copy_match;
251
79.1k
#endif /* COPY_DICT */
252
79.1k
            }
253
55.4k
            else if (t >= 32)           /* a M3 match */
254
19.2k
            {
255
19.2k
                t &= 31;
256
19.2k
                if (t == 0)
257
2.84k
                {
258
1.63M
                    while (*ip == 0)
259
1.63M
                    {
260
1.63M
                        t += 255;
261
1.63M
                        ip++;
262
1.63M
                        TEST_OV(t);
263
1.63M
                        NEED_IP(1);
264
1.63M
                    }
265
2.82k
                    t += 31 + *ip++;
266
2.82k
                    NEED_IP(2);
267
2.82k
                }
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
19.2k
#if defined(LZO1Z)
277
19.2k
                {
278
19.2k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
19.2k
                    m_pos = op - off;
280
19.2k
                    last_m_off = off;
281
19.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
19.2k
#endif /* COPY_DICT */
290
19.2k
                ip += 2;
291
19.2k
            }
292
36.2k
            else if (t >= 16)           /* a M4 match */
293
6.76k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
6.76k
                m_pos = op;
298
6.76k
                m_pos -= (t & 8) << 11;
299
6.76k
#endif /* COPY_DICT */
300
6.76k
                t &= 7;
301
6.76k
                if (t == 0)
302
2.29k
                {
303
4.58k
                    while (*ip == 0)
304
2.29k
                    {
305
2.29k
                        t += 255;
306
2.29k
                        ip++;
307
2.29k
                        TEST_OV(t);
308
2.29k
                        NEED_IP(1);
309
2.29k
                    }
310
2.29k
                    t += 7 + *ip++;
311
2.29k
                    NEED_IP(2);
312
2.29k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
6.75k
#if defined(LZO1Z)
328
6.75k
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
6.75k
                ip += 2;
335
6.75k
                if (m_pos == op)
336
15
                    goto eof_found;
337
6.73k
                m_pos -= 0x4000;
338
6.73k
#if defined(LZO1Z)
339
6.73k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
6.73k
#endif
341
6.73k
#endif /* COPY_DICT */
342
6.73k
            }
343
29.4k
            else                            /* a M1 match */
344
29.4k
            {
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
29.4k
#if defined(LZO1Z)
356
29.4k
                t = 1 + (t << 6) + (*ip++ >> 2);
357
29.4k
                m_pos = op - t;
358
29.4k
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
29.4k
                TEST_LB(m_pos); NEED_OP(2);
365
29.4k
                *op++ = *m_pos++; *op++ = *m_pos;
366
29.4k
#endif /* COPY_DICT */
367
29.4k
                goto match_done;
368
29.4k
            }
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
25.9k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
25.8k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
25.8k
            if (op - m_pos >= 8)
381
23.9k
            {
382
23.9k
                t += (3 - 1);
383
23.9k
                if (t >= 8) do
384
950k
                {
385
950k
                    UA_COPY8(op,m_pos);
386
950k
                    op += 8; m_pos += 8; t -= 8;
387
950k
                } while (t >= 8);
388
23.9k
                if (t >= 4)
389
11.3k
                {
390
11.3k
                    UA_COPY4(op,m_pos);
391
11.3k
                    op += 4; m_pos += 4; t -= 4;
392
11.3k
                }
393
23.9k
                if (t > 0)
394
19.0k
                {
395
19.0k
                    *op++ = m_pos[0];
396
19.0k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
19.0k
                }
398
23.9k
            }
399
1.92k
            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
1.92k
            {
420
81.0k
copy_match:
421
81.0k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
6.89M
                do *op++ = *m_pos++; while (--t > 0);
423
81.0k
            }
424
425
25.8k
#endif /* COPY_DICT */
426
427
142k
match_done:
428
142k
#if defined(LZO1Z)
429
142k
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
142k
            if (t == 0)
434
49.8k
                break;
435
436
            /* copy literals */
437
93.2k
match_next:
438
93.2k
            assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
439
#if 0
440
            do *op++ = *ip++; while (--t > 0);
441
#else
442
93.1k
            *op++ = *ip++;
443
93.1k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
93.1k
#endif
445
93.1k
            t = *ip++;
446
93.1k
        }
447
0
    }
448
449
15
eof_found:
450
15
    *out_len = pd(op, out);
451
15
    return (ip == ip_end ? LZO_E_OK :
452
15
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
387
input_overrun:
457
387
    *out_len = pd(op, out);
458
387
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
57
output_overrun:
463
57
    *out_len = pd(op, out);
464
57
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
147
lookbehind_overrun:
469
147
    *out_len = pd(op, out);
470
147
    return LZO_E_LOOKBEHIND_OVERRUN;
471
195
#endif
472
195
}
473
474
475
/* vim:set ts=4 sw=4 et: */