]> www.wagner.pp.ru Git - oss/catdoc.git/blob - src/catdoc.c
Fixed buffer overflow on very-very long RTF paragraphs.
[oss/catdoc.git] / src / catdoc.c
1 /*
2   Copyright 1996-2003 Victor Wagner
3   Copyright 2003 Alex Ott
4   This file is released under the GPL.  Details can be
5   found in the file COPYING accompanying this distribution.
6 */
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <ctype.h>
16 #include "catdoc.h"
17
18 void help(void);
19
20
21 int signature_check = 1;
22 int forced_charset = 0; /* Flag which disallow rtf parser override charset*/
23 int wrap_margin = WRAP_MARGIN;
24 int (*get_unicode_char)(FILE *f,long *offset,long fileend) =NULL;
25
26 char *input_buffer, *output_buffer;
27 #ifdef __WATCOMC__
28 /* watcom doesn't provide way to access program args via global variable */
29 /* so we would hack it ourselves in Borland-compatible way*/
30 char **_argv;
31 int _argc;
32 #endif
33 /**************************************************************/
34 /*       Main program                                         */
35 /*  Processes options, reads charsets  files and substitution */
36 /*  maps and passes all remaining args to processfile         */
37 /**************************************************************/
38 int main(int argc, char **argv) {
39         FILE *f;
40         int c,i;
41         char *tempname;
42         short int *tmp_charset;
43         int stdin_processed=0;
44 #ifdef __WATCOMC__
45         _argv=argv;
46         _argc=argc;
47 #endif
48         read_config_file(SYSTEMRC);
49 #ifdef USERRC
50         tempname=find_file(strdup(USERRC),getenv("HOME"));
51         if (tempname) {
52                 read_config_file(tempname);
53                 free(tempname);
54         }
55 #endif
56 #ifdef HAVE_LANGINFO
57         get_locale_charset();
58 #endif  
59         while ((c=getopt(argc,argv,"Vls:d:f:taubxv8wm:"))!=-1) {
60                 switch (c) {
61                         case 's':
62                                 check_charset(&source_csname,optarg);
63                                 forced_charset = 1;
64                                 break;
65                         case 'd':
66                                 check_charset(&dest_csname,optarg);
67                                 break;
68                         case 'f':
69                                 format_name=strdup(optarg);
70                                 break;
71                         case 't':
72                                 format_name=strdup("tex");
73                                 break;
74                         case 'a':
75                                 format_name=strdup("ascii");
76                                 break;
77                         case 'u':
78                                 get_unicode_char = get_word8_char;
79                                 break;
80                         case '8':
81                                 get_unicode_char = get_8bit_char;
82                                 break;
83                         case 'v':
84                                 verbose=1;
85                                 break;
86                         case 'w':
87                                 wrap_margin=0; /* No wrap */
88                                 break;
89                         case 'm': {
90                                                   char *endptr;
91                                                   wrap_margin = strtol(optarg,&endptr,0);
92                                                   if (*endptr) {
93                                                           fprintf(stderr,"Invalid wrap margin value `%s'\n",optarg);
94                                                           exit(1);
95                                                   }
96                                                   break;
97                                           }
98                         case 'l': list_charsets(); exit(0);          
99                         case 'b': signature_check =0; break;
100                         case 'x': unknown_as_hex = 1; break;
101                         case 'V': printf("Catdoc Version %s\n",CATDOC_VERSION);
102                                           exit(0);
103                         default:
104                                           help();
105                                           exit(1);
106                 }
107         }
108         input_buffer=malloc(FILE_BUFFER);
109         if (!input_buffer) {
110                 fprintf(stderr,"Input buffer not allocated\n");
111         }
112         source_charset = read_charset(source_csname);
113         if (!source_charset) exit(1);
114         if (strncmp(dest_csname,"utf-8",6)) {
115                 tmp_charset = read_charset(dest_csname);
116                 if (!tmp_charset) exit(1);
117                 target_charset= make_reverse_map(tmp_charset);
118                 free(tmp_charset);
119         } else {
120                 target_charset = NULL;
121         }  
122         spec_chars=read_substmap(stradd(format_name,SPEC_EXT));
123         if (!spec_chars) {
124                 fprintf(stderr,"Cannot read substitution map %s%s\n",format_name,
125                                 SPEC_EXT);
126                 exit(1);
127         }  
128         replacements=read_substmap(stradd(format_name,REPL_EXT));
129         if (!replacements) {
130                 fprintf(stderr,"Cannot read replacement map %s%s\n",format_name,
131                                 REPL_EXT);
132                 exit(1);
133         }  
134
135         if (LINE_BUF_SIZE-longest_sequence<=wrap_margin) {
136                 fprintf(stderr,"wrap margin is too large. cannot proceed\n");
137                 exit(1);
138         }  
139         if (!isatty(fileno(stdout))) {
140                 output_buffer=malloc(FILE_BUFFER);
141                 if (output_buffer) {
142                         if  (setvbuf(stdout,output_buffer,_IOFBF,FILE_BUFFER)) {
143                                 perror("stdout");
144                         }
145                 } else {
146                         fprintf(stderr,"output buffer not allocated\n");
147                 }
148         }
149         set_std_func();
150         if (optind == argc) {
151                 if (isatty(fileno(stdin))) {
152                         help();
153                         exit(0);
154                 }
155                 if (input_buffer) setvbuf(stdin,input_buffer,_IOFBF,FILE_BUFFER);
156                 return analyze_format(stdin);
157         }
158         c=0;
159         for (i=optind;i<argc;i++) {
160                 if (!strcmp(argv[i],"-")) {
161                         if (stdin_processed) {
162                                 fprintf(stderr,"Cannot process stdin twice\n");
163                                 exit(1);
164                         }
165                         if (input_buffer) setvbuf(stdin,input_buffer,_IOFBF,FILE_BUFFER);
166                         analyze_format(stdin);
167                         stdin_processed=1;
168                 } else {
169                         f=fopen(argv[i],"rb");
170                         if (!f) {
171                                 c=1;
172                                 perror("catdoc");
173                                 continue;
174                         }
175                         if (input_buffer) {
176                                 if (setvbuf(f,input_buffer,_IOFBF,FILE_BUFFER)) {
177                                         perror(argv[i]);
178                                 }
179                         }
180                         c=analyze_format(f);
181                         fclose(f);
182                 }
183         }
184         return c;
185 }
186 /************************************************************************/
187 /* Displays  help message                                               */
188 /************************************************************************/
189 void help (void) {
190         printf("Usage:\n catdoc [-vu8btawxlV] [-m number] [-s charset] "
191                         "[-d charset] [ -f format] files\n");
192 }