1 /*****************************************************************************/
2 /*  LibreDWG - free implementation of the DWG file format                    */
3 /*                                                                           */
4 /*  Copyright (C) 2019 Free Software Foundation, Inc.                        */
5 /*                                                                           */
6 /*  This library is free software, licensed under the terms of the GNU       */
7 /*  General Public License as published by the Free Software Foundation,     */
8 /*  either version 3 of the License, or (at your option) any later version.  */
9 /*  You should have received a copy of the GNU General Public License        */
10 /*  along with this program.  If not, see <http://www.gnu.org/licenses/>.    */
11 /*****************************************************************************/
12 
13 /*
14  * escape.c: SVG helpers
15  * written by Reini Urban
16  */
17 
18 #include "config.h"
19 #include <string.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 
23 #include "common.h"
24 #include "escape.h"
25 
26 char * ATTRIBUTE_MALLOC
htmlescape(const char * restrict src,const int cp)27 htmlescape (const char *restrict src, const int cp)
28 {
29   int len;
30   char *dest, *d, *end;
31   unsigned char *s;
32   if (!src)
33     return NULL;
34   len = strlen (src) + 10;
35   d = calloc (len, 1);
36   s = (unsigned char *)src;
37   dest = d;
38   end = dest + len;
39   while (*s)
40     {
41       const int off = d - dest;
42       if (end - d <= 8)
43         {
44           len += 10;
45           dest = realloc (dest, len);
46           d = dest + off;
47           *d = 0;
48           end = dest + len;
49         }
50       switch (*s)
51         {
52         case '"':
53           strcat (d, "&quot;");
54           d += 6;
55           break;
56         case '\'':
57           strcat (d, "&#39;");
58           d += 5;
59           break;
60         case '`':
61           strcat (d, "&#96;");
62           d += 5;
63           break;
64         case '&':
65           strcat (d, "&amp;");
66           d += 5;
67           break;
68         case '<':
69           strcat (d, "&lt;");
70           d += 4;
71           break;
72         case '>':
73           strcat (d, "&gt;");
74           d += 4;
75           break;
76         case '{':
77           strcat (d, "&#123;");
78           d += 6;
79           break;
80         case '}':
81           strcat (d, "&#125;");
82           d += 6;
83           break;
84         default:
85           if (*s >= 127) // maybe encodings, no utf8 (see htmlwescape)
86             {
87               sprintf (d, "&#x%X;", *s); // 4 + 4
88               d += strlen (d);
89               *d = 0;
90             }
91           else if (*s >= 20)
92             {
93               *d++ = *s;
94               *d = 0;
95             }
96         }
97       s++;
98     }
99   *d = 0;
100   return dest;
101 }
102 
103 char * ATTRIBUTE_MALLOC
htmlwescape(BITCODE_TU wstr)104 htmlwescape (BITCODE_TU wstr)
105 {
106   int len = 0;
107   char *dest, *d;
108   BITCODE_TU tmp = wstr;
109   BITCODE_RS c;
110 
111   if (!wstr)
112     return NULL;
113   while ((c = *tmp++))
114     len++;
115   len += 16;
116   d = dest = calloc (len, 1);
117 
118   while (*wstr)
119     {
120       const int off = d - dest;
121       if (off >= len - 8)
122         {
123           len += 16;
124           dest = realloc (dest, len);
125           d = dest + off;
126           *d = 0;
127         }
128       switch (*wstr)
129         {
130         case 34: strcat (d, "&quot;"); d += 6; break;
131         case 39: strcat (d, "&#39;"); d += 5; break;
132         case 38: strcat (d, "&amp;"); d += 5; break;
133         case 60: strcat (d, "&lt;"); d += 4; break;
134         case 62: strcat (d, "&gt;"); d += 4; break;
135         case 96: strcat (d, "&#96;"); d += 5; break;
136         case 123: strcat (d, "&#123;"); d += 6; break;
137         case 125: strcat (d, "&#125;"); d += 6; break;
138         default:
139           if (*wstr >= 127) // utf8 encodings
140             {
141               sprintf (d, "&#x%X;", *wstr);
142               d += strlen (d);
143               *d = 0;
144             }
145           else if (*wstr >= 20)
146             {
147               *d++ = *wstr;
148               *d = 0;
149             }
150         }
151       wstr++;
152     }
153   *d = 0;
154   return dest;
155 }
156