Coverage Report

Created: 2026-01-17 06:09

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.03k
{
43
9.03k
    lzo_bytep op;
44
9.03k
    const lzo_bytep ip;
45
9.03k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
9.03k
    const lzo_bytep m_pos;
51
9.03k
#endif
52
53
9.03k
    const lzo_bytep const ip_end = in + in_len;
54
#if defined(HAVE_ANY_OP)
55
1.76k
    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.03k
    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.03k
    *out_len = 0;
81
82
9.03k
    op = out;
83
9.03k
    ip = in;
84
85
9.03k
    NEED_IP(1);
86
9.03k
    if (*ip > 17)
87
5.46k
    {
88
5.46k
        t = *ip++ - 17;
89
5.46k
        if (t < 4)
90
2.71k
            goto match_next;
91
5.46k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
50.7k
        do *op++ = *ip++; while (--t > 0);
93
319
        goto first_literal_run;
94
357
    }
95
96
3.57k
    for (;;)
97
1.81M
    {
98
1.81M
        NEED_IP(3);
99
206k
        t = *ip++;
100
1.81M
        if (t >= 16)
101
1.40M
            goto match;
102
        /* a literal run */
103
413k
        if (t == 0)
104
131k
        {
105
22.9M
            while (*ip == 0)
106
22.8M
            {
107
22.8M
                t += 255;
108
22.8M
                ip++;
109
22.8M
                TEST_IV(t);
110
22.8M
                NEED_IP(1);
111
22.1M
            }
112
21.6k
            t += 15 + *ip++;
113
21.6k
        }
114
        /* copy literals */
115
413k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
47.2k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
47.2k
        t += 3;
118
413k
        if (t >= 8) do
119
23.5M
        {
120
23.5M
            UA_COPY8(op,ip);
121
23.5M
            op += 8; ip += 8; t -= 8;
122
23.5M
        } while (t >= 8);
123
413k
        if (t >= 4)
124
265k
        {
125
265k
            UA_COPY4(op,ip);
126
265k
            op += 4; ip += 4; t -= 4;
127
265k
        }
128
413k
        if (t > 0)
129
270k
        {
130
270k
            *op++ = *ip++;
131
270k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
270k
        }
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
415k
first_literal_run:
167
168
169
415k
        t = *ip++;
170
415k
        if (t >= 16)
171
378k
            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
14.1k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
4.55k
        m_pos = op - t;
185
4.55k
        last_m_off = t;
186
#else
187
22.7k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
        m_pos -= t >> 2;
189
        m_pos -= *ip++ << 2;
190
#endif
191
36.9k
        TEST_LB(m_pos); NEED_OP(3);
192
23.8k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
23.8k
#endif /* COPY_DICT */
194
23.8k
        goto match_done;
195
196
197
        /* handle matches */
198
2.00M
        for (;;) {
199
3.78M
match:
200
3.78M
            if (t >= 64)                /* a M2 match */
201
1.65M
            {
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
34.1k
                    {
237
34.1k
                        assert(last_m_off > 0);
238
34.1k
                        m_pos -= last_m_off;
239
34.1k
                    }
240
362k
                    else
241
362k
                    {
242
362k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
362k
                        m_pos -= off;
244
362k
                        last_m_off = off;
245
362k
                    }
246
                }
247
                t = (t >> 5) - 1;
248
#endif
249
1.65M
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
254k
                goto copy_match;
251
254k
#endif /* COPY_DICT */
252
254k
            }
253
2.12M
            else if (t >= 32)           /* a M3 match */
254
1.18M
            {
255
1.18M
                t &= 31;
256
1.18M
                if (t == 0)
257
231k
                {
258
15.1M
                    while (*ip == 0)
259
14.9M
                    {
260
14.9M
                        t += 255;
261
14.9M
                        ip++;
262
14.9M
                        TEST_OV(t);
263
14.9M
                        NEED_IP(1);
264
14.7M
                    }
265
10.4k
                    t += 31 + *ip++;
266
231k
                    NEED_IP(2);
267
10.4k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
31.6k
                {
278
31.6k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
31.6k
                    m_pos = op - off;
280
31.6k
                    last_m_off = off;
281
31.6k
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
68.7k
                m_pos = op - 1;
284
875k
                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
68.7k
#endif /* COPY_DICT */
290
68.7k
                ip += 2;
291
68.7k
            }
292
943k
            else if (t >= 16)           /* a M4 match */
293
269k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
269k
                m_pos = op;
298
269k
                m_pos -= (t & 8) << 11;
299
269k
#endif /* COPY_DICT */
300
269k
                t &= 7;
301
269k
                if (t == 0)
302
105k
                {
303
6.97M
                    while (*ip == 0)
304
6.87M
                    {
305
6.87M
                        t += 255;
306
6.87M
                        ip++;
307
6.87M
                        TEST_OV(t);
308
6.87M
                        NEED_IP(1);
309
6.82M
                    }
310
8.14k
                    t += 7 + *ip++;
311
105k
                    NEED_IP(2);
312
8.14k
                }
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
8.87k
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
188k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
20.1k
                ip += 2;
335
269k
                if (m_pos == op)
336
7.30k
                    goto eof_found;
337
261k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
78.7k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
261k
#endif /* COPY_DICT */
342
261k
            }
343
673k
            else                            /* a M1 match */
344
673k
            {
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
673k
                TEST_LB(m_pos); NEED_OP(2);
365
98.4k
                *op++ = *m_pos++; *op++ = *m_pos;
366
98.4k
#endif /* COPY_DICT */
367
98.4k
                goto match_done;
368
98.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
1.44M
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
129k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
1.44M
            if (op - m_pos >= 8)
381
1.35M
            {
382
1.35M
                t += (3 - 1);
383
1.35M
                if (t >= 8) do
384
10.5M
                {
385
10.5M
                    UA_COPY8(op,m_pos);
386
10.5M
                    op += 8; m_pos += 8; t -= 8;
387
10.5M
                } while (t >= 8);
388
1.35M
                if (t >= 4)
389
674k
                {
390
674k
                    UA_COPY4(op,m_pos);
391
674k
                    op += 4; m_pos += 4; t -= 4;
392
674k
                }
393
1.35M
                if (t > 0)
394
986k
                {
395
986k
                    *op++ = m_pos[0];
396
986k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
986k
                }
398
1.35M
            }
399
90.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
90.4k
            {
420
1.74M
copy_match:
421
1.74M
                *op++ = *m_pos++; *op++ = *m_pos++;
422
62.3M
                do *op++ = *m_pos++; while (--t > 0);
423
1.74M
            }
424
425
129k
#endif /* COPY_DICT */
426
427
3.81M
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
3.81M
            if (t == 0)
434
1.81M
                break;
435
436
            /* copy literals */
437
2.00M
match_next:
438
2.00M
            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
300k
            *op++ = *ip++;
443
2.00M
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
300k
#endif
445
300k
            t = *ip++;
446
300k
        }
447
0
    }
448
449
7.30k
eof_found:
450
7.30k
    *out_len = pd(op, out);
451
7.30k
    return (ip == ip_end ? LZO_E_OK :
452
7.30k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
#if defined(HAVE_NEED_IP)
456
1.08k
input_overrun:
457
1.08k
    *out_len = pd(op, out);
458
1.08k
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
#if defined(HAVE_NEED_OP)
462
177
output_overrun:
463
177
    *out_len = pd(op, out);
464
177
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
460
lookbehind_overrun:
469
460
    *out_len = pd(op, out);
470
460
    return LZO_E_LOOKBEHIND_OVERRUN;
471
#endif
472
3.57k
}
lzo1x_decompress
Line
Count
Source
42
3.77k
{
43
3.77k
    lzo_bytep op;
44
3.77k
    const lzo_bytep ip;
45
3.77k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
3.77k
    const lzo_bytep m_pos;
51
3.77k
#endif
52
53
3.77k
    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.77k
    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.77k
    *out_len = 0;
81
82
3.77k
    op = out;
83
3.77k
    ip = in;
84
85
3.77k
    NEED_IP(1);
86
3.77k
    if (*ip > 17)
87
1.42k
    {
88
1.42k
        t = *ip++ - 17;
89
1.42k
        if (t < 4)
90
652
            goto match_next;
91
1.42k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
17.9k
        do *op++ = *ip++; while (--t > 0);
93
768
        goto first_literal_run;
94
1.42k
    }
95
96
2.35k
    for (;;)
97
848k
    {
98
848k
        NEED_IP(3);
99
848k
        t = *ip++;
100
848k
        if (t >= 16)
101
637k
            goto match;
102
        /* a literal run */
103
210k
        if (t == 0)
104
57.4k
        {
105
545k
            while (*ip == 0)
106
488k
            {
107
488k
                t += 255;
108
488k
                ip++;
109
488k
                TEST_IV(t);
110
488k
                NEED_IP(1);
111
488k
            }
112
57.4k
            t += 15 + *ip++;
113
57.4k
        }
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.1M
        {
120
16.1M
            UA_COPY8(op,ip);
121
16.1M
            op += 8; ip += 8; t -= 8;
122
16.1M
        } 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
134k
        {
130
134k
            *op++ = *ip++;
131
134k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
134k
        }
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
209k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
2.65k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
2.65k
        m_pos -= t >> 2;
189
2.65k
        m_pos -= *ip++ << 2;
190
2.65k
#endif
191
2.65k
        TEST_LB(m_pos); NEED_OP(3);
192
2.65k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
2.65k
#endif /* COPY_DICT */
194
2.65k
        goto match_done;
195
196
197
        /* handle matches */
198
689k
        for (;;) {
199
1.53M
match:
200
1.53M
            if (t >= 64)                /* a M2 match */
201
670k
            {
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
670k
#if defined(LZO1X)
222
670k
                m_pos = op - 1;
223
670k
                m_pos -= (t >> 2) & 7;
224
670k
                m_pos -= *ip++ << 3;
225
670k
                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
670k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
670k
                goto copy_match;
251
670k
#endif /* COPY_DICT */
252
670k
            }
253
865k
            else if (t >= 32)           /* a M3 match */
254
533k
            {
255
533k
                t &= 31;
256
533k
                if (t == 0)
257
115k
                {
258
228k
                    while (*ip == 0)
259
112k
                    {
260
112k
                        t += 255;
261
112k
                        ip++;
262
112k
                        TEST_OV(t);
263
112k
                        NEED_IP(1);
264
112k
                    }
265
115k
                    t += 31 + *ip++;
266
115k
                    NEED_IP(2);
267
115k
                }
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
533k
                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
533k
#endif /* COPY_DICT */
290
533k
                ip += 2;
291
533k
            }
292
332k
            else if (t >= 16)           /* a M4 match */
293
98.4k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
98.4k
                m_pos = op;
298
98.4k
                m_pos -= (t & 8) << 11;
299
98.4k
#endif /* COPY_DICT */
300
98.4k
                t &= 7;
301
98.4k
                if (t == 0)
302
40.7k
                {
303
67.1k
                    while (*ip == 0)
304
26.4k
                    {
305
26.4k
                        t += 255;
306
26.4k
                        ip++;
307
26.4k
                        TEST_OV(t);
308
26.4k
                        NEED_IP(1);
309
26.4k
                    }
310
40.7k
                    t += 7 + *ip++;
311
40.7k
                    NEED_IP(2);
312
40.7k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
98.4k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
98.4k
                ip += 2;
335
98.4k
                if (m_pos == op)
336
3.77k
                    goto eof_found;
337
94.7k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
94.7k
#endif /* COPY_DICT */
342
94.7k
            }
343
233k
            else                            /* a M1 match */
344
233k
            {
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
233k
                m_pos = op - 1;
361
233k
                m_pos -= t >> 2;
362
233k
                m_pos -= *ip++ << 2;
363
233k
#endif
364
233k
                TEST_LB(m_pos); NEED_OP(2);
365
233k
                *op++ = *m_pos++; *op++ = *m_pos;
366
233k
#endif /* COPY_DICT */
367
233k
                goto match_done;
368
233k
            }
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
627k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
627k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
627k
            if (op - m_pos >= 8)
381
581k
            {
382
581k
                t += (3 - 1);
383
581k
                if (t >= 8) do
384
4.32M
                {
385
4.32M
                    UA_COPY8(op,m_pos);
386
4.32M
                    op += 8; m_pos += 8; t -= 8;
387
4.32M
                } while (t >= 8);
388
581k
                if (t >= 4)
389
305k
                {
390
305k
                    UA_COPY4(op,m_pos);
391
305k
                    op += 4; m_pos += 4; t -= 4;
392
305k
                }
393
581k
                if (t > 0)
394
409k
                {
395
409k
                    *op++ = m_pos[0];
396
409k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
409k
                }
398
581k
            }
399
45.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
45.8k
            {
420
715k
copy_match:
421
715k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
19.1M
                do *op++ = *m_pos++; while (--t > 0);
423
715k
            }
424
425
627k
#endif /* COPY_DICT */
426
427
1.53M
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
1.53M
            t = ip[-2] & 3;
432
1.53M
#endif
433
1.53M
            if (t == 0)
434
845k
                break;
435
436
            /* copy literals */
437
689k
match_next:
438
689k
            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
689k
            *op++ = *ip++;
443
689k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
689k
#endif
445
689k
            t = *ip++;
446
689k
        }
447
0
    }
448
449
3.77k
eof_found:
450
3.77k
    *out_len = pd(op, out);
451
3.77k
    return (ip == ip_end ? LZO_E_OK :
452
3.77k
           (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.35k
}
lzo1y_decompress
Line
Count
Source
42
1.83k
{
43
1.83k
    lzo_bytep op;
44
1.83k
    const lzo_bytep ip;
45
1.83k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
1.83k
    const lzo_bytep m_pos;
51
1.83k
#endif
52
53
1.83k
    const lzo_bytep const ip_end = in + in_len;
54
#if defined(HAVE_ANY_OP)
55
    lzo_bytep const op_end = out + *out_len;
56
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
1.83k
    LZO_UNUSED(wrkmem);
62
63
#if defined(COPY_DICT)
64
    if (dict)
65
    {
66
        if (dict_len > M4_MAX_OFFSET)
67
        {
68
            dict += dict_len - M4_MAX_OFFSET;
69
            dict_len = M4_MAX_OFFSET;
70
        }
71
        dict_end = dict + dict_len;
72
    }
73
    else
74
    {
75
        dict_len = 0;
76
        dict_end = NULL;
77
    }
78
#endif /* COPY_DICT */
79
80
1.83k
    *out_len = 0;
81
82
1.83k
    op = out;
83
1.83k
    ip = in;
84
85
1.83k
    NEED_IP(1);
86
1.83k
    if (*ip > 17)
87
1.31k
    {
88
1.31k
        t = *ip++ - 17;
89
1.31k
        if (t < 4)
90
575
            goto match_next;
91
1.31k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
12.5k
        do *op++ = *ip++; while (--t > 0);
93
744
        goto first_literal_run;
94
1.31k
    }
95
96
511
    for (;;)
97
427k
    {
98
427k
        NEED_IP(3);
99
427k
        t = *ip++;
100
427k
        if (t >= 16)
101
330k
            goto match;
102
        /* a literal run */
103
96.7k
        if (t == 0)
104
34.5k
        {
105
178k
            while (*ip == 0)
106
143k
            {
107
143k
                t += 255;
108
143k
                ip++;
109
143k
                TEST_IV(t);
110
143k
                NEED_IP(1);
111
143k
            }
112
34.5k
            t += 15 + *ip++;
113
34.5k
        }
114
        /* copy literals */
115
96.7k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
96.7k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
96.7k
        t += 3;
118
96.7k
        if (t >= 8) do
119
4.95M
        {
120
4.95M
            UA_COPY8(op,ip);
121
4.95M
            op += 8; ip += 8; t -= 8;
122
4.95M
        } while (t >= 8);
123
96.7k
        if (t >= 4)
124
61.0k
        {
125
61.0k
            UA_COPY4(op,ip);
126
61.0k
            op += 4; ip += 4; t -= 4;
127
61.0k
        }
128
96.7k
        if (t > 0)
129
63.7k
        {
130
63.7k
            *op++ = *ip++;
131
63.7k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
63.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
97.5k
first_literal_run:
167
168
169
97.5k
        t = *ip++;
170
97.5k
        if (t >= 16)
171
91.7k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
5.73k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
5.73k
        m_pos -= t >> 2;
189
5.73k
        m_pos -= *ip++ << 2;
190
5.73k
#endif
191
5.73k
        TEST_LB(m_pos); NEED_OP(3);
192
5.73k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
5.73k
#endif /* COPY_DICT */
194
5.73k
        goto match_done;
195
196
197
        /* handle matches */
198
456k
        for (;;) {
199
878k
match:
200
878k
            if (t >= 64)                /* a M2 match */
201
398k
            {
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
398k
                m_pos -= (t >> 2) & 3;
229
398k
                m_pos -= *ip++ << 2;
230
398k
                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
398k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
398k
                goto copy_match;
251
398k
#endif /* COPY_DICT */
252
398k
            }
253
480k
            else if (t >= 32)           /* a M3 match */
254
273k
            {
255
273k
                t &= 31;
256
273k
                if (t == 0)
257
58.4k
                {
258
114k
                    while (*ip == 0)
259
55.7k
                    {
260
55.7k
                        t += 255;
261
55.7k
                        ip++;
262
55.7k
                        TEST_OV(t);
263
55.7k
                        NEED_IP(1);
264
55.7k
                    }
265
58.4k
                    t += 31 + *ip++;
266
58.4k
                    NEED_IP(2);
267
58.4k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
                {
278
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
                    m_pos = op - off;
280
                    last_m_off = off;
281
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
                m_pos = op - 1;
284
273k
                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
273k
#endif /* COPY_DICT */
290
273k
                ip += 2;
291
273k
            }
292
207k
            else if (t >= 16)           /* a M4 match */
293
69.9k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
69.9k
                m_pos = op;
298
69.9k
                m_pos -= (t & 8) << 11;
299
69.9k
#endif /* COPY_DICT */
300
69.9k
                t &= 7;
301
69.9k
                if (t == 0)
302
25.8k
                {
303
36.2k
                    while (*ip == 0)
304
10.3k
                    {
305
10.3k
                        t += 255;
306
10.3k
                        ip++;
307
10.3k
                        TEST_OV(t);
308
10.3k
                        NEED_IP(1);
309
10.3k
                    }
310
25.8k
                    t += 7 + *ip++;
311
25.8k
                    NEED_IP(2);
312
25.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
69.9k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
69.9k
                ip += 2;
335
69.9k
                if (m_pos == op)
336
1.83k
                    goto eof_found;
337
68.1k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
68.1k
#endif /* COPY_DICT */
342
68.1k
            }
343
137k
            else                            /* a M1 match */
344
137k
            {
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
137k
                m_pos = op - 1;
361
137k
                m_pos -= t >> 2;
362
137k
                m_pos -= *ip++ << 2;
363
137k
#endif
364
137k
                TEST_LB(m_pos); NEED_OP(2);
365
137k
                *op++ = *m_pos++; *op++ = *m_pos;
366
137k
#endif /* COPY_DICT */
367
137k
                goto match_done;
368
137k
            }
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
341k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
341k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
341k
            if (op - m_pos >= 8)
381
324k
            {
382
324k
                t += (3 - 1);
383
324k
                if (t >= 8) do
384
2.05M
                {
385
2.05M
                    UA_COPY8(op,m_pos);
386
2.05M
                    op += 8; m_pos += 8; t -= 8;
387
2.05M
                } while (t >= 8);
388
324k
                if (t >= 4)
389
166k
                {
390
166k
                    UA_COPY4(op,m_pos);
391
166k
                    op += 4; m_pos += 4; t -= 4;
392
166k
                }
393
324k
                if (t > 0)
394
230k
                {
395
230k
                    *op++ = m_pos[0];
396
230k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
230k
                }
398
324k
            }
399
17.3k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
17.3k
            {
420
415k
copy_match:
421
415k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
10.2M
                do *op++ = *m_pos++; while (--t > 0);
423
415k
            }
424
425
341k
#endif /* COPY_DICT */
426
427
882k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
882k
            t = ip[-2] & 3;
432
882k
#endif
433
882k
            if (t == 0)
434
426k
                break;
435
436
            /* copy literals */
437
456k
match_next:
438
456k
            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
456k
            *op++ = *ip++;
443
456k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
456k
#endif
445
456k
            t = *ip++;
446
456k
        }
447
0
    }
448
449
1.83k
eof_found:
450
1.83k
    *out_len = pd(op, out);
451
1.83k
    return (ip == ip_end ? LZO_E_OK :
452
1.83k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
#if defined(HAVE_NEED_IP)
456
input_overrun:
457
    *out_len = pd(op, out);
458
    return LZO_E_INPUT_OVERRUN;
459
#endif
460
461
#if defined(HAVE_NEED_OP)
462
output_overrun:
463
    *out_len = pd(op, out);
464
    return LZO_E_OUTPUT_OVERRUN;
465
#endif
466
467
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
lookbehind_overrun:
469
    *out_len = pd(op, out);
470
    return LZO_E_LOOKBEHIND_OVERRUN;
471
#endif
472
511
}
lzo1z_decompress
Line
Count
Source
42
1.66k
{
43
1.66k
    lzo_bytep op;
44
1.66k
    const lzo_bytep ip;
45
1.66k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
1.66k
    const lzo_bytep m_pos;
51
1.66k
#endif
52
53
1.66k
    const lzo_bytep const ip_end = in + in_len;
54
#if defined(HAVE_ANY_OP)
55
    lzo_bytep const op_end = out + *out_len;
56
#endif
57
1.66k
#if defined(LZO1Z)
58
1.66k
    lzo_uint last_m_off = 0;
59
1.66k
#endif
60
61
1.66k
    LZO_UNUSED(wrkmem);
62
63
#if defined(COPY_DICT)
64
    if (dict)
65
    {
66
        if (dict_len > M4_MAX_OFFSET)
67
        {
68
            dict += dict_len - M4_MAX_OFFSET;
69
            dict_len = M4_MAX_OFFSET;
70
        }
71
        dict_end = dict + dict_len;
72
    }
73
    else
74
    {
75
        dict_len = 0;
76
        dict_end = NULL;
77
    }
78
#endif /* COPY_DICT */
79
80
1.66k
    *out_len = 0;
81
82
1.66k
    op = out;
83
1.66k
    ip = in;
84
85
1.66k
    NEED_IP(1);
86
1.66k
    if (*ip > 17)
87
1.62k
    {
88
1.62k
        t = *ip++ - 17;
89
1.62k
        if (t < 4)
90
751
            goto match_next;
91
1.62k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
14.4k
        do *op++ = *ip++; while (--t > 0);
93
877
        goto first_literal_run;
94
1.62k
    }
95
96
39
    for (;;)
97
333k
    {
98
333k
        NEED_IP(3);
99
333k
        t = *ip++;
100
333k
        if (t >= 16)
101
275k
            goto match;
102
        /* a literal run */
103
58.1k
        if (t == 0)
104
18.1k
        {
105
53.5k
            while (*ip == 0)
106
35.3k
            {
107
35.3k
                t += 255;
108
35.3k
                ip++;
109
35.3k
                TEST_IV(t);
110
35.3k
                NEED_IP(1);
111
35.3k
            }
112
18.1k
            t += 15 + *ip++;
113
18.1k
        }
114
        /* copy literals */
115
58.1k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
58.1k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
58.1k
        t += 3;
118
58.1k
        if (t >= 8) do
119
1.30M
        {
120
1.30M
            UA_COPY8(op,ip);
121
1.30M
            op += 8; ip += 8; t -= 8;
122
1.30M
        } while (t >= 8);
123
58.1k
        if (t >= 4)
124
38.1k
        {
125
38.1k
            UA_COPY4(op,ip);
126
38.1k
            op += 4; ip += 4; t -= 4;
127
38.1k
        }
128
58.1k
        if (t > 0)
129
39.7k
        {
130
39.7k
            *op++ = *ip++;
131
39.7k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
39.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
59.0k
first_literal_run:
167
168
169
59.0k
        t = *ip++;
170
59.0k
        if (t >= 16)
171
54.4k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
4.55k
#if defined(LZO1Z)
183
4.55k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
4.55k
        m_pos = op - t;
185
4.55k
        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
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
555k
        for (;;) {
199
884k
match:
200
884k
            if (t >= 64)                /* a M2 match */
201
334k
            {
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
334k
                    lzo_uint off = t & 0x1f;
234
334k
                    m_pos = op;
235
334k
                    if (off >= 0x1c)
236
24.7k
                    {
237
24.7k
                        assert(last_m_off > 0);
238
24.7k
                        m_pos -= last_m_off;
239
24.7k
                    }
240
309k
                    else
241
309k
                    {
242
309k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
309k
                        m_pos -= off;
244
309k
                        last_m_off = off;
245
309k
                    }
246
334k
                }
247
334k
                t = (t >> 5) - 1;
248
334k
#endif
249
334k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
334k
                goto copy_match;
251
334k
#endif /* COPY_DICT */
252
334k
            }
253
550k
            else if (t >= 32)           /* a M3 match */
254
274k
            {
255
274k
                t &= 31;
256
274k
                if (t == 0)
257
46.9k
                {
258
88.3k
                    while (*ip == 0)
259
41.4k
                    {
260
41.4k
                        t += 255;
261
41.4k
                        ip++;
262
41.4k
                        TEST_OV(t);
263
41.4k
                        NEED_IP(1);
264
41.4k
                    }
265
46.9k
                    t += 31 + *ip++;
266
46.9k
                    NEED_IP(2);
267
46.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
274k
#if defined(LZO1Z)
277
274k
                {
278
274k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
274k
                    m_pos = op - off;
280
274k
                    last_m_off = off;
281
274k
                }
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
274k
#endif /* COPY_DICT */
290
274k
                ip += 2;
291
274k
            }
292
275k
            else if (t >= 16)           /* a M4 match */
293
71.5k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
71.5k
                m_pos = op;
298
71.5k
                m_pos -= (t & 8) << 11;
299
71.5k
#endif /* COPY_DICT */
300
71.5k
                t &= 7;
301
71.5k
                if (t == 0)
302
31.0k
                {
303
38.0k
                    while (*ip == 0)
304
6.98k
                    {
305
6.98k
                        t += 255;
306
6.98k
                        ip++;
307
6.98k
                        TEST_OV(t);
308
6.98k
                        NEED_IP(1);
309
6.98k
                    }
310
31.0k
                    t += 7 + *ip++;
311
31.0k
                    NEED_IP(2);
312
31.0k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
71.5k
#if defined(LZO1Z)
328
71.5k
                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
71.5k
                ip += 2;
335
71.5k
                if (m_pos == op)
336
1.66k
                    goto eof_found;
337
69.8k
                m_pos -= 0x4000;
338
69.8k
#if defined(LZO1Z)
339
69.8k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
69.8k
#endif
341
69.8k
#endif /* COPY_DICT */
342
69.8k
            }
343
204k
            else                            /* a M1 match */
344
204k
            {
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
204k
#if defined(LZO1Z)
356
204k
                t = 1 + (t << 6) + (*ip++ >> 2);
357
204k
                m_pos = op - t;
358
204k
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
204k
                TEST_LB(m_pos); NEED_OP(2);
365
204k
                *op++ = *m_pos++; *op++ = *m_pos;
366
204k
#endif /* COPY_DICT */
367
204k
                goto match_done;
368
204k
            }
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
344k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
344k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
344k
            if (op - m_pos >= 8)
381
325k
            {
382
325k
                t += (3 - 1);
383
325k
                if (t >= 8) do
384
1.92M
                {
385
1.92M
                    UA_COPY8(op,m_pos);
386
1.92M
                    op += 8; m_pos += 8; t -= 8;
387
1.92M
                } while (t >= 8);
388
325k
                if (t >= 4)
389
134k
                {
390
134k
                    UA_COPY4(op,m_pos);
391
134k
                    op += 4; m_pos += 4; t -= 4;
392
134k
                }
393
325k
                if (t > 0)
394
250k
                {
395
250k
                    *op++ = m_pos[0];
396
250k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
250k
                }
398
325k
            }
399
18.9k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
18.9k
            {
420
353k
copy_match:
421
353k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
5.69M
                do *op++ = *m_pos++; while (--t > 0);
423
353k
            }
424
425
344k
#endif /* COPY_DICT */
426
427
887k
match_done:
428
887k
#if defined(LZO1Z)
429
887k
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
887k
            if (t == 0)
434
333k
                break;
435
436
            /* copy literals */
437
555k
match_next:
438
555k
            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
555k
            *op++ = *ip++;
443
555k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
555k
#endif
445
555k
            t = *ip++;
446
555k
        }
447
0
    }
448
449
1.66k
eof_found:
450
1.66k
    *out_len = pd(op, out);
451
1.66k
    return (ip == ip_end ? LZO_E_OK :
452
1.66k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
#if defined(HAVE_NEED_IP)
456
input_overrun:
457
    *out_len = pd(op, out);
458
    return LZO_E_INPUT_OVERRUN;
459
#endif
460
461
#if defined(HAVE_NEED_OP)
462
output_overrun:
463
    *out_len = pd(op, out);
464
    return LZO_E_OUTPUT_OVERRUN;
465
#endif
466
467
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
lookbehind_overrun:
469
    *out_len = pd(op, out);
470
    return LZO_E_LOOKBEHIND_OVERRUN;
471
#endif
472
39
}
lzo1x_decompress_safe
Line
Count
Source
42
590
{
43
590
    lzo_bytep op;
44
590
    const lzo_bytep ip;
45
590
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
590
    const lzo_bytep m_pos;
51
590
#endif
52
53
590
    const lzo_bytep const ip_end = in + in_len;
54
590
#if defined(HAVE_ANY_OP)
55
590
    lzo_bytep const op_end = out + *out_len;
56
590
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
590
    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
590
    *out_len = 0;
81
82
590
    op = out;
83
590
    ip = in;
84
85
590
    NEED_IP(1);
86
590
    if (*ip > 17)
87
349
    {
88
349
        t = *ip++ - 17;
89
349
        if (t < 4)
90
248
            goto match_next;
91
349
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
1.71k
        do *op++ = *ip++; while (--t > 0);
93
85
        goto first_literal_run;
94
101
    }
95
96
241
    for (;;)
97
36.7k
    {
98
36.7k
        NEED_IP(3);
99
36.7k
        t = *ip++;
100
36.7k
        if (t >= 16)
101
24.8k
            goto match;
102
        /* a literal run */
103
11.8k
        if (t == 0)
104
5.25k
        {
105
4.32M
            while (*ip == 0)
106
4.32M
            {
107
4.32M
                t += 255;
108
4.32M
                ip++;
109
4.32M
                TEST_IV(t);
110
4.32M
                NEED_IP(1);
111
4.32M
            }
112
5.23k
            t += 15 + *ip++;
113
5.23k
        }
114
        /* copy literals */
115
11.8k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
11.6k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
11.6k
        t += 3;
118
11.6k
        if (t >= 8) do
119
251k
        {
120
251k
            UA_COPY8(op,ip);
121
251k
            op += 8; ip += 8; t -= 8;
122
251k
        } while (t >= 8);
123
11.6k
        if (t >= 4)
124
7.51k
        {
125
7.51k
            UA_COPY4(op,ip);
126
7.51k
            op += 4; ip += 4; t -= 4;
127
7.51k
        }
128
11.6k
        if (t > 0)
129
8.79k
        {
130
8.79k
            *op++ = *ip++;
131
8.79k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
8.79k
        }
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
11.7k
first_literal_run:
167
168
169
11.7k
        t = *ip++;
170
11.7k
        if (t >= 16)
171
6.01k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
5.74k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
5.74k
        m_pos -= t >> 2;
189
5.74k
        m_pos -= *ip++ << 2;
190
5.74k
#endif
191
5.74k
        TEST_LB(m_pos); NEED_OP(3);
192
5.71k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
5.71k
#endif /* COPY_DICT */
194
5.71k
        goto match_done;
195
196
197
        /* handle matches */
198
102k
        for (;;) {
199
133k
match:
200
133k
            if (t >= 64)                /* a M2 match */
201
49.9k
            {
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
49.9k
#if defined(LZO1X)
222
49.9k
                m_pos = op - 1;
223
49.9k
                m_pos -= (t >> 2) & 7;
224
49.9k
                m_pos -= *ip++ << 3;
225
49.9k
                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
49.9k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
49.9k
                goto copy_match;
251
49.9k
#endif /* COPY_DICT */
252
49.9k
            }
253
83.3k
            else if (t >= 32)           /* a M3 match */
254
31.0k
            {
255
31.0k
                t &= 31;
256
31.0k
                if (t == 0)
257
2.68k
                {
258
1.41M
                    while (*ip == 0)
259
1.40M
                    {
260
1.40M
                        t += 255;
261
1.40M
                        ip++;
262
1.40M
                        TEST_OV(t);
263
1.40M
                        NEED_IP(1);
264
1.40M
                    }
265
2.66k
                    t += 31 + *ip++;
266
2.66k
                    NEED_IP(2);
267
2.66k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
                {
278
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
                    m_pos = op - off;
280
                    last_m_off = off;
281
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
31.0k
                m_pos = op - 1;
284
31.0k
                m_pos -= UA_GET_LE16(ip) >> 2;
285
#else
286
                m_pos = op - 1;
287
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
288
#endif
289
31.0k
#endif /* COPY_DICT */
290
31.0k
                ip += 2;
291
31.0k
            }
292
52.2k
            else if (t >= 16)           /* a M4 match */
293
9.28k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
9.28k
                m_pos = op;
298
9.28k
                m_pos -= (t & 8) << 11;
299
9.28k
#endif /* COPY_DICT */
300
9.28k
                t &= 7;
301
9.28k
                if (t == 0)
302
2.43k
                {
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.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
9.25k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
9.25k
                ip += 2;
335
9.25k
                if (m_pos == op)
336
14
                    goto eof_found;
337
9.23k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
9.23k
#endif /* COPY_DICT */
342
9.23k
            }
343
42.9k
            else                            /* a M1 match */
344
42.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
42.9k
                m_pos = op - 1;
361
42.9k
                m_pos -= t >> 2;
362
42.9k
                m_pos -= *ip++ << 2;
363
42.9k
#endif
364
42.9k
                TEST_LB(m_pos); NEED_OP(2);
365
42.9k
                *op++ = *m_pos++; *op++ = *m_pos;
366
42.9k
#endif /* COPY_DICT */
367
42.9k
                goto match_done;
368
42.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
40.2k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
40.1k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
40.1k
            if (op - m_pos >= 8)
381
37.3k
            {
382
37.3k
                t += (3 - 1);
383
37.3k
                if (t >= 8) do
384
599k
                {
385
599k
                    UA_COPY8(op,m_pos);
386
599k
                    op += 8; m_pos += 8; t -= 8;
387
599k
                } while (t >= 8);
388
37.3k
                if (t >= 4)
389
23.3k
                {
390
23.3k
                    UA_COPY4(op,m_pos);
391
23.3k
                    op += 4; m_pos += 4; t -= 4;
392
23.3k
                }
393
37.3k
                if (t > 0)
394
29.8k
                {
395
29.8k
                    *op++ = m_pos[0];
396
29.8k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
29.8k
                }
398
37.3k
            }
399
2.79k
            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.79k
            {
420
52.7k
copy_match:
421
52.7k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
10.1M
                do *op++ = *m_pos++; while (--t > 0);
423
52.7k
            }
424
425
40.1k
#endif /* COPY_DICT */
426
427
138k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
138k
            t = ip[-2] & 3;
432
138k
#endif
433
138k
            if (t == 0)
434
36.5k
                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
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
368
input_overrun:
457
368
    *out_len = pd(op, out);
458
368
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
58
output_overrun:
463
58
    *out_len = pd(op, out);
464
58
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
150
lookbehind_overrun:
469
150
    *out_len = pd(op, out);
470
150
    return LZO_E_LOOKBEHIND_OVERRUN;
471
241
#endif
472
241
}
lzo1y_decompress_safe
Line
Count
Source
42
597
{
43
597
    lzo_bytep op;
44
597
    const lzo_bytep ip;
45
597
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
597
    const lzo_bytep m_pos;
51
597
#endif
52
53
597
    const lzo_bytep const ip_end = in + in_len;
54
597
#if defined(HAVE_ANY_OP)
55
597
    lzo_bytep const op_end = out + *out_len;
56
597
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
597
    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
597
    *out_len = 0;
81
82
597
    op = out;
83
597
    ip = in;
84
85
597
    NEED_IP(1);
86
597
    if (*ip > 17)
87
351
    {
88
351
        t = *ip++ - 17;
89
351
        if (t < 4)
90
225
            goto match_next;
91
351
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
2.72k
        do *op++ = *ip++; while (--t > 0);
93
114
        goto first_literal_run;
94
126
    }
95
96
246
    for (;;)
97
120k
    {
98
120k
        NEED_IP(3);
99
120k
        t = *ip++;
100
120k
        if (t >= 16)
101
103k
            goto match;
102
        /* a literal run */
103
16.9k
        if (t == 0)
104
7.81k
        {
105
15.1M
            while (*ip == 0)
106
15.1M
            {
107
15.1M
                t += 255;
108
15.1M
                ip++;
109
15.1M
                TEST_IV(t);
110
15.1M
                NEED_IP(1);
111
15.1M
            }
112
7.78k
            t += 15 + *ip++;
113
7.78k
        }
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
511k
        {
120
511k
            UA_COPY8(op,ip);
121
511k
            op += 8; ip += 8; t -= 8;
122
511k
        } while (t >= 8);
123
16.7k
        if (t >= 4)
124
10.6k
        {
125
10.6k
            UA_COPY4(op,ip);
126
10.6k
            op += 4; ip += 4; t -= 4;
127
10.6k
        }
128
16.7k
        if (t > 0)
129
12.2k
        {
130
12.2k
            *op++ = *ip++;
131
12.2k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
12.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
16.8k
first_literal_run:
167
168
169
16.8k
        t = *ip++;
170
16.8k
        if (t >= 16)
171
8.26k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
8.59k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
8.59k
        m_pos -= t >> 2;
189
8.59k
        m_pos -= *ip++ << 2;
190
8.59k
#endif
191
8.59k
        TEST_LB(m_pos); NEED_OP(3);
192
8.55k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
8.55k
#endif /* COPY_DICT */
194
8.55k
        goto match_done;
195
196
197
        /* handle matches */
198
121k
        for (;;) {
199
233k
match:
200
233k
            if (t >= 64)                /* a M2 match */
201
142k
            {
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
142k
                m_pos -= (t >> 2) & 3;
229
142k
                m_pos -= *ip++ << 2;
230
142k
                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
142k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
141k
                goto copy_match;
251
142k
#endif /* COPY_DICT */
252
142k
            }
253
91.6k
            else if (t >= 32)           /* a M3 match */
254
37.8k
            {
255
37.8k
                t &= 31;
256
37.8k
                if (t == 0)
257
4.30k
                {
258
11.6M
                    while (*ip == 0)
259
11.6M
                    {
260
11.6M
                        t += 255;
261
11.6M
                        ip++;
262
11.6M
                        TEST_OV(t);
263
11.6M
                        NEED_IP(1);
264
11.6M
                    }
265
4.28k
                    t += 31 + *ip++;
266
4.28k
                    NEED_IP(2);
267
4.28k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
                {
278
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
                    m_pos = op - off;
280
                    last_m_off = off;
281
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
37.7k
                m_pos = op - 1;
284
37.7k
                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
37.7k
#endif /* COPY_DICT */
290
37.7k
                ip += 2;
291
37.7k
            }
292
53.8k
            else if (t >= 16)           /* a M4 match */
293
10.9k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
10.9k
                m_pos = op;
298
10.9k
                m_pos -= (t & 8) << 11;
299
10.9k
#endif /* COPY_DICT */
300
10.9k
                t &= 7;
301
10.9k
                if (t == 0)
302
3.19k
                {
303
4.99M
                    while (*ip == 0)
304
4.98M
                    {
305
4.98M
                        t += 255;
306
4.98M
                        ip++;
307
4.98M
                        TEST_OV(t);
308
4.98M
                        NEED_IP(1);
309
4.98M
                    }
310
3.17k
                    t += 7 + *ip++;
311
3.17k
                    NEED_IP(2);
312
3.17k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
10.9k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
10.9k
                ip += 2;
335
10.9k
                if (m_pos == op)
336
12
                    goto eof_found;
337
10.9k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
10.9k
#endif /* COPY_DICT */
342
10.9k
            }
343
42.9k
            else                            /* a M1 match */
344
42.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
42.9k
                m_pos = op - 1;
361
42.9k
                m_pos -= t >> 2;
362
42.9k
                m_pos -= *ip++ << 2;
363
42.9k
#endif
364
42.9k
                TEST_LB(m_pos); NEED_OP(2);
365
42.9k
                *op++ = *m_pos++; *op++ = *m_pos;
366
42.9k
#endif /* COPY_DICT */
367
42.9k
                goto match_done;
368
42.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
48.6k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
48.5k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
48.5k
            if (op - m_pos >= 8)
381
45.1k
            {
382
45.1k
                t += (3 - 1);
383
45.1k
                if (t >= 8) do
384
583k
                {
385
583k
                    UA_COPY8(op,m_pos);
386
583k
                    op += 8; m_pos += 8; t -= 8;
387
583k
                } while (t >= 8);
388
45.1k
                if (t >= 4)
389
25.6k
                {
390
25.6k
                    UA_COPY4(op,m_pos);
391
25.6k
                    op += 4; m_pos += 4; t -= 4;
392
25.6k
                }
393
45.1k
                if (t > 0)
394
35.9k
                {
395
35.9k
                    *op++ = m_pos[0];
396
35.9k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
35.9k
                }
398
45.1k
            }
399
3.45k
            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.45k
            {
420
145k
copy_match:
421
145k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
10.9M
                do *op++ = *m_pos++; while (--t > 0);
423
145k
            }
424
425
48.5k
#endif /* COPY_DICT */
426
427
242k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
242k
            t = ip[-2] & 3;
432
242k
#endif
433
242k
            if (t == 0)
434
120k
                break;
435
436
            /* copy literals */
437
121k
match_next:
438
121k
            assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
439
#if 0
440
            do *op++ = *ip++; while (--t > 0);
441
#else
442
121k
            *op++ = *ip++;
443
121k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
121k
#endif
445
121k
            t = *ip++;
446
121k
        }
447
0
    }
448
449
12
eof_found:
450
12
    *out_len = pd(op, out);
451
12
    return (ip == ip_end ? LZO_E_OK :
452
12
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
365
input_overrun:
457
365
    *out_len = pd(op, out);
458
365
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
67
output_overrun:
463
67
    *out_len = pd(op, out);
464
67
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
153
lookbehind_overrun:
469
153
    *out_len = pd(op, out);
470
153
    return LZO_E_LOOKBEHIND_OVERRUN;
471
246
#endif
472
246
}
lzo1z_decompress_safe
Line
Count
Source
42
575
{
43
575
    lzo_bytep op;
44
575
    const lzo_bytep ip;
45
575
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
575
    const lzo_bytep m_pos;
51
575
#endif
52
53
575
    const lzo_bytep const ip_end = in + in_len;
54
575
#if defined(HAVE_ANY_OP)
55
575
    lzo_bytep const op_end = out + *out_len;
56
575
#endif
57
575
#if defined(LZO1Z)
58
575
    lzo_uint last_m_off = 0;
59
575
#endif
60
61
575
    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
575
    *out_len = 0;
81
82
575
    op = out;
83
575
    ip = in;
84
85
575
    NEED_IP(1);
86
575
    if (*ip > 17)
87
395
    {
88
395
        t = *ip++ - 17;
89
395
        if (t < 4)
90
265
            goto match_next;
91
395
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
1.32k
        do *op++ = *ip++; while (--t > 0);
93
120
        goto first_literal_run;
94
130
    }
95
96
180
    for (;;)
97
48.5k
    {
98
48.5k
        NEED_IP(3);
99
48.4k
        t = *ip++;
100
48.4k
        if (t >= 16)
101
29.4k
            goto match;
102
        /* a literal run */
103
19.0k
        if (t == 0)
104
8.62k
        {
105
2.74M
            while (*ip == 0)
106
2.73M
            {
107
2.73M
                t += 255;
108
2.73M
                ip++;
109
2.73M
                TEST_IV(t);
110
2.73M
                NEED_IP(1);
111
2.73M
            }
112
8.60k
            t += 15 + *ip++;
113
8.60k
        }
114
        /* copy literals */
115
19.0k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
18.8k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
18.8k
        t += 3;
118
18.8k
        if (t >= 8) do
119
408k
        {
120
408k
            UA_COPY8(op,ip);
121
408k
            op += 8; ip += 8; t -= 8;
122
408k
        } while (t >= 8);
123
18.8k
        if (t >= 4)
124
10.9k
        {
125
10.9k
            UA_COPY4(op,ip);
126
10.9k
            op += 4; ip += 4; t -= 4;
127
10.9k
        }
128
18.8k
        if (t > 0)
129
11.6k
        {
130
11.6k
            *op++ = *ip++;
131
11.6k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
11.6k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
18.9k
first_literal_run:
167
168
169
18.9k
        t = *ip++;
170
18.9k
        if (t >= 16)
171
9.32k
            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
9.63k
#if defined(LZO1Z)
183
9.63k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
9.63k
        m_pos = op - t;
185
9.63k
        last_m_off = t;
186
#else
187
        m_pos = op - (1 + M2_MAX_OFFSET);
188
        m_pos -= t >> 2;
189
        m_pos -= *ip++ << 2;
190
#endif
191
9.63k
        TEST_LB(m_pos); NEED_OP(3);
192
9.60k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
9.60k
#endif /* COPY_DICT */
194
9.60k
        goto match_done;
195
196
197
        /* handle matches */
198
76.6k
        for (;;) {
199
115k
match:
200
115k
            if (t >= 64)                /* a M2 match */
201
62.3k
            {
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
62.3k
                    lzo_uint off = t & 0x1f;
234
62.3k
                    m_pos = op;
235
62.3k
                    if (off >= 0x1c)
236
9.47k
                    {
237
9.47k
                        assert(last_m_off > 0);
238
9.47k
                        m_pos -= last_m_off;
239
9.47k
                    }
240
52.8k
                    else
241
52.8k
                    {
242
52.8k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
52.8k
                        m_pos -= off;
244
52.8k
                        last_m_off = off;
245
52.8k
                    }
246
62.3k
                }
247
62.3k
                t = (t >> 5) - 1;
248
62.3k
#endif
249
62.3k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
62.3k
                goto copy_match;
251
62.3k
#endif /* COPY_DICT */
252
62.3k
            }
253
53.0k
            else if (t >= 32)           /* a M3 match */
254
31.6k
            {
255
31.6k
                t &= 31;
256
31.6k
                if (t == 0)
257
3.50k
                {
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
3.48k
                    t += 31 + *ip++;
266
3.48k
                    NEED_IP(2);
267
3.48k
                }
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
31.6k
#if defined(LZO1Z)
277
31.6k
                {
278
31.6k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
31.6k
                    m_pos = op - off;
280
31.6k
                    last_m_off = off;
281
31.6k
                }
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
31.6k
#endif /* COPY_DICT */
290
31.6k
                ip += 2;
291
31.6k
            }
292
21.4k
            else if (t >= 16)           /* a M4 match */
293
8.89k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
8.89k
                m_pos = op;
298
8.89k
                m_pos -= (t & 8) << 11;
299
8.89k
#endif /* COPY_DICT */
300
8.89k
                t &= 7;
301
8.89k
                if (t == 0)
302
2.56k
                {
303
4.31k
                    while (*ip == 0)
304
1.75k
                    {
305
1.75k
                        t += 255;
306
1.75k
                        ip++;
307
1.75k
                        TEST_OV(t);
308
1.75k
                        NEED_IP(1);
309
1.75k
                    }
310
2.55k
                    t += 7 + *ip++;
311
2.55k
                    NEED_IP(2);
312
2.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
8.87k
#if defined(LZO1Z)
328
8.87k
                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
8.87k
                ip += 2;
335
8.87k
                if (m_pos == op)
336
10
                    goto eof_found;
337
8.86k
                m_pos -= 0x4000;
338
8.86k
#if defined(LZO1Z)
339
8.86k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
8.86k
#endif
341
8.86k
#endif /* COPY_DICT */
342
8.86k
            }
343
12.5k
            else                            /* a M1 match */
344
12.5k
            {
345
#if defined(COPY_DICT)
346
#if defined(LZO1Z)
347
                m_off = 1 + (t << 6) + (*ip++ >> 2);
348
                last_m_off = m_off;
349
#else
350
                m_off = 1 + (t >> 2) + (*ip++ << 2);
351
#endif
352
                NEED_OP(2);
353
                t = 2; COPY_DICT(t,m_off)
354
#else /* !COPY_DICT */
355
12.5k
#if defined(LZO1Z)
356
12.5k
                t = 1 + (t << 6) + (*ip++ >> 2);
357
12.5k
                m_pos = op - t;
358
12.5k
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
12.5k
                TEST_LB(m_pos); NEED_OP(2);
365
12.5k
                *op++ = *m_pos++; *op++ = *m_pos;
366
12.5k
#endif /* COPY_DICT */
367
12.5k
                goto match_done;
368
12.5k
            }
369
370
            /* copy match */
371
#if defined(COPY_DICT)
372
373
            NEED_OP(t+3-1);
374
            t += 3-1; COPY_DICT(t,m_off)
375
376
#else /* !COPY_DICT */
377
378
40.4k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
40.3k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
40.3k
            if (op - m_pos >= 8)
381
38.2k
            {
382
38.2k
                t += (3 - 1);
383
38.2k
                if (t >= 8) do
384
1.02M
                {
385
1.02M
                    UA_COPY8(op,m_pos);
386
1.02M
                    op += 8; m_pos += 8; t -= 8;
387
1.02M
                } while (t >= 8);
388
38.2k
                if (t >= 4)
389
18.7k
                {
390
18.7k
                    UA_COPY4(op,m_pos);
391
18.7k
                    op += 4; m_pos += 4; t -= 4;
392
18.7k
                }
393
38.2k
                if (t > 0)
394
29.8k
                {
395
29.8k
                    *op++ = m_pos[0];
396
29.8k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
29.8k
                }
398
38.2k
            }
399
2.12k
            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.12k
            {
420
64.4k
copy_match:
421
64.4k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
6.19M
                do *op++ = *m_pos++; while (--t > 0);
423
64.4k
            }
424
425
40.3k
#endif /* COPY_DICT */
426
427
124k
match_done:
428
124k
#if defined(LZO1Z)
429
124k
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
124k
            if (t == 0)
434
48.3k
                break;
435
436
            /* copy literals */
437
76.7k
match_next:
438
76.7k
            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
76.6k
            *op++ = *ip++;
443
76.6k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
76.6k
#endif
445
76.6k
            t = *ip++;
446
76.6k
        }
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
356
input_overrun:
457
356
    *out_len = pd(op, out);
458
356
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
52
output_overrun:
463
52
    *out_len = pd(op, out);
464
52
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
157
lookbehind_overrun:
469
157
    *out_len = pd(op, out);
470
157
    return LZO_E_LOOKBEHIND_OVERRUN;
471
180
#endif
472
180
}
473
474
475
/* vim:set ts=4 sw=4 et: */