~ubuntu-branches/ubuntu/intrepid/altermime/intrepid

« back to all changes in this revision

Viewing changes to ffget.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien Valroff
  • Date: 2007-08-07 20:00:08 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070807200008-hddutz1e96ym8alx
Tags: 0.3.8-2
Added patch so that altermime handles nostrip build option (Closes: #436433)

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
routine by line-buffering up first.
9
9
 
10
10
12/11/2002: Corrected input buffer termination with fgets where the last line
11
 
        of the input file does not terminate with a \n or \r.
 
11
of the input file does not terminate with a \n or \r.
12
12
 
13
13
27/09/2001:  Added SGI specific compile time changes from char -> short
14
14
contributed by Don Lafontaine <lafont02@cn.ca>
23
23
#include "logger.h"
24
24
#include "ffget.h"
25
25
 
26
 
#define FFGET_VERSION   "1.0.0.4"
27
 
#define FFGET_LASTUPDATED "29/03/2006"
28
 
 
29
 
#define FFGET_DNORMAL   ((FFGET_debug >= _FFGET_DEBUG_NORMAL  ))
30
 
#define FFGET_DPEDANTIC ((FFGET_debug >= _FFGET_DEBUG_PEDANTIC))
 
26
#ifndef FL
 
27
#define FL __FILE__,__LINE__
 
28
#endif
 
29
 
 
30
#define FFGET_VERSION   "1.0.0.7"
 
31
#define FFGET_LASTUPDATED "200707091500"
 
32
 
 
33
#define FFGET_DNORMAL   ((FFGET_debug >= FFGET_DEBUG_NORMAL  ))
 
34
#define FFGET_DPEDANTIC ((FFGET_debug >= FFGET_DEBUG_PEDANTIC))
31
35
 
32
36
/* GLOBALS */
33
37
int ffget_linesize=0;
35
39
int FFGET_SDL_MODE = 0;  // Single Char Delimeter
36
40
 
37
41
int FFGET_SDL_WATCH = 0;        // Set if we want to watch for double-CR exploits
 
42
int FFGET_ALLOW_NUL = 0;        // Dont Convert \0's to spaces.
38
43
 
39
44
int FFGET_debug = 0;
40
45
 
41
 
static char SDL_MODE_DELIMITS[]="\n\r";
42
 
static char NORM_MODE_DELIMITS[]="\n";
43
 
static char *DELIMITERS=SDL_MODE_DELIMITS;
 
46
char SDL_MODE_DELIMITS[]="\n\r";
 
47
char NORM_MODE_DELIMITS[]="\n";
 
48
char *DELIMITERS=SDL_MODE_DELIMITS;
44
49
 
45
50
/*------------------------------------------------------------------------
46
51
Procedure:     FFGET_set_watch_SDL ID:1
58
63
        return FFGET_SDL_WATCH;
59
64
}
60
65
 
 
66
/*-----------------------------------------------------------------\
 
67
  Function Name : FFGET_set_allow_nul
 
68
  Returns Type  : int
 
69
  ----Parameter List
 
70
  1. int level , 
 
71
  ------------------
 
72
  Exit Codes    : 
 
73
  Side Effects  : 
 
74
  --------------------------------------------------------------------
 
75
Comments:
 
76
This tells the FFGET_raw() if it needs to remove \0's or not
 
77
in the data it reads.  This was added so as to ensure that \0
 
78
sequences were preserved in form-data from WWW pages.
 
79
 
 
80
--------------------------------------------------------------------
 
81
Changes:
 
82
Added 2004-Aug-09 by PLD.
 
83
 
 
84
\------------------------------------------------------------------*/
 
85
int FFGET_set_allow_nul(int level )
 
86
{
 
87
        FFGET_ALLOW_NUL = level;
 
88
 
 
89
        return FFGET_ALLOW_NUL;
 
90
}
61
91
 
62
92
/*------------------------------------------------------------------------
63
93
Procedure:     FFGET_set_debug ID:1
102
132
        } else {
103
133
                long block_pos;
104
134
 
105
 
                block_pos = ftell(f->f);
106
 
                bs = fread( f->buffer, 1, _FFGET_BUFFER_MAX -2, f->f );
107
 
 
108
 
                if (bs < (_FFGET_BUFFER_MAX -2)) {
109
 
                        if (feof(f->f)) {
 
135
                block_pos = ftell(f->f); /** Get our current read position so we can use it in FFGET_ftell if required **/
 
136
 
 
137
                bs = fread( f->buffer, 1, FFGET_BUFFER_MAX -FFGET_BUFFER_PADDING, f->f );
 
138
 
 
139
                if (bs < (FFGET_BUFFER_MAX -FFGET_BUFFER_PADDING))
 
140
                {
 
141
                        if (feof(f->f))
 
142
                        {
110
143
                                f->FILEEND = 1;
111
 
 
112
 
                        } else {
113
 
 
114
 
                                fprintf(stderr,"%s:%d: WARNING - File read failed with error:%s",__FILE__,__LINE__,strerror(errno));
 
144
                        }
 
145
                        else
 
146
                        {
 
147
                                LOGGER_log("%s:%d:FFGET_getnewblock:ERROR: File read failed with error:%s", FL, strerror(errno));
115
148
                                return 0;
116
149
                        }
117
150
                }
118
151
 
119
 
                if (bs > 0) {
 
152
                if (bs > 0)
 
153
                {
120
154
 
121
155
                        // If we read in some data, then adjust the buffer to deal with it
122
 
                //
123
 
                // First we set the start point back to the start of the buffer,
124
 
                // then we set the end point to be the start +datasize we read, -1
125
 
                // then we adjust the total bytes read (for the sake of record keeping
126
 
                // though it has no /real/ purpose)
127
 
                //
 
156
                        //
 
157
                        // First we set the start point back to the start of the buffer,
 
158
                        // then we set the end point to be the start +datasize we read, -1
 
159
                        // then we adjust the total bytes read (for the sake of record keeping
 
160
                        // though it has no /real/ purpose)
 
161
                        //
128
162
 
129
 
                        f->last_block_read_from = block_pos;
 
163
                        f->buffer[bs] = '\0';   //20040208-1703:PLD:JS
 
164
                        f->last_block_read_from = block_pos; // 200607150941:PLD
130
165
                        f->startpoint = f->buffer;
131
166
                        f->endpoint = f->startpoint +bs -1;
132
167
                        f->bytes += bs;
133
168
 
134
169
                        // Check the buffer for poisioning \0's
135
 
                //  As these routines are being used for 7-bit valid text data,
136
 
                // we have to filter out any nasty \0's.
 
170
                        //  As these routines are being used for 7-bit valid text data,
 
171
                        // we have to filter out any nasty \0's.
137
172
 
138
 
                        p = f->startpoint;
139
 
                        for (i = 0; i < bs; i++) {
140
 
                                if (*p == '\0') *p = ' ';
141
 
                                p++;
 
173
                        if (FFGET_ALLOW_NUL == 0)
 
174
                        {
 
175
                                p = f->startpoint;
 
176
                                for (i = 0; i < bs; i++) {
 
177
                                        if (*p == '\0') *p = ' ';
 
178
                                        p++;
 
179
                                }
 
180
                                *p = '\0';
142
181
                        }
143
 
                        *p = '\0';
144
182
 
145
 
                        if (FFGET_DPEDANTIC) LOGGER_log("Size: %ld bytes\n",f->bytes);
 
183
                        if (FFGET_DPEDANTIC) LOGGER_log("%s:%d:FFGET_getnewblock:DEBUG-PEDANTIC: Size: %ld bytes\n", FL, f->bytes);
146
184
 
147
185
                }
148
186
 
167
205
------------------------------------------------------------------------*/
168
206
int FFGET_presetbuffer( FFGET_FILE *f, char *buffer, int size )
169
207
{
170
 
        if (size > _FFGET_BUFFER_MAX) size = _FFGET_BUFFER_MAX;
 
208
        if (size > FFGET_BUFFER_MAX) size = FFGET_BUFFER_MAX;
171
209
 
172
210
        memcpy(f->buffer,buffer,size);
173
211
        f->startpoint = buffer;
186
224
------------------------------------------------------------------------*/
187
225
int FFGET_setstream( FFGET_FILE *f, FILE *fi )
188
226
{
 
227
 
 
228
        memset(f,0,sizeof(FFGET_FILE)); // be pedantic - clear the struct
 
229
 
189
230
        f->f = fi;
190
231
        f->bytes = 0;
191
232
        f->linecount = 0;
192
233
        f->endpoint = f->buffer;
193
234
        f->startpoint = f->endpoint +1;
 
235
        f->buffer_end = f->buffer +FFGET_BUFFER_MAX +FFGET_BUFFER_PADDING;
194
236
        f->trueblank = 0;
195
237
        f->ungetcset = 0;
196
238
        f->lastchar = '\0';
197
 
        memset(f->buffer,'\0',_FFGET_BUFFER_MAX +1);
 
239
        memset(f->buffer,'\0',FFGET_BUFFER_MAX +FFGET_BUFFER_PADDING);
198
240
        f->c = '\0';
199
241
        f->FFEOF = 0;
200
242
        f->FILEEND = 0;
229
271
}
230
272
 
231
273
 
 
274
 
232
275
/*-----------------------------------------------------------------\
233
 
 Function Name  : FFGET_seek
234
 
 Returns Type   : int
235
 
        ----Parameter List
236
 
        1. FFGET_FILE *f, 
237
 
        2.  size_t offset , 
238
 
        ------------------
239
 
 Exit Codes     : 
240
 
 Side Effects   : 
241
 
--------------------------------------------------------------------
242
 
 Comments:
243
 
                Seeks to 'offset' bytes from the first byte of the file.
244
 
                Reloads the buffer block.
245
 
 
246
 
--------------------------------------------------------------------
247
 
 Changes:
248
 
 
 
276
  Function Name : FFGET_seek
 
277
  Returns Type  : int
 
278
  ----Parameter List
 
279
  1. FFGET_FILE *f, 
 
280
  2.  size_t offset , 
 
281
  ------------------
 
282
  Exit Codes    : 
 
283
  -1 = error, check logs for reason of failure.
 
284
 
 
285
  Side Effects  : 
 
286
  --------------------------------------------------------------------
 
287
Comments:
 
288
Seeks to 'offset' bytes from the first byte of the file.
 
289
Reloads the buffer block.
 
290
 
 
291
--------------------------------------------------------------------
 
292
Changes:
 
293
 
249
294
\------------------------------------------------------------------*/
250
295
int FFGET_seek( FFGET_FILE *f, long offset, int whence )
251
296
{
252
297
        int result = 0;
253
 
        fseek(f->f, offset, whence);
 
298
 
 
299
        /** Move to the new block location **/
 
300
        result = fseek(f->f, offset, whence);
 
301
        if (result == -1) {
 
302
                LOGGER_log("%s:%d:FFGET_seek:ERROR: While attempting to seek to offset %ld from %d - [%s]", FL, offset, whence, strerror(errno));
 
303
                return -1;
 
304
        }
 
305
 
 
306
        /** Read a whole new block **/
254
307
        result = FFGET_getnewblock(f);
 
308
 
255
309
        return result;
256
310
}
257
311
 
258
312
 
 
313
 
259
314
/*-----------------------------------------------------------------\
260
 
 Function Name  : FFGET_tell
261
 
 Returns Type   : size_t
262
 
        ----Parameter List
263
 
        1. FFGET_FILE *f , 
264
 
        ------------------
265
 
 Exit Codes     : 
266
 
 Side Effects   : 
267
 
--------------------------------------------------------------------
268
 
 Comments:
269
 
                Returns the position in the file that the current "file cursor"
270
 
                is pointing to.
271
 
 
272
 
 
273
 
--------------------------------------------------------------------
274
 
 Changes:
275
 
 
 
315
  Function Name : FFGET_tell
 
316
  Returns Type  : size_t
 
317
  ----Parameter List
 
318
  1. FFGET_FILE *f , 
 
319
  ------------------
 
320
  Exit Codes    : 
 
321
  Side Effects  : 
 
322
  --------------------------------------------------------------------
 
323
Comments:
 
324
Returns the position in the file that the current "file cursor"
 
325
is pointing to.
 
326
 
 
327
 
 
328
--------------------------------------------------------------------
 
329
Changes:
 
330
 
276
331
\------------------------------------------------------------------*/
277
332
long FFGET_ftell( FFGET_FILE *f )
278
333
{
284
339
 
285
340
}
286
341
 
 
342
 
 
343
 
 
344
 
287
345
/*------------------------------------------------------------------------
288
346
Procedure:     FFGET_ungetc ID:1
289
347
Purpose:       Pushes back into the buffer (effectively) a single character
334
392
                f->startpoint++;
335
393
        }
336
394
        else
337
 
            {
 
395
        {
338
396
                c = EOF;
339
397
        }
340
398
 
360
418
char *FFGET_fgets( char *linein, int maxsize, FFGET_FILE *f )
361
419
{
362
420
        char *line = linein;
363
 
        char *crlfpos;
364
 
        int charstoCRLF;
365
 
        int chardiff;
366
 
        int result;
 
421
        char *crlfpos = NULL;
 
422
        int charstoCRLF = 0;
 
423
        int chardiff = 0;
 
424
        int result = 0;
367
425
        int max_size = maxsize;
368
 
 
369
 
 
370
 
        // We /ONLY/ return EOF -here-, because, even if during the process of
371
 
        // reading through the bufffer we reach the end, we do still have data
372
 
        // which we can send back to the caller.  I'm surprised that more people
373
 
        // didn't pick up on this, it's a glaring flaw.
 
426
        int endpoint_tainted = 0;
 
427
        int extra_char_kept=0;
 
428
        int c, nextchar;
374
429
 
375
430
        f->trueblank = 0;
376
431
 
386
441
        else DELIMITERS = NORM_MODE_DELIMITS;
387
442
 
388
443
 
389
 
//      fprintf(stderr,"FFGET_called, SDLMODE = %d, Offset = %d, maxsize = %d, DATA left = %d, first char is '%02X'\n", FFGET_SDL_MODE, (f->startpoint -f->buffer), max_size, (f->endpoint -f->startpoint)+1, (int)(*f->startpoint));
 
444
        //      fprintf(stderr,"FFGET_called, SDLMODE = %d, Offset = %d, maxsize = %d, DATA left = %d, first char is '%02X'\n", FFGET_SDL_MODE, (f->startpoint -f->buffer), max_size, (f->endpoint -f->startpoint)+1, (int)(*f->startpoint));
390
445
 
391
446
        max_size = maxsize = maxsize -2;
392
447
 
393
 
//      memset(line, 0, max_size+1);
 
448
        //      memset(line, 0, max_size+1);
394
449
 
395
450
        // If we dont have enough data in the buffer to fill up the fgets request
396
451
        // we'll have to do a two step fill
397
452
 
398
 
//fprintf(stderr,"DATA Reminianing : %d\n", (int)(f->endpoint -f->startpoint)+1);
 
453
        //fprintf(stderr,"DATA Reminianing : %d\n", (int)(f->endpoint -f->startpoint)+1);
399
454
 
400
455
        if ((f->startpoint > f->endpoint))
401
456
        {
417
472
                crlfpos = strpbrk( f->startpoint, DELIMITERS);
418
473
                if (crlfpos)
419
474
                {
 
475
                                extra_char_kept = 0;
 
476
                                endpoint_tainted = 0;
 
477
                                nextchar = -1;
420
478
                        // if our next char is a CR or LF, then pick it up and
421
479
                        // return it with the line.  NOTE - this is to deal with
422
480
                        // CRLF pairings which are common on DOS files.  In fact,
423
481
                        // this is a case of where UNIX is actually -wrong-.  It
424
482
                        // should have also used CRLF pairing to mark line ends, but
425
483
                        // someone obviously (and understandably, to save space)
426
 
                        // thought they'd leave make LF imply a CR as well.
 
484
                        // thought they'd leave make LF imply a CR as well.
427
485
                        //   Well done... another bugger up in life.
428
486
 
429
487
 
443
501
 
444
502
                                // We have an EOL character, get 1 more from the stream to test the next character
445
503
 
446
 
                                int c;
447
504
 
448
 
                                c = fgetc(f->f);
 
505
                                nextchar = c = fgetc(f->f);
449
506
                                if (c==EOF)
450
507
                                {
451
 
//                                      fprintf(stderr,"EOF hit due to fgetc()\n");
 
508
                                        //                                      fprintf(stderr,"EOF hit due to fgetc()\n");
452
509
                                        f->FILEEND = 1;
453
510
                                }
454
511
                                else
459
516
 
460
517
                                        if ((c > 0) && (c <= 255))
461
518
                                        {
 
519
                                                if (FFGET_DNORMAL) LOGGER_log("%s:%d:FFGET_fgets:DEBUG: Tainting endpoint +1 (%p -> %p,  hard buffer end = %p, file read bytes = %ld)", FL, f->endpoint, f->endpoint+1, f->buffer_end, f->bytes);
462
520
                                                f->endpoint++;
463
521
                                                *(f->endpoint) = c;
464
522
                                                *(f->endpoint+1) = '\0';
 
523
                                                endpoint_tainted = 1;
465
524
                                        }
466
525
 
467
526
                                }
474
533
                        if ( ((crlfpos +1) <= f->endpoint))
475
534
                        {
476
535
 
477
 
//                              fprintf(stderr,"Found '%02X' [next is '%02X']\n",*crlfpos, *(crlfpos+1));
 
536
                                //                              fprintf(stderr,"Found '%02X' [next is '%02X']\n",*crlfpos, *(crlfpos+1));
478
537
 
479
538
                                if ( *crlfpos == '\n' )
480
539
                                {
481
540
                                        if ( *(crlfpos +1) == '\r' )
482
541
                                        {
483
542
                                                crlfpos++;
 
543
                                                extra_char_kept = 1;
484
544
                                        }
485
545
                                }
486
546
 
501
561
                                                FFGET_doubleCR=1;
502
562
                                                FFGET_SDL_MODE=1;
503
563
                                                crlfpos++;
504
 
                                        }
505
 
                                        else
506
 
                                            if ( *(crlfpos +1) == '\n' )
507
 
                                        {
 
564
                                                extra_char_kept = 1;
 
565
 
 
566
                                        } else if ( *(crlfpos +1) == '\n' ) {
508
567
                                                // If we see a \n after our \r, then treat this as a single
509
568
                                                //      line delimeter if we are NOT in Single Delimeter mode
510
569
 
511
 
                                                if (!FFGET_SDL_MODE) { crlfpos++; }
512
 
                                        }
513
 
                                        else
514
 
                                            {
 
570
                                                if (!FFGET_SDL_MODE) {
 
571
                                                        crlfpos++;
 
572
                                                        extra_char_kept = 1;
 
573
                                                }// 20040208-1706:PLD
 
574
                                                //crlfpos++;// 20040208-1706:PLD         // 20040306-0003:PLD - this line causes a CRCR test to fail; mailpack.virus.badtrans
 
575
                                        } else {
515
576
                                                // If we saw a \r, but then there was no other EOL type char (\r or \n)
516
577
                                                //      then switch to SDL mode (Single delimeter).
517
578
 
537
598
 
538
599
                        if ((charstoCRLF >= 0)&&(charstoCRLF < max_size)) max_size = charstoCRLF;
539
600
 
 
601
                        if ((extra_char_kept == 0) && (nextchar != -1)) ungetc(nextchar,f->f);
 
602
 
540
603
                } // If CRLF pos found.
541
604
 
542
605
 
543
 
//              else crlfpos = (f->endpoint +1);
 
606
                //              else crlfpos = (f->endpoint +1);
544
607
 
545
608
 
546
609
 
551
614
 
552
615
                if (( f->endpoint -f->startpoint) >= max_size)
553
616
                {
554
 
                        if (max_size < 0) fprintf(stderr,"ERROR - Max size < 0\n");
 
617
                        if (max_size < 0) LOGGER_log("%s:%d:FFGET_fgets:ERROR: Max size < 0\n", FL);
555
618
                        memcpy(line, f->startpoint, max_size +1);//+1
556
619
                        f->startpoint += (max_size +1); //+1
557
620
                        *(line +max_size +1) = '\0'; //+1
558
621
                        max_size = 0;
559
 
                }
560
 
                else
561
 
                    {
 
622
 
 
623
                } else {
562
624
 
563
625
                        // else, if the amount of data available is /LESS/ than what we can
564
 
                // accept in the line buffer then copy what remains out to the line
565
 
                // buffer and then tack on the results of a new read.
 
626
                        // accept in the line buffer then copy what remains out to the line
 
627
                        // buffer and then tack on the results of a new read.
566
628
 
567
629
                        chardiff = f->endpoint -f->startpoint;
568
630
 
569
 
//                      fprintf(stderr,"CHARDiff = %d, FFEOF = %d, FILEEND = %d\n",chardiff, f->FFEOF, f->FILEEND);
 
631
                        //                      fprintf(stderr,"CHARDiff = %d, FFEOF = %d, FILEEND = %d\n",chardiff, f->FFEOF, f->FILEEND);
570
632
 
571
633
                        if (chardiff >= 0)
572
634
                        {
579
641
                        }
580
642
 
581
643
                        FFGET_getnewblock(f);
 
644
                        endpoint_tainted=0;
582
645
 
583
646
                } // If there wasn't enough data to satisfy ends.
584
647
 
 
648
                if (endpoint_tainted) {
 
649
                        FFGET_getnewblock(f);
 
650
                        endpoint_tainted = 0;
 
651
                }
 
652
 
585
653
        } // While we've got space to fill, and we've got data to read
586
654
 
587
655
        line = linein;
600
668
 
601
669
        f->linecount++;
602
670
 
 
671
        //      LOGGER_log("%s:%d:LINE='%s'",FL,linein);
 
672
 
603
673
        return linein;
604
674
}
605
675
 
636
706
                bytestogo = FFGET_getnewblock(f);
637
707
        }
638
708
        else
639
 
            {
 
709
        {
640
710
                bytestogo = f->endpoint -f->startpoint +1;
641
711
        }
642
712