Changeset 76 for trunk/src/sh_utils.c


Ignore:
Timestamp:
Dec 19, 2006, 10:01:59 PM (13 years ago)
Author:
rainer
Message:

Fix for ticket #38 (csv escaping) and #39 (building on cygwin). Also optimize a bit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/sh_utils.c

    r68 r76  
    268268  return out;
    269269}
    270    
     270
     271
     272char * sh_util_strdup_l (const char * str, size_t len)
     273{
     274  char * p = NULL;
     275
     276  SL_ENTER(_("sh_util_strdup_l"));
     277
     278  SH_VALIDATE_NE(str, NULL);
     279  SH_VALIDATE_NE(len, 0);
     280
     281  if (sl_ok_adds (len, 1))
     282    {
     283      p   = SH_ALLOC (len + 1);
     284      (void) sl_strlcpy (p, str, len+1);
     285    }
     286  else
     287    {
     288      safe_fatal(_("integer overflow in sh_util_strdup_l"), FIL__, __LINE__);
     289    }
     290  SL_RETURN( p, _("sh_util_strdup_l"));
     291}
     292
    271293char * sh_util_strdup (const char * str)
    272294{
     
    14131435
    14141436static unsigned char sh_obscure_index[256];
     1437static int sh_obscure_no_check = S_FALSE;
    14151438
    14161439int sh_util_valid_utf8 (const unsigned char * str)
    14171440{
     1441  const int     sh_val_utf8_1 = 1;
     1442  const int     sh_val_utf8_2 = 2;
     1443  const int     sh_val_utf8_3 = 3;
     1444  const int     sh_val_utf8_4 = 4;
     1445
    14181446  size_t        len = strlen((char *)str);
    14191447  size_t        l   = 0;
    1420   unsigned char c;
     1448  int           typ = 0;
     1449  unsigned char c     = '\0';
     1450  unsigned char c2[2] = { 0x00, 0x00 };
     1451  unsigned char c3[3] = { 0x00, 0x00, 0x00 };
     1452
    14211453
    14221454#define SH_VAL_UTF8_1 ((c != '\0') && ((c & 0x80) == 0x00))
     
    14251457#define SH_VAL_UTF8_4 ((c != '\0') && ((c & 0xF8) == 0xF0)) /* 1111 0xxx */
    14261458#define SH_VAL_UTF8_N ((c != '\0') && ((c & 0xC0) == 0x80)) /* 10xx xxxx */
    1427 #define SH_VAL_BAD    ((c == '"') || (c == '\t') || (c == '\b') || (c == '\f') || (c == '\n') || \
     1459#define SH_VAL_BAD    ((c == '"')  || (c == '\t') || (c == '\b') || \
     1460                       (c == '\f') || (c == '\n') || \
    14281461                       (c == '\r') || (c == '\v') || iscntrl((int) c) || \
    14291462                       (c != ' ' && !isgraph ((int) c)))
     
    14351468      if      (SH_VAL_UTF8_1)
    14361469        {
    1437           if (SH_VAL_BAD && (sh_obscure_index[c] != 1)) return S_FALSE;
    1438           ++l; continue; /* ASCII character */
     1470          if (!(SH_VAL_BAD && (sh_obscure_index[c] != 1)))
     1471            {
     1472              typ = sh_val_utf8_1;
     1473              ++l; continue;
     1474            }
     1475          else
     1476            {
     1477              return S_FALSE;
     1478            }
    14391479        }
    14401480      else if (SH_VAL_UTF8_2)
    14411481        {
    1442           if ((c & 0x3e) == 0x00)
    1443             return S_FALSE; /* overlong 2-byte seq. */
    1444           ++l; if (l == len) return S_FALSE; c = str[l];
    1445           if(!SH_VAL_UTF8_N) return S_FALSE;
    1446           ++l; continue;
    1447          
     1482          typ = sh_val_utf8_2;
     1483          c2[0] = c;
     1484          if ((c & 0x3e) != 0x00) /* !(overlong 2-byte seq.) */
     1485            {
     1486              ++l;
     1487              if (l != len) {
     1488                c = str[l];
     1489                if(SH_VAL_UTF8_N) {
     1490                  c2[1] = c;
     1491                  ++l; continue;
     1492                }
     1493                else {
     1494                  return S_FALSE;
     1495                }
     1496              }
     1497              else {
     1498                return S_FALSE;
     1499              }
     1500            }
     1501          else
     1502            {
     1503              return S_FALSE; /* overlong 2-byte seq. */
     1504            }
    14481505        }
    14491506      else if (SH_VAL_UTF8_3)
    14501507        {
     1508          typ = sh_val_utf8_3;
     1509          c3[0] = c;
    14511510          ++l; if (l == len) return S_FALSE; c = str[l];
    14521511          if(!SH_VAL_UTF8_N) return S_FALSE;
    14531512          if (((str[l-1] & 0x1F) == 0x00) && ((c & 0x60) == 0x00))
    14541513            return S_FALSE; /* overlong 3-byte seq. */
     1514          c3[1] = c;
    14551515          ++l; if (l == len) return S_FALSE; c = str[l];
    14561516          if(!SH_VAL_UTF8_N) return S_FALSE;
     1517          c3[2] = c;
    14571518          ++l; continue;
    14581519        }
    14591520      else if (SH_VAL_UTF8_4)
    14601521        {
     1522          typ = sh_val_utf8_4;
    14611523          ++l; if (l == len) return S_FALSE; c = str[l];
    14621524          if(!SH_VAL_UTF8_N) return S_FALSE;
     
    14711533      return S_FALSE;
    14721534    }
    1473   return S_TRUE;
     1535
     1536  /* last character is invisible (space or else)
     1537   */
     1538  if (typ == sh_val_utf8_1)
     1539    {
     1540      if (c != ' ')
     1541        return S_TRUE;
     1542      else
     1543        return S_FALSE;
     1544    }
     1545  else if (typ == sh_val_utf8_2)
     1546    {
     1547      if (c2[0] == 0xC2 && c2[1] == 0xA0) /* nbsp */
     1548        return S_FALSE;
     1549      else
     1550        return S_TRUE;
     1551    }
     1552  else if (typ == sh_val_utf8_3)
     1553    {
     1554      if (c3[0] == 0xE2)
     1555        {
     1556          if (c3[1] == 0x80 && c3[2] >= 0x80 && c3[2] <= 0x8F)
     1557            return S_FALSE; /* various spaces, left-to-right, right-to-left */
     1558          else if (c3[1] == 0x80 && (c3[2] == 0xA8 || c3[2] == 0xA9 ||
     1559                                     c3[2] == 0xAD || c3[2] == 0xAF))
     1560            return S_FALSE; /* line sep, para sep, zw word joiner, nnbsp */
     1561          else if (c3[1] == 0x81 && (c3[2] == 0xA0 || c3[2] == 0xA1 ||
     1562                                     c3[2] == 0x9F))
     1563            return S_FALSE; /* word joiner, function app, math space */
     1564          else
     1565            return S_TRUE;
     1566        }
     1567      else if (c3[0] == 0xE3 && c3[1] == 0x80 && c3[2] == 0x80)
     1568        {
     1569          return S_FALSE; /* ideographic space */
     1570        }
     1571      else if (c3[0] == 0xEF && c3[1] == 0xBB && c3[2] == 0xBF)
     1572        {
     1573          return S_FALSE; /* zwnbsp */
     1574        }
     1575      else
     1576        {
     1577          return S_TRUE;
     1578        }
     1579    }
     1580  else
     1581    {
     1582      return S_TRUE;
     1583    }
    14741584}
    14751585
     
    14881598          sh_obscure_index[i] = (unsigned char)1;
    14891599        }
     1600      sh_obscure_no_check = S_TRUE;
    14901601      SL_RETURN(0, _("sh_util_obscure_ok"));
    14911602    }
     1603
     1604  sh_obscure_no_check = S_FALSE;
    14921605
    14931606  for (i = 0; i < 255; ++i)
     
    15261639  SL_ENTER(_("sh_util_obscure_utf8"));
    15271640  i = sh_util_flagval(c, &(sh_obscure_check_utf8));
    1528 
     1641  if (sh_obscure_check_utf8 == S_TRUE)
     1642    sh_obscure_no_check = S_FALSE;
    15291643  SL_RETURN(i, _("sh_util_obscure_utf8"));
    15301644}
     
    15361650  char * safe;
    15371651  unsigned int i;
     1652  size_t len = 0;
    15381653
    15391654  SL_ENTER(_("sh_util_obscurename"));
     
    15411656  ASSERT_RET((name != NULL), _("name != NULL"), (0))
    15421657
    1543   if (sh_obscure_check_utf8 == S_TRUE)
    1544     {
    1545       if (S_FALSE == sh_util_valid_utf8(name))
    1546         {
    1547           goto err;
    1548         }
    1549       SL_RETURN((0),_("sh_util_obscurename"));
    1550     }
    1551 
    1552   /* -- Check name. --
    1553    */
    1554   while (*name != '\0')
    1555     {
    1556       if ( (*name) >  0x7F || (*name) == '"'  || (*name) == '\t' ||
    1557            (*name) == '\b' || (*name) == '\f' ||
    1558            (*name) == '\n' || (*name) == '\r' ||
    1559            (*name) == '\v' || iscntrl((int) *name) ||
    1560            ((*name) != ' ' && !isgraph ((int) *name)) )
    1561         {
    1562           i = (unsigned char) *name;
    1563           if (sh_obscure_index[i] != (unsigned char)1)
     1658  if (sh_obscure_no_check == S_FALSE)
     1659    {
     1660      if (sh_obscure_check_utf8 != S_TRUE)
     1661        {
     1662          /* -- Check name. --
     1663           */
     1664          while (*name != '\0')
     1665            {
     1666              if ( (*name) >  0x7F || (*name) == '"'  || (*name) == '\t' ||
     1667                   (*name) == '\b' || (*name) == '\f' ||
     1668                   (*name) == '\n' || (*name) == '\r' ||
     1669                   (*name) == '\v' || iscntrl((int) *name) ||
     1670                   ((*name) != ' ' && !isgraph ((int) *name)) )
     1671                {
     1672                  i = (unsigned char) *name;
     1673                  if (sh_obscure_index[i] != (unsigned char)1)
     1674                    {
     1675                      goto err;
     1676                    }
     1677                }
     1678              name++; ++len;
     1679            }
     1680
     1681          /* Check for blank at end of name
     1682           */
     1683          if ((len > 0) && (name_orig[len-1] == ' '))
    15641684            {
    15651685              goto err;
    15661686            }
    15671687        }
    1568       name++;
    1569     }
    1570 
     1688      else
     1689        {
     1690          if (S_FALSE == sh_util_valid_utf8(name))
     1691            {
     1692              goto err;
     1693            }
     1694          SL_RETURN((0),_("sh_util_obscurename"));
     1695        }
     1696    }
     1697     
    15711698  SL_RETURN((0),_("sh_util_obscurename"));
    15721699
    15731700 err:
    1574 
     1701 
    15751702  if (flag == S_TRUE)
    15761703    {
     
    18221949}
    18231950
    1824 char * sh_util_strconcat (const char * arg1, ...)
     1951char * sh_util_strconcat (const char * arg1, ...) 
    18251952{
    18261953  size_t    length, l2;
Note: See TracChangeset for help on using the changeset viewer.