Code

format string protection/clean up (CVE-2007-1463, CVE-2007-1464)
[inkscape.git] / src / pedro / pedrodom.h
1 #ifndef __PEDRODOM_H__
2 #define __PEDRODOM_H__
3 /*
4  * API for the Pedro mini-DOM parser and tree
5  *
6  * Authors:
7  *   Bob Jamison
8  *
9  * Copyright (C) 2005-2007 Bob Jamison
10  *
11  *  This library is free software; you can redistribute it and/or
12  *  modify it under the terms of the GNU Lesser General Public
13  *  License as published by the Free Software Foundation; either
14  *  version 2.1 of the License, or (at your option) any later version.
15  *
16  *  This library is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  *  Lesser General Public License for more details.
20  *
21  *  You should have received a copy of the GNU Lesser General Public
22  *  License along with this library; if not, write to the Free Software
23  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24  */
26 #include <glib.h>
28 #include <string>
29 #include <vector>
32 namespace Pedro
33 {
35 typedef std::string DOMString;
36 typedef unsigned int XMLCh;
39 class Namespace
40 {
41 public:
42     Namespace()
43         {}
45     Namespace(const DOMString &prefixArg, const DOMString &namespaceURIArg)
46         {
47         prefix       = prefixArg;
48         namespaceURI = namespaceURIArg;
49         }
51     Namespace(const Namespace &other)
52         {
53         assign(other);
54         }
56     Namespace &operator=(const Namespace &other)
57         {
58         assign(other);
59         return *this;
60         }
62     virtual ~Namespace()
63         {}
65     virtual DOMString getPrefix()
66         { return prefix; }
68     virtual DOMString getNamespaceURI()
69         { return namespaceURI; }
71 protected:
73     void assign(const Namespace &other)
74         {
75         prefix       = other.prefix;
76         namespaceURI = other.namespaceURI;
77         }
79     DOMString prefix;
80     DOMString namespaceURI;
82 };
84 class Attribute
85 {
86 public:
87     Attribute()
88         {}
90     Attribute(const DOMString &nameArg, const DOMString &valueArg)
91         {
92         name  = nameArg;
93         value = valueArg;
94         }
96     Attribute(const Attribute &other)
97         {
98         assign(other);
99         }
101     Attribute &operator=(const Attribute &other)
102         {
103         assign(other);
104         return *this;
105         }
107     virtual ~Attribute()
108         {}
110     virtual DOMString getName()
111         { return name; }
113     virtual DOMString getValue()
114         { return value; }
116 protected:
118     void assign(const Attribute &other)
119         {
120         name  = other.name;
121         value = other.value;
122         }
124     DOMString name;
125     DOMString value;
127 };
130 class Element
132 friend class Parser;
134 public:
135     Element()
136         {
137         parent = NULL;
138         }
140     Element(const DOMString &nameArg)
141         {
142         parent = NULL;
143         name   = nameArg;
144         }
146     Element(const DOMString &nameArg, const DOMString &valueArg)
147         {
148         parent = NULL;
149         name   = nameArg;
150         value  = valueArg;
151         }
153     Element(const Element &other)
154         {
155         assign(other);
156         }
158     Element &operator=(const Element &other)
159         {
160         assign(other);
161         return *this;
162         }
164     virtual Element *clone();
166     virtual ~Element()
167         {
168         for (unsigned int i=0 ; i<children.size() ; i++)
169             delete children[i];
170         }
172     virtual DOMString getName()
173         { return name; }
175     virtual DOMString getValue()
176         { return value; }
178     Element *getParent()
179         { return parent; }
181     Element *getFirstChild()
182         { return (children.size() == 0) ? NULL : children[0]; }
184     std::vector<Element *> getChildren()
185         { return children; }
187     std::vector<Element *> findElements(const DOMString &name);
189     DOMString getAttribute(const DOMString &name);
191     std::vector<Attribute> &getAttributes()
192         { return attributes; } 
194     DOMString getTagAttribute(const DOMString &tagName, const DOMString &attrName);
196     DOMString getTagValue(const DOMString &tagName);
198     void addChild(Element *child);
200     void addAttribute(const DOMString &name, const DOMString &value);
202     void addNamespace(const DOMString &prefix, const DOMString &namespaceURI);
204     bool exists(const DOMString &name)
205         { return (findElements(name).size() > 0); }
207     /**
208      * Prettyprint an XML tree to an output stream.  Elements are indented
209      * according to element hierarchy.
210      * @param f a stream to receive the output
211      * @param elem the element to output
212      */
213     void writeIndented(FILE *f);
215     /**
216      * Prettyprint an XML tree to standard output.  This is the equivalent of
217      * writeIndented(stdout).
218      * @param elem the element to output
219      */
220     void print();
222 protected:
224     void assign(const Element &other)
225         {
226         parent     = other.parent;
227         children   = other.children;
228         attributes = other.attributes;
229         namespaces = other.namespaces;
230         name       = other.name;
231         value      = other.value;
232         }
234     void findElementsRecursive(std::vector<Element *>&res, const DOMString &name);
236     void writeIndentedRecursive(FILE *f, int indent);
238     Element *parent;
240     std::vector<Element *>children;
242     std::vector<Attribute> attributes;
243     std::vector<Namespace> namespaces;
245     DOMString name;
246     DOMString value;
248 };
254 class Parser
256 public:
257     /**
258      * Constructor
259      */
260     Parser()
261         { init(); }
263     virtual ~Parser()
264         {}
266     /**
267      * Parse XML in a char buffer.
268      * @param buf a character buffer to parse
269      * @param pos position to start parsing
270      * @param len number of chars, from pos, to parse.
271      * @return a pointer to the root of the XML document;
272      */
273     Element *parse(const char *buf,int pos,int len);
275     /**
276      * Parse XML in a char buffer.
277      * @param buf a character buffer to parse
278      * @param pos position to start parsing
279      * @param len number of chars, from pos, to parse.
280      * @return a pointer to the root of the XML document;
281      */
282     Element *parse(const DOMString &buf);
284     /**
285      * Parse a named XML file.  The file is loaded like a data file;
286      * the original format is not preserved.
287      * @param fileName the name of the file to read
288      * @return a pointer to the root of the XML document;
289      */
290     Element *parseFile(const DOMString &fileName);
292     /**
293      * Utility method to preprocess a string for XML
294      * output, escaping its entities.
295      * @param str the string to encode
296      */
297     static DOMString encode(const DOMString &str);
299     /**
300      *  Removes whitespace from beginning and end of a string
301      */
302     DOMString trim(const DOMString &s);
304 private:
306     void init()
307         {
308         keepGoing       = true;
309         currentNode     = NULL;
310         parselen        = 0;
311         parsebuf        = NULL;
312         currentPosition = 0;
313         }
315     void getLineAndColumn(long pos, long *lineNr, long *colNr);
317     void error(char *fmt, ...) G_GNUC_PRINTF(2,3);
319     int peek(long pos);
321     int match(long pos, const char *text);
323     int skipwhite(long p);
325     int getWord(int p0, DOMString &buf);
327     int getQuoted(int p0, DOMString &buf, int do_i_parse);
329     int parseVersion(int p0);
331     int parseDoctype(int p0);
333     int parseElement(int p0, Element *par,int depth);
335     Element *parse(XMLCh *buf,int pos,int len);
337     bool       keepGoing;
338     Element    *currentNode;
339     long       parselen;
340     XMLCh      *parsebuf;
341     DOMString  cdatabuf;
342     long       currentPosition;
343     int        colNr;
345 };
349 }//namespace Pedro
352 #endif /* __PEDRODOM_H__ */
354 //########################################################################
355 //#  E N D    O F    F I L E
356 //########################################################################