Coverage Report

Created: 2025-07-18 06:09

/src/lzo-2.10/src/lzo1x_d.ch
Line
Count
Source (jump to first uncovered line)
1
/* lzo1x_d.ch -- implementation of the LZO1X decompression algorithm
2
3
   This file is part of the LZO real-time data compression library.
4
5
   Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
6
   All Rights Reserved.
7
8
   The LZO library is free software; you can redistribute it and/or
9
   modify it under the terms of the GNU General Public License as
10
   published by the Free Software Foundation; either version 2 of
11
   the License, or (at your option) any later version.
12
13
   The LZO library is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with the LZO library; see the file COPYING.
20
   If not, write to the Free Software Foundation, Inc.,
21
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22
23
   Markus F.X.J. Oberhumer
24
   <markus@oberhumer.com>
25
   http://www.oberhumer.com/opensource/lzo/
26
 */
27
28
29
#include "lzo1_d.ch"
30
31
32
/***********************************************************************
33
// decompress a block of data.
34
************************************************************************/
35
36
#if defined(DO_DECOMPRESS)
37
LZO_PUBLIC(int)
38
DO_DECOMPRESS  ( const lzo_bytep in , lzo_uint  in_len,
39
                       lzo_bytep out, lzo_uintp out_len,
40
                       lzo_voidp wrkmem )
41
#endif
42
8.30k
{
43
8.30k
    lzo_bytep op;
44
8.30k
    const lzo_bytep ip;
45
8.30k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
8.30k
    const lzo_bytep m_pos;
51
8.30k
#endif
52
53
8.30k
    const lzo_bytep const ip_end = in + in_len;
54
#if defined(HAVE_ANY_OP)
55
1.88k
    lzo_bytep const op_end = out + *out_len;
56
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
8.30k
    LZO_UNUSED(wrkmem);
62
63
#if defined(COPY_DICT)
64
    if (dict)
65
    {
66
        if (dict_len > M4_MAX_OFFSET)
67
        {
68
            dict += dict_len - M4_MAX_OFFSET;
69
            dict_len = M4_MAX_OFFSET;
70
        }
71
        dict_end = dict + dict_len;
72
    }
73
    else
74
    {
75
        dict_len = 0;
76
        dict_end = NULL;
77
    }
78
#endif /* COPY_DICT */
79
80
8.30k
    *out_len = 0;
81
82
8.30k
    op = out;
83
8.30k
    ip = in;
84
85
8.30k
    NEED_IP(1);
86
8.30k
    if (*ip > 17)
87
4.89k
    {
88
4.89k
        t = *ip++ - 17;
89
4.89k
        if (t < 4)
90
2.63k
            goto match_next;
91
2.25k
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
39.6k
        do *op++ = *ip++; while (--t > 0);
93
209
        goto first_literal_run;
94
252
    }
95
96
3.40k
    for (;;)
97
1.79M
    {
98
1.79M
        NEED_IP(3);
99
83.6k
        t = *ip++;
100
1.79M
        if (t >= 16)
101
1.37M
            goto match;
102
        /* a literal run */
103
425k
        if (t == 0)
104
103k
        {
105
18.0M
            while (*ip == 0)
106
17.9M
            {
107
17.9M
                t += 255;
108
17.9M
                ip++;
109
17.9M
                TEST_IV(t);
110
17.9M
                NEED_IP(1);
111
17.5M
            }
112
13.0k
            t += 15 + *ip++;
113
13.0k
        }
114
        /* copy literals */
115
425k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
32.3k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
32.3k
        t += 3;
118
424k
        if (t >= 8) do
119
13.3M
        {
120
13.3M
            UA_COPY8(op,ip);
121
13.3M
            op += 8; ip += 8; t -= 8;
122
13.3M
        } while (t >= 8);
123
424k
        if (t >= 4)
124
286k
        {
125
286k
            UA_COPY4(op,ip);
126
286k
            op += 4; ip += 4; t -= 4;
127
286k
        }
128
424k
        if (t > 0)
129
274k
        {
130
274k
            *op++ = *ip++;
131
274k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
274k
        }
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
426k
first_literal_run:
167
168
169
426k
        t = *ip++;
170
426k
        if (t >= 16)
171
404k
            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
7.01k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
2.65k
        m_pos = op - t;
185
2.65k
        last_m_off = t;
186
#else
187
15.7k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
        m_pos -= t >> 2;
189
        m_pos -= *ip++ << 2;
190
#endif
191
22.7k
        TEST_LB(m_pos); NEED_OP(3);
192
16.6k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
16.6k
#endif /* COPY_DICT */
194
16.6k
        goto match_done;
195
196
197
        /* handle matches */
198
1.58M
        for (;;) {
199
3.36M
match:
200
3.36M
            if (t >= 64)                /* a M2 match */
201
1.58M
            {
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
363k
                    if (off >= 0x1c)
236
18.2k
                    {
237
18.2k
                        assert(last_m_off > 0);
238
18.2k
                        m_pos -= last_m_off;
239
18.2k
                    }
240
344k
                    else
241
344k
                    {
242
344k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
344k
                        m_pos -= off;
244
344k
                        last_m_off = off;
245
344k
                    }
246
                }
247
                t = (t >> 5) - 1;
248
#endif
249
1.58M
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
97.1k
                goto copy_match;
251
97.1k
#endif /* COPY_DICT */
252
97.1k
            }
253
1.77M
            else if (t >= 32)           /* a M3 match */
254
1.18M
            {
255
1.18M
                t &= 31;
256
1.18M
                if (t == 0)
257
250k
                {
258
4.90M
                    while (*ip == 0)
259
4.65M
                    {
260
4.65M
                        t += 255;
261
4.65M
                        ip++;
262
4.65M
                        TEST_OV(t);
263
4.65M
                        NEED_IP(1);
264
4.45M
                    }
265
7.04k
                    t += 31 + *ip++;
266
250k
                    NEED_IP(2);
267
7.04k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
14.7k
                {
278
14.7k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
14.7k
                    m_pos = op - off;
280
14.7k
                    last_m_off = off;
281
14.7k
                }
282
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
283
39.9k
                m_pos = op - 1;
284
904k
                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
39.9k
#endif /* COPY_DICT */
290
39.9k
                ip += 2;
291
39.9k
            }
292
596k
            else if (t >= 16)           /* a M4 match */
293
267k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
267k
                m_pos = op;
298
267k
                m_pos -= (t & 8) << 11;
299
267k
#endif /* COPY_DICT */
300
267k
                t &= 7;
301
267k
                if (t == 0)
302
100k
                {
303
4.76M
                    while (*ip == 0)
304
4.66M
                    {
305
4.66M
                        t += 255;
306
4.66M
                        ip++;
307
4.66M
                        TEST_OV(t);
308
4.66M
                        NEED_IP(1);
309
4.60M
                    }
310
5.97k
                    t += 7 + *ip++;
311
100k
                    NEED_IP(2);
312
5.97k
                }
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
4.30k
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
177k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
12.9k
                ip += 2;
335
266k
                if (m_pos == op)
336
6.46k
                    goto eof_found;
337
260k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
87.8k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
260k
#endif /* COPY_DICT */
342
260k
            }
343
329k
            else                            /* a M1 match */
344
329k
            {
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
329k
                TEST_LB(m_pos); NEED_OP(2);
365
41.7k
                *op++ = *m_pos++; *op++ = *m_pos;
366
41.7k
#endif /* COPY_DICT */
367
41.7k
                goto match_done;
368
41.7k
            }
369
370
            /* copy match */
371
#if defined(COPY_DICT)
372
373
            NEED_OP(t+3-1);
374
            t += 3-1; COPY_DICT(t,m_off)
375
376
#else /* !COPY_DICT */
377
378
1.44M
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
71.5k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
1.44M
            if (op - m_pos >= 8)
381
1.31M
            {
382
1.31M
                t += (3 - 1);
383
1.31M
                if (t >= 8) do
384
11.9M
                {
385
11.9M
                    UA_COPY8(op,m_pos);
386
11.9M
                    op += 8; m_pos += 8; t -= 8;
387
11.9M
                } while (t >= 8);
388
1.31M
                if (t >= 4)
389
706k
                {
390
706k
                    UA_COPY4(op,m_pos);
391
706k
                    op += 4; m_pos += 4; t -= 4;
392
706k
                }
393
1.31M
                if (t > 0)
394
940k
                {
395
940k
                    *op++ = m_pos[0];
396
940k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
940k
                }
398
1.31M
            }
399
125k
            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
125k
            {
420
1.71M
copy_match:
421
1.71M
                *op++ = *m_pos++; *op++ = *m_pos++;
422
54.5M
                do *op++ = *m_pos++; while (--t > 0);
423
1.71M
            }
424
425
71.5k
#endif /* COPY_DICT */
426
427
3.38M
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
3.38M
            if (t == 0)
434
1.79M
                break;
435
436
            /* copy literals */
437
1.58M
match_next:
438
1.58M
            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
144k
            *op++ = *ip++;
443
1.58M
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
144k
#endif
445
144k
            t = *ip++;
446
144k
        }
447
0
    }
448
449
6.46k
eof_found:
450
6.46k
    *out_len = pd(op, out);
451
6.46k
    return (ip == ip_end ? LZO_E_OK :
452
6.46k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
#if defined(HAVE_NEED_IP)
456
1.21k
input_overrun:
457
1.21k
    *out_len = pd(op, out);
458
1.21k
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
#if defined(HAVE_NEED_OP)
462
145
output_overrun:
463
145
    *out_len = pd(op, out);
464
145
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
480
lookbehind_overrun:
469
480
    *out_len = pd(op, out);
470
480
    return LZO_E_LOOKBEHIND_OVERRUN;
471
#endif
472
3.40k
}
lzo1x_decompress
Line
Count
Source
42
3.31k
{
43
3.31k
    lzo_bytep op;
44
3.31k
    const lzo_bytep ip;
45
3.31k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
3.31k
    const lzo_bytep m_pos;
51
3.31k
#endif
52
53
3.31k
    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.31k
    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.31k
    *out_len = 0;
81
82
3.31k
    op = out;
83
3.31k
    ip = in;
84
85
3.31k
    NEED_IP(1);
86
3.31k
    if (*ip > 17)
87
1.23k
    {
88
1.23k
        t = *ip++ - 17;
89
1.23k
        if (t < 4)
90
585
            goto match_next;
91
652
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
12.3k
        do *op++ = *ip++; while (--t > 0);
93
652
        goto first_literal_run;
94
1.23k
    }
95
96
2.07k
    for (;;)
97
956k
    {
98
956k
        NEED_IP(3);
99
956k
        t = *ip++;
100
956k
        if (t >= 16)
101
713k
            goto match;
102
        /* a literal run */
103
242k
        if (t == 0)
104
56.0k
        {
105
300k
            while (*ip == 0)
106
244k
            {
107
244k
                t += 255;
108
244k
                ip++;
109
244k
                TEST_IV(t);
110
244k
                NEED_IP(1);
111
244k
            }
112
56.0k
            t += 15 + *ip++;
113
56.0k
        }
114
        /* copy literals */
115
242k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
242k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
242k
        t += 3;
118
242k
        if (t >= 8) do
119
8.38M
        {
120
8.38M
            UA_COPY8(op,ip);
121
8.38M
            op += 8; ip += 8; t -= 8;
122
8.38M
        } while (t >= 8);
123
242k
        if (t >= 4)
124
163k
        {
125
163k
            UA_COPY4(op,ip);
126
163k
            op += 4; ip += 4; t -= 4;
127
163k
        }
128
242k
        if (t > 0)
129
155k
        {
130
155k
            *op++ = *ip++;
131
155k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
155k
        }
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
243k
first_literal_run:
167
168
169
243k
        t = *ip++;
170
243k
        if (t >= 16)
171
241k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
1.34k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
1.34k
        m_pos -= t >> 2;
189
1.34k
        m_pos -= *ip++ << 2;
190
1.34k
#endif
191
1.34k
        TEST_LB(m_pos); NEED_OP(3);
192
1.34k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
1.34k
#endif /* COPY_DICT */
194
1.34k
        goto match_done;
195
196
197
        /* handle matches */
198
565k
        for (;;) {
199
1.52M
match:
200
1.52M
            if (t >= 64)                /* a M2 match */
201
737k
            {
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
737k
#if defined(LZO1X)
222
737k
                m_pos = op - 1;
223
737k
                m_pos -= (t >> 2) & 7;
224
737k
                m_pos -= *ip++ << 3;
225
737k
                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
737k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
737k
                goto copy_match;
251
737k
#endif /* COPY_DICT */
252
737k
            }
253
783k
            else if (t >= 32)           /* a M3 match */
254
594k
            {
255
594k
                t &= 31;
256
594k
                if (t == 0)
257
136k
                {
258
241k
                    while (*ip == 0)
259
104k
                    {
260
104k
                        t += 255;
261
104k
                        ip++;
262
104k
                        TEST_OV(t);
263
104k
                        NEED_IP(1);
264
104k
                    }
265
136k
                    t += 31 + *ip++;
266
136k
                    NEED_IP(2);
267
136k
                }
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
594k
                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
594k
#endif /* COPY_DICT */
290
594k
                ip += 2;
291
594k
            }
292
188k
            else if (t >= 16)           /* a M4 match */
293
104k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
104k
                m_pos = op;
298
104k
                m_pos -= (t & 8) << 11;
299
104k
#endif /* COPY_DICT */
300
104k
                t &= 7;
301
104k
                if (t == 0)
302
46.7k
                {
303
80.2k
                    while (*ip == 0)
304
33.5k
                    {
305
33.5k
                        t += 255;
306
33.5k
                        ip++;
307
33.5k
                        TEST_OV(t);
308
33.5k
                        NEED_IP(1);
309
33.5k
                    }
310
46.7k
                    t += 7 + *ip++;
311
46.7k
                    NEED_IP(2);
312
46.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
104k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
104k
                ip += 2;
335
104k
                if (m_pos == op)
336
3.31k
                    goto eof_found;
337
100k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
100k
#endif /* COPY_DICT */
342
100k
            }
343
84.5k
            else                            /* a M1 match */
344
84.5k
            {
345
#if defined(COPY_DICT)
346
#if defined(LZO1Z)
347
                m_off = 1 + (t << 6) + (*ip++ >> 2);
348
                last_m_off = m_off;
349
#else
350
                m_off = 1 + (t >> 2) + (*ip++ << 2);
351
#endif
352
                NEED_OP(2);
353
                t = 2; COPY_DICT(t,m_off)
354
#else /* !COPY_DICT */
355
#if defined(LZO1Z)
356
                t = 1 + (t << 6) + (*ip++ >> 2);
357
                m_pos = op - t;
358
                last_m_off = t;
359
#else
360
84.5k
                m_pos = op - 1;
361
84.5k
                m_pos -= t >> 2;
362
84.5k
                m_pos -= *ip++ << 2;
363
84.5k
#endif
364
84.5k
                TEST_LB(m_pos); NEED_OP(2);
365
84.5k
                *op++ = *m_pos++; *op++ = *m_pos;
366
84.5k
#endif /* COPY_DICT */
367
84.5k
                goto match_done;
368
84.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
695k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
695k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
695k
            if (op - m_pos >= 8)
381
625k
            {
382
625k
                t += (3 - 1);
383
625k
                if (t >= 8) do
384
5.38M
                {
385
5.38M
                    UA_COPY8(op,m_pos);
386
5.38M
                    op += 8; m_pos += 8; t -= 8;
387
5.38M
                } while (t >= 8);
388
625k
                if (t >= 4)
389
348k
                {
390
348k
                    UA_COPY4(op,m_pos);
391
348k
                    op += 4; m_pos += 4; t -= 4;
392
348k
                }
393
625k
                if (t > 0)
394
434k
                {
395
434k
                    *op++ = m_pos[0];
396
434k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
434k
                }
398
625k
            }
399
70.0k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
70.0k
            {
420
807k
copy_match:
421
807k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
14.1M
                do *op++ = *m_pos++; while (--t > 0);
423
807k
            }
424
425
695k
#endif /* COPY_DICT */
426
427
1.51M
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
1.51M
            t = ip[-2] & 3;
432
1.51M
#endif
433
1.51M
            if (t == 0)
434
954k
                break;
435
436
            /* copy literals */
437
565k
match_next:
438
565k
            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
565k
            *op++ = *ip++;
443
565k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
565k
#endif
445
565k
            t = *ip++;
446
565k
        }
447
0
    }
448
449
3.31k
eof_found:
450
3.31k
    *out_len = pd(op, out);
451
3.31k
    return (ip == ip_end ? LZO_E_OK :
452
3.31k
           (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.07k
}
lzo1y_decompress
Line
Count
Source
42
1.65k
{
43
1.65k
    lzo_bytep op;
44
1.65k
    const lzo_bytep ip;
45
1.65k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
1.65k
    const lzo_bytep m_pos;
51
1.65k
#endif
52
53
1.65k
    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.65k
    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.65k
    *out_len = 0;
81
82
1.65k
    op = out;
83
1.65k
    ip = in;
84
85
1.65k
    NEED_IP(1);
86
1.65k
    if (*ip > 17)
87
1.16k
    {
88
1.16k
        t = *ip++ - 17;
89
1.16k
        if (t < 4)
90
548
            goto match_next;
91
620
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
8.86k
        do *op++ = *ip++; while (--t > 0);
93
620
        goto first_literal_run;
94
1.16k
    }
95
96
486
    for (;;)
97
423k
    {
98
423k
        NEED_IP(3);
99
423k
        t = *ip++;
100
423k
        if (t >= 16)
101
332k
            goto match;
102
        /* a literal run */
103
90.8k
        if (t == 0)
104
19.4k
        {
105
111k
            while (*ip == 0)
106
92.2k
            {
107
92.2k
                t += 255;
108
92.2k
                ip++;
109
92.2k
                TEST_IV(t);
110
92.2k
                NEED_IP(1);
111
92.2k
            }
112
19.4k
            t += 15 + *ip++;
113
19.4k
        }
114
        /* copy literals */
115
90.8k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
90.8k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
90.8k
        t += 3;
118
90.8k
        if (t >= 8) do
119
3.15M
        {
120
3.15M
            UA_COPY8(op,ip);
121
3.15M
            op += 8; ip += 8; t -= 8;
122
3.15M
        } while (t >= 8);
123
90.8k
        if (t >= 4)
124
62.0k
        {
125
62.0k
            UA_COPY4(op,ip);
126
62.0k
            op += 4; ip += 4; t -= 4;
127
62.0k
        }
128
90.8k
        if (t > 0)
129
57.6k
        {
130
57.6k
            *op++ = *ip++;
131
57.6k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
57.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
91.5k
first_literal_run:
167
168
169
91.5k
        t = *ip++;
170
91.5k
        if (t >= 16)
171
89.4k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
2.02k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
2.02k
        m_pos -= t >> 2;
189
2.02k
        m_pos -= *ip++ << 2;
190
2.02k
#endif
191
2.02k
        TEST_LB(m_pos); NEED_OP(3);
192
2.02k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
2.02k
#endif /* COPY_DICT */
194
2.02k
        goto match_done;
195
196
197
        /* handle matches */
198
402k
        for (;;) {
199
824k
match:
200
824k
            if (t >= 64)                /* a M2 match */
201
415k
            {
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
415k
                m_pos -= (t >> 2) & 3;
229
415k
                m_pos -= *ip++ << 2;
230
415k
                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
415k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
415k
                goto copy_match;
251
415k
#endif /* COPY_DICT */
252
415k
            }
253
409k
            else if (t >= 32)           /* a M3 match */
254
269k
            {
255
269k
                t &= 31;
256
269k
                if (t == 0)
257
63.0k
                {
258
115k
                    while (*ip == 0)
259
52.2k
                    {
260
52.2k
                        t += 255;
261
52.2k
                        ip++;
262
52.2k
                        TEST_OV(t);
263
52.2k
                        NEED_IP(1);
264
52.2k
                    }
265
63.0k
                    t += 31 + *ip++;
266
63.0k
                    NEED_IP(2);
267
63.0k
                }
268
#if defined(COPY_DICT)
269
#if defined(LZO1Z)
270
                m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
271
                last_m_off = m_off;
272
#else
273
                m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
274
#endif
275
#else /* !COPY_DICT */
276
#if defined(LZO1Z)
277
                {
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
269k
                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
269k
#endif /* COPY_DICT */
290
269k
                ip += 2;
291
269k
            }
292
139k
            else if (t >= 16)           /* a M4 match */
293
60.6k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
60.6k
                m_pos = op;
298
60.6k
                m_pos -= (t & 8) << 11;
299
60.6k
#endif /* COPY_DICT */
300
60.6k
                t &= 7;
301
60.6k
                if (t == 0)
302
25.4k
                {
303
41.3k
                    while (*ip == 0)
304
15.8k
                    {
305
15.8k
                        t += 255;
306
15.8k
                        ip++;
307
15.8k
                        TEST_OV(t);
308
15.8k
                        NEED_IP(1);
309
15.8k
                    }
310
25.4k
                    t += 7 + *ip++;
311
25.4k
                    NEED_IP(2);
312
25.4k
                }
313
#if defined(COPY_DICT)
314
#if defined(LZO1Z)
315
                m_off += (ip[0] << 6) + (ip[1] >> 2);
316
#else
317
                m_off += (ip[0] >> 2) + (ip[1] << 6);
318
#endif
319
                ip += 2;
320
                if (m_off == 0)
321
                    goto eof_found;
322
                m_off += 0x4000;
323
#if defined(LZO1Z)
324
                last_m_off = m_off;
325
#endif
326
#else /* !COPY_DICT */
327
#if defined(LZO1Z)
328
                m_pos -= (ip[0] << 6) + (ip[1] >> 2);
329
#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
330
60.6k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
60.6k
                ip += 2;
335
60.6k
                if (m_pos == op)
336
1.65k
                    goto eof_found;
337
58.9k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
58.9k
#endif /* COPY_DICT */
342
58.9k
            }
343
79.1k
            else                            /* a M1 match */
344
79.1k
            {
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
79.1k
                m_pos = op - 1;
361
79.1k
                m_pos -= t >> 2;
362
79.1k
                m_pos -= *ip++ << 2;
363
79.1k
#endif
364
79.1k
                TEST_LB(m_pos); NEED_OP(2);
365
79.1k
                *op++ = *m_pos++; *op++ = *m_pos;
366
79.1k
#endif /* COPY_DICT */
367
79.1k
                goto match_done;
368
79.1k
            }
369
370
            /* copy match */
371
#if defined(COPY_DICT)
372
373
            NEED_OP(t+3-1);
374
            t += 3-1; COPY_DICT(t,m_off)
375
376
#else /* !COPY_DICT */
377
378
328k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
328k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
328k
            if (op - m_pos >= 8)
381
305k
            {
382
305k
                t += (3 - 1);
383
305k
                if (t >= 8) do
384
2.60M
                {
385
2.60M
                    UA_COPY8(op,m_pos);
386
2.60M
                    op += 8; m_pos += 8; t -= 8;
387
2.60M
                } while (t >= 8);
388
305k
                if (t >= 4)
389
171k
                {
390
171k
                    UA_COPY4(op,m_pos);
391
171k
                    op += 4; m_pos += 4; t -= 4;
392
171k
                }
393
305k
                if (t > 0)
394
210k
                {
395
210k
                    *op++ = m_pos[0];
396
210k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
210k
                }
398
305k
            }
399
23.5k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
23.5k
            {
420
438k
copy_match:
421
438k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
7.60M
                do *op++ = *m_pos++; while (--t > 0);
423
438k
            }
424
425
328k
#endif /* COPY_DICT */
426
427
825k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
825k
            t = ip[-2] & 3;
432
825k
#endif
433
825k
            if (t == 0)
434
423k
                break;
435
436
            /* copy literals */
437
402k
match_next:
438
402k
            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
402k
            *op++ = *ip++;
443
402k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
402k
#endif
445
402k
            t = *ip++;
446
402k
        }
447
0
    }
448
449
1.65k
eof_found:
450
1.65k
    *out_len = pd(op, out);
451
1.65k
    return (ip == ip_end ? LZO_E_OK :
452
1.65k
           (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
486
}
lzo1z_decompress
Line
Count
Source
42
1.45k
{
43
1.45k
    lzo_bytep op;
44
1.45k
    const lzo_bytep ip;
45
1.45k
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
1.45k
    const lzo_bytep m_pos;
51
1.45k
#endif
52
53
1.45k
    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.45k
#if defined(LZO1Z)
58
1.45k
    lzo_uint last_m_off = 0;
59
1.45k
#endif
60
61
1.45k
    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.45k
    *out_len = 0;
81
82
1.45k
    op = out;
83
1.45k
    ip = in;
84
85
1.45k
    NEED_IP(1);
86
1.45k
    if (*ip > 17)
87
1.42k
    {
88
1.42k
        t = *ip++ - 17;
89
1.42k
        if (t < 4)
90
687
            goto match_next;
91
735
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
9.72k
        do *op++ = *ip++; while (--t > 0);
93
735
        goto first_literal_run;
94
1.42k
    }
95
96
28
    for (;;)
97
335k
    {
98
335k
        NEED_IP(3);
99
335k
        t = *ip++;
100
335k
        if (t >= 16)
101
277k
            goto match;
102
        /* a literal run */
103
58.7k
        if (t == 0)
104
14.6k
        {
105
37.2k
            while (*ip == 0)
106
22.5k
            {
107
22.5k
                t += 255;
108
22.5k
                ip++;
109
22.5k
                TEST_IV(t);
110
22.5k
                NEED_IP(1);
111
22.5k
            }
112
14.6k
            t += 15 + *ip++;
113
14.6k
        }
114
        /* copy literals */
115
58.7k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
58.7k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
58.7k
        t += 3;
118
58.7k
        if (t >= 8) do
119
889k
        {
120
889k
            UA_COPY8(op,ip);
121
889k
            op += 8; ip += 8; t -= 8;
122
889k
        } while (t >= 8);
123
58.7k
        if (t >= 4)
124
40.2k
        {
125
40.2k
            UA_COPY4(op,ip);
126
40.2k
            op += 4; ip += 4; t -= 4;
127
40.2k
        }
128
58.7k
        if (t > 0)
129
38.3k
        {
130
38.3k
            *op++ = *ip++;
131
38.3k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
38.3k
        }
133
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
134
#if !(LZO_OPT_UNALIGNED32)
135
        if (PTR_ALIGNED2_4(op,ip))
136
        {
137
#endif
138
        UA_COPY4(op,ip);
139
        op += 4; ip += 4;
140
        if (--t > 0)
141
        {
142
            if (t >= 4)
143
            {
144
                do {
145
                    UA_COPY4(op,ip);
146
                    op += 4; ip += 4; t -= 4;
147
                } while (t >= 4);
148
                if (t > 0) do *op++ = *ip++; while (--t > 0);
149
            }
150
            else
151
                do *op++ = *ip++; while (--t > 0);
152
        }
153
#if !(LZO_OPT_UNALIGNED32)
154
        }
155
        else
156
#endif
157
#endif
158
#if !(LZO_OPT_UNALIGNED32)
159
        {
160
            *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
161
            do *op++ = *ip++; while (--t > 0);
162
        }
163
#endif
164
165
166
59.5k
first_literal_run:
167
168
169
59.5k
        t = *ip++;
170
59.5k
        if (t >= 16)
171
56.8k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
2.65k
#if defined(LZO1Z)
183
2.65k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
2.65k
        m_pos = op - t;
185
2.65k
        last_m_off = t;
186
#else
187
        m_pos = op - (1 + M2_MAX_OFFSET);
188
        m_pos -= t >> 2;
189
        m_pos -= *ip++ << 2;
190
#endif
191
2.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
475k
        for (;;) {
199
809k
match:
200
809k
            if (t >= 64)                /* a M2 match */
201
337k
            {
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
337k
                    lzo_uint off = t & 0x1f;
234
337k
                    m_pos = op;
235
337k
                    if (off >= 0x1c)
236
14.4k
                    {
237
14.4k
                        assert(last_m_off > 0);
238
14.4k
                        m_pos -= last_m_off;
239
14.4k
                    }
240
323k
                    else
241
323k
                    {
242
323k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
323k
                        m_pos -= off;
244
323k
                        last_m_off = off;
245
323k
                    }
246
337k
                }
247
337k
                t = (t >> 5) - 1;
248
337k
#endif
249
337k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
337k
                goto copy_match;
251
337k
#endif /* COPY_DICT */
252
337k
            }
253
472k
            else if (t >= 32)           /* a M3 match */
254
263k
            {
255
263k
                t &= 31;
256
263k
                if (t == 0)
257
43.9k
                {
258
85.5k
                    while (*ip == 0)
259
41.6k
                    {
260
41.6k
                        t += 255;
261
41.6k
                        ip++;
262
41.6k
                        TEST_OV(t);
263
41.6k
                        NEED_IP(1);
264
41.6k
                    }
265
43.9k
                    t += 31 + *ip++;
266
43.9k
                    NEED_IP(2);
267
43.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
263k
#if defined(LZO1Z)
277
263k
                {
278
263k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
263k
                    m_pos = op - off;
280
263k
                    last_m_off = off;
281
263k
                }
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
263k
#endif /* COPY_DICT */
290
263k
                ip += 2;
291
263k
            }
292
209k
            else if (t >= 16)           /* a M4 match */
293
85.0k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
85.0k
                m_pos = op;
298
85.0k
                m_pos -= (t & 8) << 11;
299
85.0k
#endif /* COPY_DICT */
300
85.0k
                t &= 7;
301
85.0k
                if (t == 0)
302
21.9k
                {
303
33.3k
                    while (*ip == 0)
304
11.3k
                    {
305
11.3k
                        t += 255;
306
11.3k
                        ip++;
307
11.3k
                        TEST_OV(t);
308
11.3k
                        NEED_IP(1);
309
11.3k
                    }
310
21.9k
                    t += 7 + *ip++;
311
21.9k
                    NEED_IP(2);
312
21.9k
                }
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
85.0k
#if defined(LZO1Z)
328
85.0k
                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
85.0k
                ip += 2;
335
85.0k
                if (m_pos == op)
336
1.45k
                    goto eof_found;
337
83.6k
                m_pos -= 0x4000;
338
83.6k
#if defined(LZO1Z)
339
83.6k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
83.6k
#endif
341
83.6k
#endif /* COPY_DICT */
342
83.6k
            }
343
123k
            else                            /* a M1 match */
344
123k
            {
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
123k
#if defined(LZO1Z)
356
123k
                t = 1 + (t << 6) + (*ip++ >> 2);
357
123k
                m_pos = op - t;
358
123k
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
123k
                TEST_LB(m_pos); NEED_OP(2);
365
123k
                *op++ = *m_pos++; *op++ = *m_pos;
366
123k
#endif /* COPY_DICT */
367
123k
                goto match_done;
368
123k
            }
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
346k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
346k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
346k
            if (op - m_pos >= 8)
381
322k
            {
382
322k
                t += (3 - 1);
383
322k
                if (t >= 8) do
384
2.03M
                {
385
2.03M
                    UA_COPY8(op,m_pos);
386
2.03M
                    op += 8; m_pos += 8; t -= 8;
387
2.03M
                } while (t >= 8);
388
322k
                if (t >= 4)
389
150k
                {
390
150k
                    UA_COPY4(op,m_pos);
391
150k
                    op += 4; m_pos += 4; t -= 4;
392
150k
                }
393
322k
                if (t > 0)
394
242k
                {
395
242k
                    *op++ = m_pos[0];
396
242k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
242k
                }
398
322k
            }
399
24.7k
            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
24.7k
            {
420
362k
copy_match:
421
362k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
5.67M
                do *op++ = *m_pos++; while (--t > 0);
423
362k
            }
424
425
346k
#endif /* COPY_DICT */
426
427
811k
match_done:
428
811k
#if defined(LZO1Z)
429
811k
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
811k
            if (t == 0)
434
335k
                break;
435
436
            /* copy literals */
437
475k
match_next:
438
475k
            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
475k
            *op++ = *ip++;
443
475k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
475k
#endif
445
475k
            t = *ip++;
446
475k
        }
447
0
    }
448
449
1.45k
eof_found:
450
1.45k
    *out_len = pd(op, out);
451
1.45k
    return (ip == ip_end ? LZO_E_OK :
452
1.45k
           (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
28
}
lzo1x_decompress_safe
Line
Count
Source
42
599
{
43
599
    lzo_bytep op;
44
599
    const lzo_bytep ip;
45
599
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
599
    const lzo_bytep m_pos;
51
599
#endif
52
53
599
    const lzo_bytep const ip_end = in + in_len;
54
599
#if defined(HAVE_ANY_OP)
55
599
    lzo_bytep const op_end = out + *out_len;
56
599
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
599
    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
599
    *out_len = 0;
81
82
599
    op = out;
83
599
    ip = in;
84
85
599
    NEED_IP(1);
86
599
    if (*ip > 17)
87
338
    {
88
338
        t = *ip++ - 17;
89
338
        if (t < 4)
90
267
            goto match_next;
91
71
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
1.93k
        do *op++ = *ip++; while (--t > 0);
93
57
        goto first_literal_run;
94
71
    }
95
96
261
    for (;;)
97
30.1k
    {
98
30.1k
        NEED_IP(3);
99
30.1k
        t = *ip++;
100
30.1k
        if (t >= 16)
101
19.2k
            goto match;
102
        /* a literal run */
103
10.8k
        if (t == 0)
104
3.26k
        {
105
3.39M
            while (*ip == 0)
106
3.39M
            {
107
3.39M
                t += 255;
108
3.39M
                ip++;
109
3.39M
                TEST_IV(t);
110
3.39M
                NEED_IP(1);
111
3.39M
            }
112
3.24k
            t += 15 + *ip++;
113
3.24k
        }
114
        /* copy literals */
115
10.8k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
10.6k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
10.6k
        t += 3;
118
10.6k
        if (t >= 8) do
119
218k
        {
120
218k
            UA_COPY8(op,ip);
121
218k
            op += 8; ip += 8; t -= 8;
122
218k
        } while (t >= 8);
123
10.6k
        if (t >= 4)
124
7.17k
        {
125
7.17k
            UA_COPY4(op,ip);
126
7.17k
            op += 4; ip += 4; t -= 4;
127
7.17k
        }
128
10.6k
        if (t > 0)
129
7.96k
        {
130
7.96k
            *op++ = *ip++;
131
7.96k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
7.96k
        }
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
10.7k
first_literal_run:
167
168
169
10.7k
        t = *ip++;
170
10.7k
        if (t >= 16)
171
4.77k
            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.96k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
5.96k
        m_pos -= t >> 2;
189
5.96k
        m_pos -= *ip++ << 2;
190
5.96k
#endif
191
5.96k
        TEST_LB(m_pos); NEED_OP(3);
192
5.91k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
5.91k
#endif /* COPY_DICT */
194
5.91k
        goto match_done;
195
196
197
        /* handle matches */
198
66.9k
        for (;;) {
199
90.9k
match:
200
90.9k
            if (t >= 64)                /* a M2 match */
201
38.1k
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
38.1k
#if defined(LZO1X)
222
38.1k
                m_pos = op - 1;
223
38.1k
                m_pos -= (t >> 2) & 7;
224
38.1k
                m_pos -= *ip++ << 3;
225
38.1k
                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
38.1k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
38.0k
                goto copy_match;
251
38.1k
#endif /* COPY_DICT */
252
38.1k
            }
253
52.8k
            else if (t >= 32)           /* a M3 match */
254
24.5k
            {
255
24.5k
                t &= 31;
256
24.5k
                if (t == 0)
257
3.45k
                {
258
1.17M
                    while (*ip == 0)
259
1.17M
                    {
260
1.17M
                        t += 255;
261
1.17M
                        ip++;
262
1.17M
                        TEST_OV(t);
263
1.17M
                        NEED_IP(1);
264
1.17M
                    }
265
3.43k
                    t += 31 + *ip++;
266
3.43k
                    NEED_IP(2);
267
3.43k
                }
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
24.5k
                m_pos = op - 1;
284
24.5k
                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
24.5k
#endif /* COPY_DICT */
290
24.5k
                ip += 2;
291
24.5k
            }
292
28.2k
            else if (t >= 16)           /* a M4 match */
293
7.88k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
7.88k
                m_pos = op;
298
7.88k
                m_pos -= (t & 8) << 11;
299
7.88k
#endif /* COPY_DICT */
300
7.88k
                t &= 7;
301
7.88k
                if (t == 0)
302
1.98k
                {
303
1.84M
                    while (*ip == 0)
304
1.84M
                    {
305
1.84M
                        t += 255;
306
1.84M
                        ip++;
307
1.84M
                        TEST_OV(t);
308
1.84M
                        NEED_IP(1);
309
1.84M
                    }
310
1.96k
                    t += 7 + *ip++;
311
1.96k
                    NEED_IP(2);
312
1.96k
                }
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
7.85k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
7.85k
                ip += 2;
335
7.85k
                if (m_pos == op)
336
16
                    goto eof_found;
337
7.83k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
7.83k
#endif /* COPY_DICT */
342
7.83k
            }
343
20.4k
            else                            /* a M1 match */
344
20.4k
            {
345
#if defined(COPY_DICT)
346
#if defined(LZO1Z)
347
                m_off = 1 + (t << 6) + (*ip++ >> 2);
348
                last_m_off = m_off;
349
#else
350
                m_off = 1 + (t >> 2) + (*ip++ << 2);
351
#endif
352
                NEED_OP(2);
353
                t = 2; COPY_DICT(t,m_off)
354
#else /* !COPY_DICT */
355
#if defined(LZO1Z)
356
                t = 1 + (t << 6) + (*ip++ >> 2);
357
                m_pos = op - t;
358
                last_m_off = t;
359
#else
360
20.4k
                m_pos = op - 1;
361
20.4k
                m_pos -= t >> 2;
362
20.4k
                m_pos -= *ip++ << 2;
363
20.4k
#endif
364
20.4k
                TEST_LB(m_pos); NEED_OP(2);
365
20.4k
                *op++ = *m_pos++; *op++ = *m_pos;
366
20.4k
#endif /* COPY_DICT */
367
20.4k
                goto match_done;
368
20.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
32.3k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
32.2k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
32.2k
            if (op - m_pos >= 8)
381
29.0k
            {
382
29.0k
                t += (3 - 1);
383
29.0k
                if (t >= 8) do
384
614k
                {
385
614k
                    UA_COPY8(op,m_pos);
386
614k
                    op += 8; m_pos += 8; t -= 8;
387
614k
                } while (t >= 8);
388
29.0k
                if (t >= 4)
389
16.5k
                {
390
16.5k
                    UA_COPY4(op,m_pos);
391
16.5k
                    op += 4; m_pos += 4; t -= 4;
392
16.5k
                }
393
29.0k
                if (t > 0)
394
22.8k
                {
395
22.8k
                    *op++ = m_pos[0];
396
22.8k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
22.8k
                }
398
29.0k
            }
399
3.27k
            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.27k
            {
420
41.3k
copy_match:
421
41.3k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
10.1M
                do *op++ = *m_pos++; while (--t > 0);
423
41.3k
            }
424
425
32.2k
#endif /* COPY_DICT */
426
427
96.6k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
96.6k
            t = ip[-2] & 3;
432
96.6k
#endif
433
96.6k
            if (t == 0)
434
29.9k
                break;
435
436
            /* copy literals */
437
67.0k
match_next:
438
67.0k
            assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
439
#if 0
440
            do *op++ = *ip++; while (--t > 0);
441
#else
442
66.9k
            *op++ = *ip++;
443
66.9k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
66.9k
#endif
445
66.9k
            t = *ip++;
446
66.9k
        }
447
0
    }
448
449
16
eof_found:
450
16
    *out_len = pd(op, out);
451
16
    return (ip == ip_end ? LZO_E_OK :
452
16
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
393
input_overrun:
457
393
    *out_len = pd(op, out);
458
393
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
49
output_overrun:
463
49
    *out_len = pd(op, out);
464
49
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
141
lookbehind_overrun:
469
141
    *out_len = pd(op, out);
470
141
    return LZO_E_LOOKBEHIND_OVERRUN;
471
261
#endif
472
261
}
lzo1y_decompress_safe
Line
Count
Source
42
650
{
43
650
    lzo_bytep op;
44
650
    const lzo_bytep ip;
45
650
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
650
    const lzo_bytep m_pos;
51
650
#endif
52
53
650
    const lzo_bytep const ip_end = in + in_len;
54
650
#if defined(HAVE_ANY_OP)
55
650
    lzo_bytep const op_end = out + *out_len;
56
650
#endif
57
#if defined(LZO1Z)
58
    lzo_uint last_m_off = 0;
59
#endif
60
61
650
    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
650
    *out_len = 0;
81
82
650
    op = out;
83
650
    ip = in;
84
85
650
    NEED_IP(1);
86
650
    if (*ip > 17)
87
360
    {
88
360
        t = *ip++ - 17;
89
360
        if (t < 4)
90
259
            goto match_next;
91
101
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
4.32k
        do *op++ = *ip++; while (--t > 0);
93
85
        goto first_literal_run;
94
101
    }
95
96
290
    for (;;)
97
29.1k
    {
98
29.1k
        NEED_IP(3);
99
29.1k
        t = *ip++;
100
29.1k
        if (t >= 16)
101
16.4k
            goto match;
102
        /* a literal run */
103
12.6k
        if (t == 0)
104
6.19k
        {
105
11.8M
            while (*ip == 0)
106
11.7M
            {
107
11.7M
                t += 255;
108
11.7M
                ip++;
109
11.7M
                TEST_IV(t);
110
11.7M
                NEED_IP(1);
111
11.7M
            }
112
6.16k
            t += 15 + *ip++;
113
6.16k
        }
114
        /* copy literals */
115
12.6k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
12.4k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
12.4k
        t += 3;
118
12.4k
        if (t >= 8) do
119
472k
        {
120
472k
            UA_COPY8(op,ip);
121
472k
            op += 8; ip += 8; t -= 8;
122
472k
        } while (t >= 8);
123
12.4k
        if (t >= 4)
124
8.37k
        {
125
8.37k
            UA_COPY4(op,ip);
126
8.37k
            op += 4; ip += 4; t -= 4;
127
8.37k
        }
128
12.4k
        if (t > 0)
129
9.18k
        {
130
9.18k
            *op++ = *ip++;
131
9.18k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
9.18k
        }
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
12.5k
first_literal_run:
167
168
169
12.5k
        t = *ip++;
170
12.5k
        if (t >= 16)
171
6.08k
            goto match;
172
#if defined(COPY_DICT)
173
#if defined(LZO1Z)
174
        m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
175
        last_m_off = m_off;
176
#else
177
        m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
178
#endif
179
        NEED_OP(3);
180
        t = 3; COPY_DICT(t,m_off)
181
#else /* !COPY_DICT */
182
#if defined(LZO1Z)
183
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
        m_pos = op - t;
185
        last_m_off = t;
186
#else
187
6.45k
        m_pos = op - (1 + M2_MAX_OFFSET);
188
6.45k
        m_pos -= t >> 2;
189
6.45k
        m_pos -= *ip++ << 2;
190
6.45k
#endif
191
6.45k
        TEST_LB(m_pos); NEED_OP(3);
192
6.40k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
6.40k
#endif /* COPY_DICT */
194
6.40k
        goto match_done;
195
196
197
        /* handle matches */
198
49.1k
        for (;;) {
199
71.7k
match:
200
71.7k
            if (t >= 64)                /* a M2 match */
201
33.6k
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
#if defined(LZO1X)
222
                m_pos = op - 1;
223
                m_pos -= (t >> 2) & 7;
224
                m_pos -= *ip++ << 3;
225
                t = (t >> 5) - 1;
226
#elif defined(LZO1Y)
227
                m_pos = op - 1;
228
33.6k
                m_pos -= (t >> 2) & 3;
229
33.6k
                m_pos -= *ip++ << 2;
230
33.6k
                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
33.6k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
33.5k
                goto copy_match;
251
33.5k
#endif /* COPY_DICT */
252
33.5k
            }
253
38.1k
            else if (t >= 32)           /* a M3 match */
254
15.4k
            {
255
15.4k
                t &= 31;
256
15.4k
                if (t == 0)
257
1.99k
                {
258
1.11M
                    while (*ip == 0)
259
1.11M
                    {
260
1.11M
                        t += 255;
261
1.11M
                        ip++;
262
1.11M
                        TEST_OV(t);
263
1.11M
                        NEED_IP(1);
264
1.11M
                    }
265
1.98k
                    t += 31 + *ip++;
266
1.98k
                    NEED_IP(2);
267
1.98k
                }
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
15.4k
                m_pos = op - 1;
284
15.4k
                m_pos -= UA_GET_LE16(ip) >> 2;
285
#else
286
                m_pos = op - 1;
287
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
288
#endif
289
15.4k
#endif /* COPY_DICT */
290
15.4k
                ip += 2;
291
15.4k
            }
292
22.6k
            else if (t >= 16)           /* a M4 match */
293
5.11k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
5.11k
                m_pos = op;
298
5.11k
                m_pos -= (t & 8) << 11;
299
5.11k
#endif /* COPY_DICT */
300
5.11k
                t &= 7;
301
5.11k
                if (t == 0)
302
1.43k
                {
303
1.85M
                    while (*ip == 0)
304
1.84M
                    {
305
1.84M
                        t += 255;
306
1.84M
                        ip++;
307
1.84M
                        TEST_OV(t);
308
1.84M
                        NEED_IP(1);
309
1.84M
                    }
310
1.41k
                    t += 7 + *ip++;
311
1.41k
                    NEED_IP(2);
312
1.41k
                }
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
5.07k
                m_pos -= UA_GET_LE16(ip) >> 2;
331
#else
332
                m_pos -= (ip[0] >> 2) + (ip[1] << 6);
333
#endif
334
5.07k
                ip += 2;
335
5.07k
                if (m_pos == op)
336
16
                    goto eof_found;
337
5.06k
                m_pos -= 0x4000;
338
#if defined(LZO1Z)
339
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
#endif
341
5.06k
#endif /* COPY_DICT */
342
5.06k
            }
343
17.5k
            else                            /* a M1 match */
344
17.5k
            {
345
#if defined(COPY_DICT)
346
#if defined(LZO1Z)
347
                m_off = 1 + (t << 6) + (*ip++ >> 2);
348
                last_m_off = m_off;
349
#else
350
                m_off = 1 + (t >> 2) + (*ip++ << 2);
351
#endif
352
                NEED_OP(2);
353
                t = 2; COPY_DICT(t,m_off)
354
#else /* !COPY_DICT */
355
#if defined(LZO1Z)
356
                t = 1 + (t << 6) + (*ip++ >> 2);
357
                m_pos = op - t;
358
                last_m_off = t;
359
#else
360
17.5k
                m_pos = op - 1;
361
17.5k
                m_pos -= t >> 2;
362
17.5k
                m_pos -= *ip++ << 2;
363
17.5k
#endif
364
17.5k
                TEST_LB(m_pos); NEED_OP(2);
365
17.5k
                *op++ = *m_pos++; *op++ = *m_pos;
366
17.5k
#endif /* COPY_DICT */
367
17.5k
                goto match_done;
368
17.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
20.4k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
20.3k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
20.3k
            if (op - m_pos >= 8)
381
17.9k
            {
382
17.9k
                t += (3 - 1);
383
17.9k
                if (t >= 8) do
384
519k
                {
385
519k
                    UA_COPY8(op,m_pos);
386
519k
                    op += 8; m_pos += 8; t -= 8;
387
519k
                } while (t >= 8);
388
17.9k
                if (t >= 4)
389
10.0k
                {
390
10.0k
                    UA_COPY4(op,m_pos);
391
10.0k
                    op += 4; m_pos += 4; t -= 4;
392
10.0k
                }
393
17.9k
                if (t > 0)
394
14.1k
                {
395
14.1k
                    *op++ = m_pos[0];
396
14.1k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
14.1k
                }
398
17.9k
            }
399
2.43k
            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.43k
            {
420
36.0k
copy_match:
421
36.0k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
10.3M
                do *op++ = *m_pos++; while (--t > 0);
423
36.0k
            }
424
425
20.3k
#endif /* COPY_DICT */
426
427
77.9k
match_done:
428
#if defined(LZO1Z)
429
            t = ip[-1] & 3;
430
#else
431
77.9k
            t = ip[-2] & 3;
432
77.9k
#endif
433
77.9k
            if (t == 0)
434
28.9k
                break;
435
436
            /* copy literals */
437
49.2k
match_next:
438
49.2k
            assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
439
#if 0
440
            do *op++ = *ip++; while (--t > 0);
441
#else
442
49.1k
            *op++ = *ip++;
443
49.1k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
49.1k
#endif
445
49.1k
            t = *ip++;
446
49.1k
        }
447
0
    }
448
449
16
eof_found:
450
16
    *out_len = pd(op, out);
451
16
    return (ip == ip_end ? LZO_E_OK :
452
16
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
409
input_overrun:
457
409
    *out_len = pd(op, out);
458
409
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
51
output_overrun:
463
51
    *out_len = pd(op, out);
464
51
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
174
lookbehind_overrun:
469
174
    *out_len = pd(op, out);
470
174
    return LZO_E_LOOKBEHIND_OVERRUN;
471
290
#endif
472
290
}
lzo1z_decompress_safe
Line
Count
Source
42
639
{
43
639
    lzo_bytep op;
44
639
    const lzo_bytep ip;
45
639
    lzo_uint t;
46
#if defined(COPY_DICT)
47
    lzo_uint m_off;
48
    const lzo_bytep dict_end;
49
#else
50
639
    const lzo_bytep m_pos;
51
639
#endif
52
53
639
    const lzo_bytep const ip_end = in + in_len;
54
639
#if defined(HAVE_ANY_OP)
55
639
    lzo_bytep const op_end = out + *out_len;
56
639
#endif
57
639
#if defined(LZO1Z)
58
639
    lzo_uint last_m_off = 0;
59
639
#endif
60
61
639
    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
639
    *out_len = 0;
81
82
639
    op = out;
83
639
    ip = in;
84
85
639
    NEED_IP(1);
86
639
    if (*ip > 17)
87
372
    {
88
372
        t = *ip++ - 17;
89
372
        if (t < 4)
90
292
            goto match_next;
91
80
        assert(t > 0); NEED_OP(t); NEED_IP(t+3);
92
2.47k
        do *op++ = *ip++; while (--t > 0);
93
67
        goto first_literal_run;
94
80
    }
95
96
267
    for (;;)
97
24.5k
    {
98
24.5k
        NEED_IP(3);
99
24.4k
        t = *ip++;
100
24.4k
        if (t >= 16)
101
15.0k
            goto match;
102
        /* a literal run */
103
9.37k
        if (t == 0)
104
3.70k
        {
105
2.40M
            while (*ip == 0)
106
2.39M
            {
107
2.39M
                t += 255;
108
2.39M
                ip++;
109
2.39M
                TEST_IV(t);
110
2.39M
                NEED_IP(1);
111
2.39M
            }
112
3.68k
            t += 15 + *ip++;
113
3.68k
        }
114
        /* copy literals */
115
9.35k
        assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
116
9.19k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
117
9.19k
        t += 3;
118
9.19k
        if (t >= 8) do
119
270k
        {
120
270k
            UA_COPY8(op,ip);
121
270k
            op += 8; ip += 8; t -= 8;
122
270k
        } while (t >= 8);
123
9.19k
        if (t >= 4)
124
5.16k
        {
125
5.16k
            UA_COPY4(op,ip);
126
5.16k
            op += 4; ip += 4; t -= 4;
127
5.16k
        }
128
9.19k
        if (t > 0)
129
5.51k
        {
130
5.51k
            *op++ = *ip++;
131
5.51k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
132
5.51k
        }
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
9.25k
first_literal_run:
167
168
169
9.25k
        t = *ip++;
170
9.25k
        if (t >= 16)
171
4.89k
            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.36k
#if defined(LZO1Z)
183
4.36k
        t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
184
4.36k
        m_pos = op - t;
185
4.36k
        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.36k
        TEST_LB(m_pos); NEED_OP(3);
192
4.31k
        *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
193
4.31k
#endif /* COPY_DICT */
194
4.31k
        goto match_done;
195
196
197
        /* handle matches */
198
28.4k
        for (;;) {
199
48.3k
match:
200
48.3k
            if (t >= 64)                /* a M2 match */
201
25.4k
            {
202
#if defined(COPY_DICT)
203
#if defined(LZO1X)
204
                m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
205
                t = (t >> 5) - 1;
206
#elif defined(LZO1Y)
207
                m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
208
                t = (t >> 4) - 3;
209
#elif defined(LZO1Z)
210
                m_off = t & 0x1f;
211
                if (m_off >= 0x1c)
212
                    m_off = last_m_off;
213
                else
214
                {
215
                    m_off = 1 + (m_off << 6) + (*ip++ >> 2);
216
                    last_m_off = m_off;
217
                }
218
                t = (t >> 5) - 1;
219
#endif
220
#else /* !COPY_DICT */
221
#if defined(LZO1X)
222
                m_pos = op - 1;
223
                m_pos -= (t >> 2) & 7;
224
                m_pos -= *ip++ << 3;
225
                t = (t >> 5) - 1;
226
#elif defined(LZO1Y)
227
                m_pos = op - 1;
228
                m_pos -= (t >> 2) & 3;
229
                m_pos -= *ip++ << 2;
230
                t = (t >> 4) - 3;
231
#elif defined(LZO1Z)
232
                {
233
25.4k
                    lzo_uint off = t & 0x1f;
234
25.4k
                    m_pos = op;
235
25.4k
                    if (off >= 0x1c)
236
3.83k
                    {
237
3.83k
                        assert(last_m_off > 0);
238
3.83k
                        m_pos -= last_m_off;
239
3.83k
                    }
240
21.6k
                    else
241
21.6k
                    {
242
21.6k
                        off = 1 + (off << 6) + (*ip++ >> 2);
243
21.6k
                        m_pos -= off;
244
21.6k
                        last_m_off = off;
245
21.6k
                    }
246
25.4k
                }
247
25.4k
                t = (t >> 5) - 1;
248
25.4k
#endif
249
25.4k
                TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
250
25.4k
                goto copy_match;
251
25.4k
#endif /* COPY_DICT */
252
25.4k
            }
253
22.9k
            else if (t >= 32)           /* a M3 match */
254
14.7k
            {
255
14.7k
                t &= 31;
256
14.7k
                if (t == 0)
257
1.64k
                {
258
2.16M
                    while (*ip == 0)
259
2.16M
                    {
260
2.16M
                        t += 255;
261
2.16M
                        ip++;
262
2.16M
                        TEST_OV(t);
263
2.16M
                        NEED_IP(1);
264
2.16M
                    }
265
1.62k
                    t += 31 + *ip++;
266
1.62k
                    NEED_IP(2);
267
1.62k
                }
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
14.7k
#if defined(LZO1Z)
277
14.7k
                {
278
14.7k
                    lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
279
14.7k
                    m_pos = op - off;
280
14.7k
                    last_m_off = off;
281
14.7k
                }
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
14.7k
#endif /* COPY_DICT */
290
14.7k
                ip += 2;
291
14.7k
            }
292
8.17k
            else if (t >= 16)           /* a M4 match */
293
4.32k
            {
294
#if defined(COPY_DICT)
295
                m_off = (t & 8) << 11;
296
#else /* !COPY_DICT */
297
4.32k
                m_pos = op;
298
4.32k
                m_pos -= (t & 8) << 11;
299
4.32k
#endif /* COPY_DICT */
300
4.32k
                t &= 7;
301
4.32k
                if (t == 0)
302
2.62k
                {
303
913k
                    while (*ip == 0)
304
911k
                    {
305
911k
                        t += 255;
306
911k
                        ip++;
307
911k
                        TEST_OV(t);
308
911k
                        NEED_IP(1);
309
911k
                    }
310
2.60k
                    t += 7 + *ip++;
311
2.60k
                    NEED_IP(2);
312
2.60k
                }
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
4.30k
#if defined(LZO1Z)
328
4.30k
                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
4.30k
                ip += 2;
335
4.30k
                if (m_pos == op)
336
17
                    goto eof_found;
337
4.28k
                m_pos -= 0x4000;
338
4.28k
#if defined(LZO1Z)
339
4.28k
                last_m_off = pd((const lzo_bytep)op, m_pos);
340
4.28k
#endif
341
4.28k
#endif /* COPY_DICT */
342
4.28k
            }
343
3.84k
            else                            /* a M1 match */
344
3.84k
            {
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
3.84k
#if defined(LZO1Z)
356
3.84k
                t = 1 + (t << 6) + (*ip++ >> 2);
357
3.84k
                m_pos = op - t;
358
3.84k
                last_m_off = t;
359
#else
360
                m_pos = op - 1;
361
                m_pos -= t >> 2;
362
                m_pos -= *ip++ << 2;
363
#endif
364
3.84k
                TEST_LB(m_pos); NEED_OP(2);
365
3.83k
                *op++ = *m_pos++; *op++ = *m_pos;
366
3.83k
#endif /* COPY_DICT */
367
3.83k
                goto match_done;
368
3.83k
            }
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
18.9k
            TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
379
18.9k
#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
380
18.9k
            if (op - m_pos >= 8)
381
17.4k
            {
382
17.4k
                t += (3 - 1);
383
17.4k
                if (t >= 8) do
384
808k
                {
385
808k
                    UA_COPY8(op,m_pos);
386
808k
                    op += 8; m_pos += 8; t -= 8;
387
808k
                } while (t >= 8);
388
17.4k
                if (t >= 4)
389
10.2k
                {
390
10.2k
                    UA_COPY4(op,m_pos);
391
10.2k
                    op += 4; m_pos += 4; t -= 4;
392
10.2k
                }
393
17.4k
                if (t > 0)
394
15.8k
                {
395
15.8k
                    *op++ = m_pos[0];
396
15.8k
                    if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } }
397
15.8k
                }
398
17.4k
            }
399
1.42k
            else
400
#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
401
#if !(LZO_OPT_UNALIGNED32)
402
            if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
403
            {
404
                assert((op - m_pos) >= 4);  /* both pointers are aligned */
405
#else
406
            if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
407
            {
408
#endif
409
                UA_COPY4(op,m_pos);
410
                op += 4; m_pos += 4; t -= 4 - (3 - 1);
411
                do {
412
                    UA_COPY4(op,m_pos);
413
                    op += 4; m_pos += 4; t -= 4;
414
                } while (t >= 4);
415
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
416
            }
417
            else
418
#endif
419
1.42k
            {
420
26.8k
copy_match:
421
26.8k
                *op++ = *m_pos++; *op++ = *m_pos++;
422
6.51M
                do *op++ = *m_pos++; while (--t > 0);
423
26.8k
            }
424
425
18.9k
#endif /* COPY_DICT */
426
427
52.4k
match_done:
428
52.4k
#if defined(LZO1Z)
429
52.4k
            t = ip[-1] & 3;
430
#else
431
            t = ip[-2] & 3;
432
#endif
433
52.4k
            if (t == 0)
434
24.2k
                break;
435
436
            /* copy literals */
437
28.5k
match_next:
438
28.5k
            assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
439
#if 0
440
            do *op++ = *ip++; while (--t > 0);
441
#else
442
28.4k
            *op++ = *ip++;
443
28.4k
            if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
444
28.4k
#endif
445
28.4k
            t = *ip++;
446
28.4k
        }
447
0
    }
448
449
17
eof_found:
450
17
    *out_len = pd(op, out);
451
17
    return (ip == ip_end ? LZO_E_OK :
452
17
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
453
454
455
0
#if defined(HAVE_NEED_IP)
456
412
input_overrun:
457
412
    *out_len = pd(op, out);
458
412
    return LZO_E_INPUT_OVERRUN;
459
0
#endif
460
461
0
#if defined(HAVE_NEED_OP)
462
45
output_overrun:
463
45
    *out_len = pd(op, out);
464
45
    return LZO_E_OUTPUT_OVERRUN;
465
0
#endif
466
467
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
468
165
lookbehind_overrun:
469
165
    *out_len = pd(op, out);
470
165
    return LZO_E_LOOKBEHIND_OVERRUN;
471
267
#endif
472
267
}
473
474
475
/* vim:set ts=4 sw=4 et: */