0028034: Application Framework - stack overflow in LDOM destructor
[occt.git] / src / LDOM / LDOM_CharReference.cxx
1 // Created on: 2002-02-08
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2002-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <LDOM_CharReference.hxx>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 //   Uncomment this line if you want that your XML files contain codes 0xc0-0xff
22 //   as defined in Latin-1 code set. Otherwise these codes are written
23 //   numerically as &#x..;
24 //#define LDOM_ALLOW_LATIN_1
25
26 const int NORMAL_C  = 0;
27 const int CHAR_REF  = -1;
28 const int ENTI_AMP  = 1;
29 const int ENTI_LT   = 2;
30 const int ENTI_GT   = 3;
31 const int ENTI_QUOT = 4;
32 //const int ENTI_APOS = 5;
33
34 struct entityRef {
35   const char * name;
36   const int    length;
37   entityRef (const char * aName, const int aLen) : name(aName), length(aLen) {}
38   void operator= (const entityRef&);
39 };
40
41 //=======================================================================
42 //function : Decode
43 //purpose  : Convertes entity and character references on input
44 //           Always returns the same string (shortened after replacements)
45 //=======================================================================
46
47 char * LDOM_CharReference::Decode (char * theSrc, Standard_Integer& theLen)
48 {
49 #define IS_EQUAL(_ptr,_string) (!memcmp(_ptr, _string, sizeof(_string)-1))
50
51   char * aSrcPtr = theSrc, * aDstPtr = theSrc;
52   Standard_Integer anIncrCount = 0;
53   for(;;) {
54     char * aPtr = strchr (aSrcPtr, '&');
55     if (aPtr == NULL) {
56       //        End of the loop
57       aPtr = strchr (aSrcPtr, '\0');
58       if (anIncrCount == 0)
59         theLen = (Standard_Integer)(aPtr - theSrc);
60       else {
61         Standard_Integer aByteCount = (Standard_Integer)(aPtr - aSrcPtr);
62         memmove (aDstPtr, aSrcPtr, aByteCount + 1);
63         theLen = (Standard_Integer)(aDstPtr - theSrc) + aByteCount;
64       }
65       break;
66     }
67     Standard_Integer aByteCount = (Standard_Integer)(aPtr - aSrcPtr);
68     if (aByteCount > 0 && aDstPtr != aSrcPtr)
69       memmove (aDstPtr, aSrcPtr, aByteCount);
70     aSrcPtr = aPtr;
71     if (aSrcPtr[1] == '#') {
72       unsigned long aChar;
73       char *        aNewPtr;
74       aDstPtr = aSrcPtr - anIncrCount + 1;
75       if (aSrcPtr[2] == 'x')
76         aChar = strtoul (&aSrcPtr[3], &aNewPtr, 16);         // hex encoding
77       else
78         aChar = strtoul (&aSrcPtr[2], &aNewPtr, 10);         // decimal encoding
79       if (aNewPtr[0] != ';' || aChar == 0 || aChar > 255UL)
80         //      Error reading an XML string
81         return NULL;
82       aDstPtr[-1] = (char) aChar;
83       anIncrCount += (Standard_Integer)(aNewPtr - aSrcPtr);
84       aSrcPtr = &aNewPtr[1];
85     }
86     else if (IS_EQUAL(aSrcPtr+1, "amp;")) {
87       aDstPtr = aSrcPtr - anIncrCount + 1;
88       aDstPtr[-1] = '&';
89       anIncrCount += 4;
90       aSrcPtr += 5;
91     }
92     else if (IS_EQUAL(aSrcPtr+1, "lt;")) {
93       aDstPtr = aSrcPtr - anIncrCount + 1;
94       aDstPtr[-1] = '<';
95       anIncrCount += 3;
96       aSrcPtr += 4;
97     }
98     else if (IS_EQUAL(aSrcPtr+1, "gt;")) {
99       aDstPtr = aSrcPtr - anIncrCount + 1;
100       aDstPtr[-1] = '>';
101       anIncrCount += 3;
102       aSrcPtr += 4;
103     }
104     else if (IS_EQUAL(aSrcPtr+1, "quot;")) {
105       aDstPtr = aSrcPtr - anIncrCount + 1;
106       aDstPtr[-1] = '\"';
107       anIncrCount += 5;
108       aSrcPtr += 6;
109     }
110     else if (IS_EQUAL(aSrcPtr+1, "apos;")) {
111       aDstPtr = aSrcPtr - anIncrCount + 1;
112       aDstPtr[-1] = '\'';
113       anIncrCount += 5;
114       aSrcPtr += 6;
115     }
116     else {
117       aDstPtr = aSrcPtr - anIncrCount;
118       * aDstPtr++ = * aSrcPtr++;
119       continue;
120     }
121   }
122   return theSrc;
123 }
124
125 //=======================================================================
126 //function : Encode
127 //purpose  : This method takes the input string theSrc and returns:
128 //              - the pointer equal to theSrc if there are no replacements, or
129 //              - the pointer to a newly allocated string with replacements
130 //           The output parameter theLen is assigned to the length of
131 //           the returned string (whatever the case)
132 //=======================================================================
133
134 char * LDOM_CharReference::Encode (const char* theSrc, Standard_Integer& theLen,
135                                    const Standard_Boolean isAttribute)
136 {
137   // Initialising the constants
138   static const struct entityRef entity_ref[6] = {
139     entityRef(NULL,     0),
140     entityRef("&amp;",  5),
141     entityRef("&lt;",   4),
142     entityRef("&gt;",   4),
143     entityRef("&quot;", 6),
144     entityRef("&apos;", 6)
145   };
146
147   const char * endSrc, * ptrSrc = theSrc;
148   char       * aDest = (char *) theSrc;
149   Standard_Integer aCount = 0;
150   //    Analyse if there is a non-standard character in the string
151   for(;;) {
152     const unsigned int iSrc =
153       (const unsigned int) * (const unsigned char *) ptrSrc;
154     if (iSrc == 0) {
155       endSrc = ptrSrc;
156       break;
157     }
158     if (myTab[iSrc] != NORMAL_C)
159       if (isAttribute || myTab[iSrc] != ENTI_QUOT)
160         aCount++;
161     ptrSrc++;
162   }
163   //    If there are such, copy the string with replacements
164   if (!aCount)
165     theLen = (Standard_Integer)(endSrc - theSrc);
166   else {
167     char * ptrDest = new char [(endSrc - theSrc) + aCount * 5 + 1];
168     aDest = ptrDest;
169     for (ptrSrc = theSrc; ptrSrc < endSrc; ptrSrc++) {
170       const unsigned int iSrc =
171         (const unsigned int) * (const unsigned char *) ptrSrc;
172       const int aCode = myTab[iSrc];
173       if (aCode == NORMAL_C)                    // normal (regular) character
174         * ptrDest++ = * ptrSrc;
175       else if (aCode == CHAR_REF) {             // character reference
176         sprintf (ptrDest, "&#x%02x;", iSrc);
177         ptrDest += 6;
178       } else                                    // predefined entity reference
179         if (isAttribute == Standard_False && aCode == ENTI_QUOT)
180           * ptrDest++ = * ptrSrc;
181         else {
182           memcpy (ptrDest, entity_ref[aCode].name, entity_ref[aCode].length+1);
183           ptrDest += entity_ref[aCode].length;
184         }
185     }
186     theLen = (Standard_Integer)(ptrDest - aDest);
187     * ptrDest = '\0';
188   }
189   return aDest;
190 }
191
192 int LDOM_CharReference::myTab [256] = {
193   NORMAL_C,     // 000
194   CHAR_REF,     // 001
195   CHAR_REF,     // 002
196   CHAR_REF,     // 003
197   CHAR_REF,     // 004
198   CHAR_REF,     // 005
199   CHAR_REF,     // 006
200   CHAR_REF,     // 007
201   CHAR_REF,     // 008
202   NORMAL_C,     // 009  TAB
203   NORMAL_C,     // 00a  LF
204   CHAR_REF,     // 00b
205   CHAR_REF,     // 00c
206   NORMAL_C,     // 00d  CR
207   CHAR_REF,     // 00e
208   CHAR_REF,     // 00f
209   CHAR_REF,     // 010
210   CHAR_REF,     // 011
211   CHAR_REF,     // 012
212   CHAR_REF,     // 013
213   CHAR_REF,     // 014
214   CHAR_REF,     // 015
215   CHAR_REF,     // 016
216   CHAR_REF,     // 017
217   CHAR_REF,     // 018
218   CHAR_REF,     // 019
219   CHAR_REF,     // 01a
220   CHAR_REF,     // 01b
221   CHAR_REF,     // 01c
222   CHAR_REF,     // 01d
223   CHAR_REF,     // 01e
224   CHAR_REF,     // 01f
225   NORMAL_C,     // 020:  
226   NORMAL_C,     // 021: !
227   ENTI_QUOT,    // 022: "
228   NORMAL_C,     // 023: #
229   NORMAL_C,     // 024: $
230   NORMAL_C,     // 025: %
231   ENTI_AMP,     // 026: &
232 //  ENTI_APOS,    // 027: '   Here we do never use apostrophe as delimiter
233   NORMAL_C,     // 027: '
234   NORMAL_C,     // 028: (
235   NORMAL_C,     // 029: )
236   NORMAL_C,     // 02a: *
237   NORMAL_C,     // 02b: +
238   NORMAL_C,     // 02c: ,
239   NORMAL_C,     // 02d: -
240   NORMAL_C,     // 02e: .
241   NORMAL_C,     // 02f: /
242   NORMAL_C,     // 030: 0
243   NORMAL_C,     // 031: 1
244   NORMAL_C,     // 032: 2
245   NORMAL_C,     // 033: 3
246   NORMAL_C,     // 034: 4
247   NORMAL_C,     // 035: 5
248   NORMAL_C,     // 036: 6
249   NORMAL_C,     // 037: 7
250   NORMAL_C,     // 038: 8
251   NORMAL_C,     // 039: 9
252   NORMAL_C,     // 03a: :
253   NORMAL_C,     // 03b: ;
254   ENTI_LT,      // 03c: <
255   NORMAL_C,     // 03d: =
256   ENTI_GT,      // 03e: >
257   NORMAL_C,     // 03f: ?
258   NORMAL_C,     // 040: @
259   NORMAL_C,     // 041: A
260   NORMAL_C,     // 042: B
261   NORMAL_C,     // 043: C
262   NORMAL_C,     // 044: D
263   NORMAL_C,     // 045: E
264   NORMAL_C,     // 046: F
265   NORMAL_C,     // 047: G
266   NORMAL_C,     // 048: H
267   NORMAL_C,     // 049: I
268   NORMAL_C,     // 04a: J
269   NORMAL_C,     // 04b: K
270   NORMAL_C,     // 04c: L
271   NORMAL_C,     // 04d: M
272   NORMAL_C,     // 04e: N
273   NORMAL_C,     // 04f: O
274   NORMAL_C,     // 050: P
275   NORMAL_C,     // 051: Q
276   NORMAL_C,     // 052: R
277   NORMAL_C,     // 053: S
278   NORMAL_C,     // 054: T
279   NORMAL_C,     // 055: U
280   NORMAL_C,     // 056: V
281   NORMAL_C,     // 057: W
282   NORMAL_C,     // 058: X
283   NORMAL_C,     // 059: Y
284   NORMAL_C,     // 05a: Z
285   NORMAL_C,     // 05b: [
286   NORMAL_C,     /* 05c: \       */
287   NORMAL_C,     // 05d: ]
288   NORMAL_C,     // 05e: ^
289   NORMAL_C,     // 05f: _
290   NORMAL_C,     // 060: `
291   NORMAL_C,     // 061: a
292   NORMAL_C,     // 062: b
293   NORMAL_C,     // 063: c
294   NORMAL_C,     // 064: d
295   NORMAL_C,     // 065: e
296   NORMAL_C,     // 066: f
297   NORMAL_C,     // 067: g
298   NORMAL_C,     // 068: h
299   NORMAL_C,     // 069: i
300   NORMAL_C,     // 06a: j
301   NORMAL_C,     // 06b: k
302   NORMAL_C,     // 06c: l
303   NORMAL_C,     // 06d: m
304   NORMAL_C,     // 06e: n
305   NORMAL_C,     // 06f: o
306   NORMAL_C,     // 070: p
307   NORMAL_C,     // 071: q
308   NORMAL_C,     // 072: r
309   NORMAL_C,     // 073: s
310   NORMAL_C,     // 074: t
311   NORMAL_C,     // 075: u
312   NORMAL_C,     // 076: v
313   NORMAL_C,     // 077: w
314   NORMAL_C,     // 078: x
315   NORMAL_C,     // 079: y
316   NORMAL_C,     // 07a: z
317   NORMAL_C,     // 07b: {
318   NORMAL_C,     // 07c: |
319   NORMAL_C,     // 07d: }
320   NORMAL_C,     // 07e: ~
321   NORMAL_C,     // 07f: \7f
322   CHAR_REF,     // 080
323   CHAR_REF,     // 081
324   CHAR_REF,     // 082
325   CHAR_REF,     // 083
326   CHAR_REF,     // 084
327   CHAR_REF,     // 085
328   CHAR_REF,     // 086
329   CHAR_REF,     // 087
330   CHAR_REF,     // 088
331   CHAR_REF,     // 089
332   CHAR_REF,     // 08a
333   CHAR_REF,     // 08b
334   CHAR_REF,     // 08c
335   CHAR_REF,     // 08d
336   CHAR_REF,     // 08e
337   CHAR_REF,     // 08f
338   CHAR_REF,     // 090
339   CHAR_REF,     // 091
340   CHAR_REF,     // 092
341   CHAR_REF,     // 093
342   CHAR_REF,     // 094
343   CHAR_REF,     // 095
344   CHAR_REF,     // 096
345   CHAR_REF,     // 097
346   CHAR_REF,     // 098
347   CHAR_REF,     // 099
348   CHAR_REF,     // 09a
349   CHAR_REF,     // 09b
350   CHAR_REF,     // 09c
351   CHAR_REF,     // 09d
352   CHAR_REF,     // 09e
353   CHAR_REF,     // 09f
354   CHAR_REF,     // 0a0
355   CHAR_REF,     // 0a1
356   CHAR_REF,     // 0a2
357   CHAR_REF,     // 0a3
358   CHAR_REF,     // 0a4
359   CHAR_REF,     // 0a5
360   CHAR_REF,     // 0a6
361   CHAR_REF,     // 0a7
362   CHAR_REF,     // 0a8
363   CHAR_REF,     // 0a9
364   CHAR_REF,     // 0aa
365   CHAR_REF,     // 0ab
366   CHAR_REF,     // 0ac
367   CHAR_REF,     // 0ad
368   CHAR_REF,     // 0ae
369   CHAR_REF,     // 0af
370   CHAR_REF,     // 0b0
371   CHAR_REF,     // 0b1
372   CHAR_REF,     // 0b2
373   CHAR_REF,     // 0b3
374   CHAR_REF,     // 0b4
375   CHAR_REF,     // 0b5
376   CHAR_REF,     // 0b6
377   CHAR_REF,     // 0b7
378   CHAR_REF,     // 0b8
379   CHAR_REF,     // 0b9
380   CHAR_REF,     // 0ba
381   CHAR_REF,     // 0bb
382   CHAR_REF,     // 0bc
383   CHAR_REF,     // 0bd
384   CHAR_REF,     // 0be
385   CHAR_REF,     // 0bf
386 #ifdef LDOM_ALLOW_LATIN_1
387   NORMAL_C,     // 0c0
388   NORMAL_C,     // 0c1
389   NORMAL_C,     // 0c2
390   NORMAL_C,     // 0c3
391   NORMAL_C,     // 0c4
392   NORMAL_C,     // 0c5
393   NORMAL_C,     // 0c6
394   NORMAL_C,     // 0c7
395   NORMAL_C,     // 0c8
396   NORMAL_C,     // 0c9
397   NORMAL_C,     // 0ca
398   NORMAL_C,     // 0cb
399   NORMAL_C,     // 0cc
400   NORMAL_C,     // 0cd
401   NORMAL_C,     // 0ce
402   NORMAL_C,     // 0cf
403   NORMAL_C,     // 0d0
404   NORMAL_C,     // 0d1
405   NORMAL_C,     // 0d2
406   NORMAL_C,     // 0d3
407   NORMAL_C,     // 0d4
408   NORMAL_C,     // 0d5
409   NORMAL_C,     // 0d6
410 //  CHAR_REF,     // 0d7
411   NORMAL_C,     // 0d7
412   NORMAL_C,     // 0d8
413   NORMAL_C,     // 0d9
414   NORMAL_C,     // 0da
415   NORMAL_C,     // 0db
416   NORMAL_C,     // 0dc
417   NORMAL_C,     // 0dd
418   NORMAL_C,     // 0de
419   NORMAL_C,     // 0df
420   NORMAL_C,     // 0e0
421   NORMAL_C,     // 0e1
422   NORMAL_C,     // 0e2
423   NORMAL_C,     // 0e3
424   NORMAL_C,     // 0e4
425   NORMAL_C,     // 0e5
426   NORMAL_C,     // 0e6
427   NORMAL_C,     // 0e7
428   NORMAL_C,     // 0e8
429   NORMAL_C,     // 0e9
430   NORMAL_C,     // 0ea
431   NORMAL_C,     // 0eb
432   NORMAL_C,     // 0ec
433   NORMAL_C,     // 0ed
434   NORMAL_C,     // 0ee
435   NORMAL_C,     // 0ef
436   NORMAL_C,     // 0f0
437   NORMAL_C,     // 0f1
438   NORMAL_C,     // 0f2
439   NORMAL_C,     // 0f3
440   NORMAL_C,     // 0f4
441   NORMAL_C,     // 0f5
442   NORMAL_C,     // 0f6
443 //  CHAR_REF,     // 0f7
444   NORMAL_C,     // 0f7
445   NORMAL_C,     // 0f8
446   NORMAL_C,     // 0f9
447   NORMAL_C,     // 0fa
448   NORMAL_C,     // 0fb
449   NORMAL_C,     // 0fc
450   NORMAL_C,     // 0fd
451   NORMAL_C,     // 0fe
452   NORMAL_C      // 0ff
453 #else
454   CHAR_REF,     // 0c0
455   CHAR_REF,     // 0c1
456   CHAR_REF,     // 0c2
457   CHAR_REF,     // 0c3
458   CHAR_REF,     // 0c4
459   CHAR_REF,     // 0c5
460   CHAR_REF,     // 0c6
461   CHAR_REF,     // 0c7
462   CHAR_REF,     // 0c8
463   CHAR_REF,     // 0c9
464   CHAR_REF,     // 0ca
465   CHAR_REF,     // 0cb
466   CHAR_REF,     // 0cc
467   CHAR_REF,     // 0cd
468   CHAR_REF,     // 0ce
469   CHAR_REF,     // 0cf
470   CHAR_REF,     // 0d0
471   CHAR_REF,     // 0d1
472   CHAR_REF,     // 0d2
473   CHAR_REF,     // 0d3
474   CHAR_REF,     // 0d4
475   CHAR_REF,     // 0d5
476   CHAR_REF,     // 0d6
477   CHAR_REF,     // 0d7
478   CHAR_REF,     // 0d8
479   CHAR_REF,     // 0d9
480   CHAR_REF,     // 0da
481   CHAR_REF,     // 0db
482   CHAR_REF,     // 0dc
483   CHAR_REF,     // 0dd
484   CHAR_REF,     // 0de
485   CHAR_REF,     // 0df
486   CHAR_REF,     // 0e0
487   CHAR_REF,     // 0e1
488   CHAR_REF,     // 0e2
489   CHAR_REF,     // 0e3
490   CHAR_REF,     // 0e4
491   CHAR_REF,     // 0e5
492   CHAR_REF,     // 0e6
493   CHAR_REF,     // 0e7
494   CHAR_REF,     // 0e8
495   CHAR_REF,     // 0e9
496   CHAR_REF,     // 0ea
497   CHAR_REF,     // 0eb
498   CHAR_REF,     // 0ec
499   CHAR_REF,     // 0ed
500   CHAR_REF,     // 0ee
501   CHAR_REF,     // 0ef
502   CHAR_REF,     // 0f0
503   CHAR_REF,     // 0f1
504   CHAR_REF,     // 0f2
505   CHAR_REF,     // 0f3
506   CHAR_REF,     // 0f4
507   CHAR_REF,     // 0f5
508   CHAR_REF,     // 0f6
509   CHAR_REF,     // 0f7
510   CHAR_REF,     // 0f8
511   CHAR_REF,     // 0f9
512   CHAR_REF,     // 0fa
513   CHAR_REF,     // 0fb
514   CHAR_REF,     // 0fc
515   CHAR_REF,     // 0fd
516   CHAR_REF,     // 0fe
517   CHAR_REF      // 0ff
518 #endif  // LDOM_ALLOW_LATIN_1
519 };