~ubuntu-branches/ubuntu/quantal/graphviz/quantal-security

« back to all changes in this revision

Viewing changes to .pc/CVE-2014-1235.patch/lib/cgraph/scan.l

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2014-01-14 13:35:47 UTC
  • Revision ID: package-import@ubuntu.com-20140114133547-q1hdcszcetr4plim
Tags: 2.26.3-12ubuntu1.1
* SECURITY UPDATE: buffer overflow in yyerror()
  - debian/patches/CVE-2014-0978.patch: don't overflow buf in
    lib/cgraph/scan.l.
  - CVE-2014-0978
* SECURITY UPDATE: buffer overflow in yyerror() security fix
  - debian/patches/CVE-2014-1235.patch: once again, don't overflow buf
    in lib/cgraph/scan.l.
  - CVE-2014-1235
* SECURITY UPDATE: buffer overflow in chkNum of scanner
  - debian/patches/CVE-2014-1236.patch: don't overflow buf in
    lib/cgraph/scan.l.
  - CVE-2014-1236

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: scan.l,v 1.7 2009/06/03 01:10:51 ellson Exp $ $Revision: 1.7 $ */
 
2
/* vim:set shiftwidth=4 ts=8: */
 
3
 
 
4
/**********************************************************
 
5
*      This software is part of the graphviz package      *
 
6
*                http://www.graphviz.org/                 *
 
7
*                                                         *
 
8
*            Copyright (c) 1994-2004 AT&T Corp.           *
 
9
*                and is licensed under the                *
 
10
*            Common Public License, Version 1.0           *
 
11
*                      by AT&T Corp.                      *
 
12
*                                                         *
 
13
*        Information and Software Systems Research        *
 
14
*              AT&T Research, Florham Park NJ             *
 
15
**********************************************************/
 
16
 
 
17
 
 
18
/* requires flex (i.e. not lex)  */
 
19
%{
 
20
#include <grammar.h>
 
21
#include <cghdr.h>
 
22
#include <agxbuf.h>
 
23
#include <ctype.h>
 
24
#define GRAPH_EOF_TOKEN         '@'             /* lex class must be defined below */
 
25
        /* this is a workaround for linux flex */
 
26
static int line_num = 1;
 
27
static int html_nest = 0;  /* nesting level for html strings */
 
28
static char* InputFile;
 
29
static Agdisc_t *Disc;
 
30
static void     *Ifile;
 
31
static int graphType;
 
32
 
 
33
  /* Reset line number */
 
34
void agreadline(int n) { line_num = n; }
 
35
 
 
36
  /* (Re)set file:
 
37
   */
 
38
void agsetfile(char* f) { InputFile = f; line_num = 1; }
 
39
 
 
40
/* There is a hole here, because switching channels 
 
41
 * requires pushing back whatever was previously read.
 
42
 * There probably is a right way of doing this.
 
43
 */
 
44
void aglexinit(Agdisc_t *disc, void *ifile) { Disc = disc; Ifile = ifile; graphType = 0;}
 
45
 
 
46
#ifndef YY_INPUT
 
47
#define YY_INPUT(buf,result,max_size) \
 
48
        if ((result = Disc->io->afread(Ifile, buf, max_size)) < 0) \
 
49
                YY_FATAL_ERROR( "input in flex scanner failed" )
 
50
#endif
 
51
 
 
52
/* buffer for arbitrary length strings (longer than BUFSIZ) */
 
53
static char     *Sbuf,*Sptr,*Send;
 
54
static void beginstr(void) {
 
55
        if (Sbuf == NIL(char*)) {
 
56
                Sbuf = malloc(BUFSIZ);
 
57
                Send = Sbuf + BUFSIZ;
 
58
        }
 
59
        Sptr = Sbuf;
 
60
        *Sptr = 0;
 
61
}
 
62
 
 
63
static void addstr(char *src) {
 
64
        char    c;
 
65
        if (Sptr > Sbuf) Sptr--;
 
66
        do {
 
67
                do {c = *Sptr++ = *src++;} while (c && (Sptr < Send));
 
68
                if (c) {
 
69
                        long    sz = Send - Sbuf;
 
70
                        long    off = Sptr - Sbuf;
 
71
                        sz *= 2;
 
72
                        Sbuf = (char*)realloc(Sbuf,sz);
 
73
                        Send = Sbuf + sz;
 
74
                        Sptr = Sbuf + off;
 
75
                }
 
76
        } while (c);
 
77
}
 
78
 
 
79
static void endstr(void) {
 
80
        yylval.str = (char*)agstrdup(Ag_G_global,Sbuf);
 
81
}
 
82
 
 
83
static void endstr_html(void) {
 
84
        yylval.str = (char*)agstrdup_html(Ag_G_global,Sbuf);
 
85
}
 
86
 
 
87
static void
 
88
storeFileName (char* fname, int len)
 
89
{
 
90
    static int cnt;
 
91
    static char* buf;
 
92
 
 
93
    if (len > cnt) {
 
94
        if (cnt) buf = (char*)realloc (buf, len+1);
 
95
        else buf = (char*)malloc (len+1);
 
96
        cnt = len;
 
97
    }
 
98
    strcpy (buf, fname);
 
99
    InputFile = buf;
 
100
}
 
101
 
 
102
/* ppDirective:
 
103
 * Process a possible preprocessor line directive.
 
104
 * yytext = #.*
 
105
 */
 
106
static void ppDirective (void)
 
107
{
 
108
    int r, cnt, lineno;
 
109
    char buf[2];
 
110
    char* s = yytext + 1;  /* skip initial # */
 
111
 
 
112
    if (strncmp(s, "line", 4) == 0) s += 4;
 
113
    r = sscanf(s, "%d %1[\"]%n", &lineno, buf, &cnt);
 
114
    if (r > 0) { /* got line number */ 
 
115
        line_num = lineno - 1;
 
116
        if (r > 1) { /* saw quote */
 
117
            char* p = s + cnt;
 
118
            char* e = p;
 
119
            while (*e && (*e != '"')) e++; 
 
120
            if (e != p) {
 
121
                *e = '\0';
 
122
                storeFileName (p, e-p);
 
123
            }
 
124
        }
 
125
    }
 
126
}
 
127
 
 
128
/* chkNum:
 
129
 * The regexp for NUMBER allows a terminating letter.
 
130
 * This way we can catch a number immediately followed by a name
 
131
 * and report this to the user.
 
132
 */
 
133
static int chkNum(void) {
 
134
  unsigned char c = (unsigned char)yytext[yyleng-1];   /* last character */
 
135
  if (!isdigit(c) && (c != '.')) {  /* c is letter */
 
136
        char    buf[BUFSIZ];
 
137
        sprintf(buf,"syntax error - badly formed number '%s' in line %d\n",yytext,line_num);
 
138
    strcat (buf, "splits into two name tokens");
 
139
        agerr(AGWARN,buf);
 
140
    return 1;
 
141
  }
 
142
  else return 0;
 
143
}
 
144
 
 
145
/* The LETTER class below consists of ascii letters, underscore, all non-ascii
 
146
 * characters. This allows identifiers to have characters from any
 
147
 * character set independent of locale. The downside is that, for certain
 
148
 * character sets, non-letter and, in fact, undefined characters will be
 
149
 * accepted. This is not likely and, from dot's stand, shouldn't do any
 
150
 * harm. (Presumably undefined characters will be ignored in display.) And,
 
151
 * it allows a greater wealth of names. */
 
152
%}
 
153
GRAPH_EOF_TOKEN                         [@]     
 
154
LETTER [A-Za-z_\200-\377]
 
155
DIGIT   [0-9]
 
156
NAME    {LETTER}({LETTER}|{DIGIT})*
 
157
NUMBER  [-]?(({DIGIT}+(\.{DIGIT}*)?)|(\.{DIGIT}+)){LETTER}?
 
158
ID              ({NAME}|{NUMBER})
 
159
%x comment
 
160
%x qstring
 
161
%x hstring
 
162
%%
 
163
{GRAPH_EOF_TOKEN}               return(EOF);
 
164
<INITIAL,comment,qstring>\n     line_num++;
 
165
"/*"                                    BEGIN(comment);
 
166
<comment>[^*\n]*                /* eat anything not a '*' */
 
167
<comment>"*"+[^*/\n]*   /* eat up '*'s not followed by '/'s */
 
168
<comment>"*"+"/"                BEGIN(INITIAL);
 
169
"//".*                                  /* ignore C++-style comments */
 
170
^"#".*                                  ppDirective ();
 
171
"#".*                                   /* ignore shell-like comments */
 
172
[ \t\r]                                 /* ignore whitespace */
 
173
"node"                                  return(T_node);                 /* see tokens in agcanonstr */
 
174
"edge"                                  return(T_edge);
 
175
"graph"                                 if (!graphType) graphType = T_graph; return(T_graph);
 
176
"digraph"                               if (!graphType) graphType = T_digraph; return(T_digraph);
 
177
"strict"                                return(T_strict);
 
178
"subgraph"                              return(T_subgraph);
 
179
"->"                            if (graphType == T_digraph) return(T_edgeop); else return('-');
 
180
"--"                            if (graphType == T_graph) return(T_edgeop); else return('-');
 
181
{NAME}                                  { yylval.str = (char*)agstrdup(Ag_G_global,yytext); return(T_atom); }
 
182
{NUMBER}                                { if (chkNum()) yyless(yyleng-1); yylval.str = (char*)agstrdup(Ag_G_global,yytext); return(T_atom); }
 
183
["]                                             BEGIN(qstring); beginstr();
 
184
<qstring>["]                    BEGIN(INITIAL); endstr(); return (T_qatom);
 
185
<qstring>[\\]["]                addstr ("\"");
 
186
<qstring>[\\][\n]               line_num++; /* ignore escaped newlines */
 
187
<qstring>([^"\\]*|[\\].)        addstr(yytext);
 
188
[<]                                             BEGIN(hstring); html_nest = 1; beginstr();
 
189
<hstring>[>]                    html_nest--; if (html_nest) addstr(yytext); else {BEGIN(INITIAL); endstr_html(); return (T_qatom);}
 
190
<hstring>[<]                    html_nest++; addstr(yytext);
 
191
<hstring>[\n]                   addstr(yytext); line_num++; /* add newlines */
 
192
<hstring>([^><]*)               addstr(yytext);
 
193
.                                               return (yytext[0]);
 
194
%%
 
195
void yyerror(char *str)
 
196
{
 
197
        unsigned char   xbuf[BUFSIZ];
 
198
        char    buf[BUFSIZ];
 
199
        agxbuf  xb;
 
200
 
 
201
        agxbinit(&xb, BUFSIZ, xbuf);
 
202
        if (InputFile) {
 
203
                agxbput (&xb, InputFile);
 
204
                agxbput (&xb, ": ");
 
205
        }
 
206
        sprintf(buf," %s in line %d near '", str,line_num);
 
207
        agxbput (&xb, buf);
 
208
        agxbput (&xb, yytext);
 
209
        agxbput (&xb,"'\n");
 
210
        agerr(AGWARN,agxbuse(&xb));
 
211
        agxbfree(&xb);
 
212
}
 
213
/* must be here to see flex's macro defns */
 
214
void aglexeof() { unput(GRAPH_EOF_TOKEN); }
 
215
 
 
216
#ifndef YY_CALL_ONLY_ARG
 
217
# define YY_CALL_ONLY_ARG void
 
218
#endif
 
219
 
 
220
int yywrap(YY_CALL_ONLY_ARG)
 
221
{
 
222
        return 1;
 
223
}
 
224