(root)/
libredwg-0.13/
programs/
escape.c
       1  /*****************************************************************************/
       2  /*  LibreDWG - free implementation of the DWG file format                    */
       3  /*                                                                           */
       4  /*  Copyright (C) 2019,2023 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
      27  htmlescape (const char *restrict src, const Dwg_Codepage cp)
      28  {
      29    size_t len;
      30    char *dest, *d, *end;
      31    unsigned char *s;
      32    if (!src)
      33      return NULL;
      34    len = strlen (src) + 10;
      35    d = (char *)calloc (len, 1);
      36    s = (unsigned char *)src;
      37    dest = d;
      38    end = dest + len;
      39    while (*s)
      40      {
      41        if (end - d <= 8)
      42          {
      43            const int off = d - dest;
      44            char *newdest = (char *)realloc (dest, len + 10);
      45            if (!newdest)
      46              return NULL;
      47            dest = newdest;
      48            len += 10;
      49            d = dest + off;
      50            *d = 0;
      51            end = dest + len;
      52          }
      53        switch (*s)
      54          {
      55          case '"':
      56            strcat (d, "&quot;");
      57            d += 6;
      58            break;
      59          case '\'':
      60            strcat (d, "&#39;");
      61            d += 5;
      62            break;
      63          case '`':
      64            strcat (d, "&#96;");
      65            d += 5;
      66            break;
      67          case '&':
      68            strcat (d, "&amp;");
      69            d += 5;
      70            break;
      71          case '<':
      72            strcat (d, "&lt;");
      73            d += 4;
      74            break;
      75          case '>':
      76            strcat (d, "&gt;");
      77            d += 4;
      78            break;
      79          case '{':
      80            strcat (d, "&#123;");
      81            d += 6;
      82            break;
      83          case '}':
      84            strcat (d, "&#125;");
      85            d += 6;
      86            break;
      87          default:
      88            {
      89              uint16_t cc = *s;
      90              wchar_t wc;
      91              if (dwg_codepage_is_twobyte (cp, *s))
      92                cc = cc << 8 | *++s;
      93              wc = dwg_codepage_uwc (cp, cc);
      94              if (wc > 127 || wc < 0x20)
      95                {
      96                  sprintf (d, "&#x%X;", (unsigned)wc); // 4 + 4
      97                  d += strlen (d);
      98                }
      99              else
     100                {
     101                  *d++ = *s;
     102                }
     103              *d = 0;
     104            }
     105          }
     106        s++;
     107      }
     108    *d = 0;
     109    return dest;
     110  }
     111  
     112  char *ATTRIBUTE_MALLOC
     113  htmlwescape (BITCODE_TU wstr)
     114  {
     115    int len = 0;
     116    char *dest, *d;
     117    BITCODE_TU tmp = wstr;
     118    BITCODE_RS c;
     119  
     120    if (!wstr)
     121      return NULL;
     122    while ((c = *tmp++))
     123      len++;
     124    len += 16;
     125    d = dest = (char *)calloc (len, 1);
     126  
     127    while (*wstr)
     128      {
     129        const int off = d - dest;
     130        if (off >= len - 8)
     131          {
     132            char *newdest = (char *)realloc (dest, len + 16);
     133            if (!newdest)
     134              return NULL;
     135            dest = newdest;
     136            len += 16;
     137            d = dest + off;
     138            *d = 0;
     139          }
     140        switch (*wstr)
     141          {
     142          case 34:
     143            strcat (d, "&quot;");
     144            d += 6;
     145            break;
     146          case 39:
     147            strcat (d, "&#39;");
     148            d += 5;
     149            break;
     150          case 38:
     151            strcat (d, "&amp;");
     152            d += 5;
     153            break;
     154          case 60:
     155            strcat (d, "&lt;");
     156            d += 4;
     157            break;
     158          case 62:
     159            strcat (d, "&gt;");
     160            d += 4;
     161            break;
     162          case 96:
     163            strcat (d, "&#96;");
     164            d += 5;
     165            break;
     166          case 123:
     167            strcat (d, "&#123;");
     168            d += 6;
     169            break;
     170          case 125:
     171            strcat (d, "&#125;");
     172            d += 6;
     173            break;
     174          default:
     175            if (*wstr >= 127 || *wstr < 20) // utf8 encodings
     176              {
     177                sprintf (d, "&#x%X;", *wstr);
     178                d += strlen (d);
     179                *d = 0;
     180              }
     181            else
     182              {
     183                *d++ = *wstr;
     184                *d = 0;
     185              }
     186          }
     187        wstr++;
     188      }
     189    *d = 0;
     190    return dest;
     191  }