~ubuntu-branches/ubuntu/precise/arj/precise-security

« back to all changes in this revision

Viewing changes to decode.c

  • Committer: Bazaar Package Importer
  • Author(s): Guillem Jover
  • Date: 2004-06-27 08:07:09 UTC
  • Revision ID: james.westby@ubuntu.com-20040627080709-1gkxm72ex66gkwe4
Tags: upstream-3.10.21
ImportĀ upstreamĀ versionĀ 3.10.21

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: decode.c,v 1.3 2003/04/12 16:15:59 andrew_belov Exp $
 
3
 * ---------------------------------------------------------------------------
 
4
 * The data decompression procedures are located in this module.
 
5
 *
 
6
 */
 
7
 
 
8
#include <setjmp.h>
 
9
 
 
10
#include "arj.h"
 
11
 
 
12
DEBUGHDR(__FILE__)                      /* Debug information block */
 
13
 
 
14
/* Delays for errors with garbled files */
 
15
 
 
16
#if SFX_LEVEL>=ARJ
 
17
 #define BADTABLE_G_DELAY          2
 
18
#else
 
19
 #define BADTABLE_G_DELAY          5
 
20
#endif
 
21
 
 
22
/* Local variables */
 
23
 
 
24
static jmp_buf decode_proc;             /* Jump buffer for decoding procedure */
 
25
 
 
26
#if SFX_LEVEL>=ARJSFXV
 
27
unsigned short FAR *c_table;
 
28
unsigned short FAR *pt_table;
 
29
#else
 
30
unsigned short c_table[CTABLESIZE];
 
31
unsigned short pt_table[PTABLESIZE];
 
32
#endif
 
33
short blocksize;
 
34
static long count;
 
35
 
 
36
/* Fills the input buffer */
 
37
 
 
38
void fillbuf(int n)
 
39
{
 
40
 #ifdef DEBUG
 
41
  int bbrc;
 
42
 #endif
 
43
 
 
44
 while(bitcount<n)
 
45
 {
 
46
  bitbuf=(bitbuf<<bitcount)|((unsigned int)byte_buf>>(8-bitcount));
 
47
  n-=bitcount;
 
48
  if(compsize>0)
 
49
  {
 
50
   compsize--;
 
51
   if(file_packing)
 
52
   {
 
53
    /* This slows the things down quite a lot so we won't put this in the
 
54
       release version (despite of what ARJ Software Inc. does in v 3.04!) */
 
55
    #ifdef DEBUG
 
56
     errno=0;                           /* ASR fix 11/10/2000 -- POSIX/MS C */
 
57
     bbrc=fgetc(aistream);
 
58
     if(errno!=0)
 
59
      msg_cprintf(0, M_DECODE_CRIT_ERROR);
 
60
     if(bbrc<0)
 
61
      msg_cprintf(0, M_DECODE_EOF);
 
62
     byte_buf=(unsigned char)bbrc;
 
63
    #else
 
64
     byte_buf=(unsigned char)fgetc(aistream);
 
65
    #endif
 
66
   }
 
67
   else                                 /* ASR improvement for RAM-to-RAM */
 
68
   {
 
69
    byte_buf=*packblock_ptr++;
 
70
    packmem_remain--;
 
71
   }
 
72
   if(file_garbled)
 
73
    garble_decode(&byte_buf, 1);
 
74
  }
 
75
  else
 
76
   byte_buf=0;
 
77
  bitcount=8;
 
78
 }
 
79
 bitcount-=n;
 
80
 bitbuf=(bitbuf<<n)|(byte_buf>>(8-n));
 
81
 byte_buf<<=n;
 
82
}
 
83
 
 
84
/* Reads a series of bits into the input buffer */
 
85
 
 
86
static int getbits(int n)
 
87
{
 
88
 int rc;
 
89
 
 
90
 rc=bitbuf>>(CODE_BIT-n);
 
91
 fillbuf(n);
 
92
 return(rc);
 
93
}
 
94
 
 
95
/* Creates a table for decoding */
 
96
 
 
97
#if SFX_LEVEL>=ARJSFXV
 
98
static void NEAR make_table(int nchar, unsigned char *bitlen, int tablebits, unsigned short FAR *table, int tablesize)
 
99
#else
 
100
static void NEAR make_table(int nchar, unsigned char *bitlen, int tablebits, unsigned short *table, int tablesize)
 
101
#endif
 
102
{
 
103
 unsigned short count[17], weight[17], start[18];
 
104
#if SFX_LEVEL>=ARJSFXV
 
105
 unsigned short FAR *p;
 
106
#else
 
107
 unsigned short *p;
 
108
#endif
 
109
 unsigned int i, k, len, ch, jutbits, avail, nextcode, mask;
 
110
 
 
111
 for(i=1; i<=16; i++)
 
112
  count[i]=0;
 
113
 for(i=0; (int)i<nchar; i++)
 
114
  count[bitlen[i]]++;
 
115
 start[1]=0;
 
116
 for(i=1; i<=16; i++)
 
117
  start[i+1]=start[i]+(count[i]<<(16-i));
 
118
 if(start[17]!=(unsigned short)(1<<16))
 
119
 {
 
120
  if(file_garbled)
 
121
  {
 
122
   arj_delay(BADTABLE_G_DELAY);
 
123
   #if SFX_LEVEL>=ARJSFXV
 
124
    msg_cprintf(H_ERR, M_BADTABLE_G);
 
125
   #else
 
126
    error(M_BADTABLE_G);
 
127
   #endif
 
128
  }
 
129
  else
 
130
   #if SFX_LEVEL>=ARJSFXV
 
131
    msg_cprintf(H_ERR, M_BADTABLE);
 
132
   #else
 
133
    error(M_BADTABLE);
 
134
   #endif
 
135
  #if SFX_LEVEL>=ARJSFXV
 
136
   longjmp(decode_proc, 1);
 
137
  #endif
 
138
 }
 
139
 jutbits=16-tablebits;
 
140
 for(i=1; (int)i<=tablebits; i++)
 
141
 {
 
142
  start[i]>>=jutbits;
 
143
  weight[i]=1<<(tablebits-i);
 
144
 }
 
145
 while(i<=16)
 
146
 {
 
147
  weight[i]=1<<(16-i);
 
148
  i++;
 
149
 }
 
150
 i=start[tablebits+1]>>jutbits;
 
151
 if(i!=(unsigned short)(1<<16))
 
152
 {
 
153
  k=1<<tablebits;
 
154
  while(i!=k)
 
155
   table[i++]=0;
 
156
 }
 
157
 avail=nchar;
 
158
 mask=1<<(15-tablebits);
 
159
 for(ch=0; (int)ch<nchar; ch++)
 
160
 {
 
161
  if((len=bitlen[ch])!=0)
 
162
  {
 
163
   k=start[len];
 
164
   nextcode=k+weight[len];
 
165
   if((int)len<=tablebits)
 
166
   {
 
167
    if(nextcode>(unsigned int)tablesize)
 
168
    {
 
169
     if(file_garbled)
 
170
     {
 
171
      arj_delay(BADTABLE_G_DELAY);
 
172
      #if SFX_LEVEL>=ARJSFXV
 
173
       msg_cprintf(H_ERR, M_BADTABLE_G);
 
174
      #else
 
175
       error(M_BADTABLE_G);
 
176
      #endif
 
177
     }
 
178
     else
 
179
      #if SFX_LEVEL>=ARJSFXV
 
180
       msg_cprintf(H_ERR, M_BADTABLE);
 
181
      #else
 
182
       error(M_BADTABLE);
 
183
      #endif
 
184
     longjmp(decode_proc, 1);
 
185
    }
 
186
    for(i=start[len]; i<nextcode; i++)
 
187
    {
 
188
     stop_optimizer();                  /* VisualAge C++ v 3.65 fix */
 
189
     table[i]=ch;
 
190
    }
 
191
   }
 
192
   else
 
193
   {
 
194
    p=&table[k>>jutbits];
 
195
    i=len-tablebits;
 
196
    while(i!=0)
 
197
    {
 
198
     if(*p==0)
 
199
     {
 
200
      right[avail]=left[avail]=0;
 
201
      *p=avail;
 
202
      avail++;
 
203
     }
 
204
     if(k&mask)
 
205
      p=&right[*p];
 
206
     else
 
207
      p=&left[*p];
 
208
     k<<=1;
 
209
     i--;
 
210
    }
 
211
    *p=ch;
 
212
   }
 
213
   start[len]=nextcode;
 
214
  }
 
215
 }
 
216
}
 
217
 
 
218
/* Reads length of data pending */
 
219
 
 
220
void read_pt_len(int nn, int nbit, int i_special)
 
221
{
 
222
 int i, n;
 
223
 short c;
 
224
 unsigned short mask;
 
225
 
 
226
 n=getbits(nbit);
 
227
 if(n==0)
 
228
 {
 
229
  c=(short)getbits(nbit);
 
230
  for(i=0; i<nn; i++)
 
231
   pt_len[i]=0;
 
232
  for(i=0; i<PTABLESIZE; i++)
 
233
   pt_table[i]=c;
 
234
 }
 
235
 else
 
236
 {
 
237
  i=0;
 
238
  /* ASR fix to prevent overrun -- 04/12/1999 */
 
239
  if(n>=NPT)                            /* FIX */
 
240
   n=NPT;                               /* FIX */
 
241
  while(i<n)
 
242
  {
 
243
   c=bitbuf>>13;
 
244
   if(c==7)
 
245
   {
 
246
    mask=1<<12;
 
247
    while(mask&bitbuf)
 
248
    {
 
249
     mask>>=1;
 
250
     c++;
 
251
    }
 
252
   }
 
253
   fillbuf((c<7)?3:(int)(c-3));
 
254
   pt_len[i++]=(unsigned char)c;
 
255
   if(i==i_special)
 
256
   {
 
257
    c=getbits(2);
 
258
    while(--c>=0)
 
259
     pt_len[i++]=0;
 
260
   }
 
261
  }
 
262
  while(i<nn)
 
263
   pt_len[i++]=0;
 
264
  make_table(nn, pt_len, 8, pt_table, PTABLESIZE);
 
265
 }
 
266
}
 
267
 
 
268
/* Reads a character table */
 
269
 
 
270
void read_c_len()
 
271
{
 
272
 short i, c, n;
 
273
 unsigned short mask;
 
274
 
 
275
 n=getbits(CBIT);
 
276
 if(n==0)
 
277
 {
 
278
  c=getbits(CBIT);
 
279
  for(i=0; i<NC; i++)
 
280
   c_len[i]=0;
 
281
  for(i=0; i<CTABLESIZE; i++)
 
282
   c_table[i]=c;
 
283
 }
 
284
 else
 
285
 {
 
286
  i=0;
 
287
  while(i<n)
 
288
  {
 
289
   c=pt_table[bitbuf>>8];
 
290
   if(c>=NT)
 
291
   {
 
292
    mask=1<<7;
 
293
    do
 
294
    {
 
295
     if(bitbuf&mask)
 
296
      c=right[c];
 
297
     else
 
298
      c=left[c];
 
299
     mask>>=1;
 
300
    } while(c>=NT);
 
301
   }
 
302
   fillbuf((int)(pt_len[c]));
 
303
   if(c<=2)
 
304
   {
 
305
    if(c==0)
 
306
     c=1;
 
307
    else if(c==1)
 
308
    {
 
309
     c=getbits(4);
 
310
     c+=3;
 
311
    }
 
312
    else
 
313
    {
 
314
     c=getbits(CBIT);
 
315
     c+=20;
 
316
    }
 
317
    while(--c>=0)
 
318
     c_len[i++]=0;
 
319
   }
 
320
   else
 
321
    c_len[i++]=(unsigned char)(c-2);
 
322
  }
 
323
  while(i<NC)
 
324
   c_len[i++]=0;
 
325
  make_table(NC, c_len, 12, c_table, CTABLESIZE);
 
326
 }
 
327
}
 
328
 
 
329
/* Decodes a single character */
 
330
 
 
331
static unsigned short NEAR decode_c()
 
332
{
 
333
 unsigned short j, mask;
 
334
 
 
335
 if(blocksize==0)
 
336
 {
 
337
  blocksize=getbits(CODE_BIT);
 
338
  read_pt_len(NT, TBIT, 3);
 
339
  read_c_len();
 
340
  read_pt_len(NP, PBIT, -1);
 
341
 }
 
342
 blocksize--;
 
343
 j=c_table[bitbuf>>4];
 
344
 if(j>=NC)
 
345
 {
 
346
  mask=1<<3;
 
347
  do
 
348
  {
 
349
   if(bitbuf&mask)
 
350
    j=right[j];
 
351
   else
 
352
    j=left[j];
 
353
   mask>>=1;
 
354
  } while(j>=NC);
 
355
 }
 
356
 fillbuf(c_len[j]);
 
357
 return(j);
 
358
}
 
359
 
 
360
/* Decodes a control character */
 
361
 
 
362
static unsigned short NEAR decode_p()
 
363
{
 
364
 unsigned short j, mask;
 
365
 
 
366
 j=pt_table[bitbuf>>8];
 
367
 if(j>=NP)
 
368
 {
 
369
  mask=1<<7;
 
370
  do
 
371
  {
 
372
   if(bitbuf&mask)
 
373
    j=right[j];
 
374
   else
 
375
    j=left[j];
 
376
   mask>>=1;
 
377
  } while(j>=NP);
 
378
 }
 
379
 fillbuf(pt_len[j]);
 
380
 if(j!=0)
 
381
 {
 
382
  j--;
 
383
  j=(1<<j)+getbits(j);
 
384
 }
 
385
 return(j);
 
386
}
 
387
 
 
388
/* Initializes memory for decoding */
 
389
 
 
390
static void NEAR decode_start()
 
391
{
 
392
 blocksize=0;
 
393
 #if SFX_LEVEL>=ARJSFXV
 
394
  if((c_table=farcalloc((unsigned long)CTABLESIZE, (unsigned long)sizeof(short)))==NULL)
 
395
   error(M_OUT_OF_MEMORY);
 
396
  if((pt_table=farcalloc((unsigned long)PTABLESIZE, (unsigned long)sizeof(short)))==NULL)
 
397
   error(M_OUT_OF_MEMORY);
 
398
 #endif
 
399
 decode_start_stub();
 
400
}
 
401
 
 
402
#if SFX_LEVEL>=ARJSFXV
 
403
 
 
404
/* Releases memory used for decoding */
 
405
 
 
406
static void NEAR decode_end()
 
407
{
 
408
 farfree(c_table);
 
409
 farfree(pt_table);
 
410
 decode_end_stub();
 
411
}
 
412
 
 
413
#endif
 
414
 
 
415
/* Decodes the entire file */
 
416
 
 
417
void decode(int action)
 
418
{
 
419
 short i;
 
420
 short r;
 
421
 short c;
 
422
 static short j;
 
423
 
 
424
 #if SFX_LEVEL>=ARJSFXV
 
425
 if(!setjmp(decode_proc))
 
426
 {
 
427
 #endif
 
428
  #if SFX_LEVEL>=ARJSFXV
 
429
   dec_text=malloc_msg(DICSIZ);
 
430
  #endif
 
431
  decode_start();
 
432
  display_indicator(0L);
 
433
  count=origsize;
 
434
  r=0;
 
435
  while(count>0L)
 
436
  {
 
437
   if((c=decode_c())<=UCHAR_MAX)
 
438
   {
 
439
    dec_text[r]=(unsigned char)c;
 
440
    count--;
 
441
    if(++r>=DICSIZ)
 
442
    {
 
443
     r=0;
 
444
     display_indicator(origsize-count);
 
445
     if(extraction_stub(dec_text, DICSIZ, action))
 
446
      goto termination;
 
447
    }
 
448
   }
 
449
   else
 
450
   {
 
451
    j=c-(UCHAR_MAX+1-THRESHOLD);
 
452
    count-=(unsigned long)j;
 
453
    i=r-decode_p()-1;
 
454
    if(i<0)
 
455
     i+=DICSIZ;
 
456
    if(r>i&&r<DICSIZ-MAXMATCH-1)
 
457
    {
 
458
     while(--j>=0)
 
459
      dec_text[r++]=dec_text[i++];
 
460
    }
 
461
    else
 
462
    {
 
463
     while(--j>=0)
 
464
     {
 
465
      dec_text[r]=dec_text[i];
 
466
      if(++r>=DICSIZ)
 
467
      {
 
468
       r=0;
 
469
       display_indicator(origsize-count);
 
470
       if(extraction_stub(dec_text, DICSIZ, action))
 
471
        goto termination;
 
472
      }
 
473
      if(++i>=DICSIZ)
 
474
       i=0;
 
475
     }
 
476
    }
 
477
   }
 
478
  }
 
479
 #if SFX_LEVEL>=ARJSFXV
 
480
 }
 
481
 #endif
 
482
 if(r>0)
 
483
  extraction_stub(dec_text, r, action);
 
484
termination:;
 
485
 #if SFX_LEVEL>=ARJSFXV
 
486
  decode_end();
 
487
  free(dec_text);
 
488
 #endif
 
489
}
 
490
 
 
491
#if SFX_LEVEL>=ARJ
 
492
 
 
493
/* Backward pointer decoding */
 
494
 
 
495
static short decode_ptr()
 
496
{
 
497
 short c, width, plus, pwr;
 
498
 
 
499
 plus=0;
 
500
 pwr=1<<9;
 
501
 for(width=9; width<13; width++)
 
502
 {
 
503
  c=getbits(1);
 
504
  if(c==0)
 
505
   break;
 
506
  plus+=pwr;
 
507
  pwr<<=1;
 
508
 }
 
509
 if(width!=0)
 
510
  c=getbits(width);
 
511
 c+=plus;
 
512
 return(c);
 
513
}
 
514
 
 
515
/* Reference length decoding */
 
516
 
 
517
static short decode_len()
 
518
{
 
519
 short c, width, plus, pwr;
 
520
 
 
521
 plus=0;
 
522
 pwr=1;
 
523
 for(width=0; width<7; width++)
 
524
 {
 
525
  c=getbits(1);
 
526
  if(c==0)
 
527
   break;
 
528
  plus+=pwr;
 
529
  pwr<<=1;
 
530
 }
 
531
 if(width!=0)
 
532
  c=getbits(width);
 
533
 c+=plus;
 
534
 return(c);
 
535
}
 
536
 
 
537
/* Decodes the entire file, using method 4 */
 
538
 
 
539
void decode_f(int action)
 
540
{
 
541
 int i;
 
542
 int j;
 
543
 int c;
 
544
 int r;
 
545
 static unsigned long ncount;
 
546
 
 
547
 if(ntext==NULL)
 
548
  ntext=malloc_msg(FDICSIZ);
 
549
 decode_start_stub();
 
550
 display_indicator(0L);
 
551
 ncount=0L;
 
552
 r=0;
 
553
 while(ncount<origsize)
 
554
 {
 
555
  c=decode_len();
 
556
  if(c==0)
 
557
  {
 
558
   ncount++;
 
559
   ntext[r]=(unsigned char)(bitbuf>>8);
 
560
   fillbuf(8);
 
561
   if(++r>=FDICSIZ)
 
562
   {
 
563
    r=0;
 
564
    display_indicator(ncount);
 
565
    if(extraction_stub(ntext, FDICSIZ, action))
 
566
     goto termination;
 
567
   }
 
568
  }
 
569
  else
 
570
  {
 
571
   j=c-1+THRESHOLD;
 
572
   ncount+=(unsigned long)j;
 
573
   if((i=r-decode_ptr()-1)<0)
 
574
    i+=FDICSIZ;
 
575
   while(j-->0)
 
576
   {
 
577
    ntext[r]=ntext[i];
 
578
    if(++r>=FDICSIZ)
 
579
    {
 
580
     r=0;
 
581
     display_indicator(ncount);
 
582
     if(extraction_stub(ntext, FDICSIZ, action))
 
583
      goto termination;
 
584
    }
 
585
    if(++i>=FDICSIZ)
 
586
     i=0;
 
587
   }
 
588
  }
 
589
 }
 
590
 if(r>0)
 
591
  extraction_stub(ntext, r, action);
 
592
 termination:
 
593
 decode_end_stub();
 
594
 /* ASR fix - otherwise destroy it in final_cleanup() -- 15/08/2001 */
 
595
 #ifdef TILED
 
596
  free(ntext);
 
597
  ntext=NULL;
 
598
 #endif
 
599
}
 
600
 
 
601
#endif