Changeset 117 for trunk/dll/literal.c


Ignore:
Timestamp:
Dec 5, 2004, 1:11:52 AM (21 years ago)
Author:
root
Message:

Rework fixup to avoid overflows

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/dll/literal.c

    r2 r117  
     1
     2/***********************************************************************
     3
     4  $Id$
     5
     6  string quoting utilities
     7  wildcarding utilities
     8
     9  Copyright (c) 1993-98 M. Kimes
     10  Copyright (c) 2004 Steven H.Levine
     11
     12  Archive containers
     13
     14  Revisions     01 Aug 04 SHL - Rework fixup to avoid overflows
     15
     16***********************************************************************/
     17
    118#define INCL_OS2
    219#define INCL_WIN
     
    926#include "fm3dll.h"
    1027
     28static INT index(const CHAR *s,const CHAR c);
     29
    1130#pragma alloc_text(LITERAL,literal,index,fixup,wildcard)
    1231
    13 
    14 INT index (const CHAR *s,const CHAR c) {
    15 
     32/* Get index of char in string
     33 * @parm s string to search
     34 * @parm c char to search for
     35 * @return 0 relative index of c in s or -1
     36 */
     37
     38static INT index(const CHAR *s,const CHAR c)
     39{
    1640    CHAR *p;
    1741
     
    2246}
    2347
    24 
    25 /*
    26  * literal.c
    27  * Translate a string with tokens in it according to several conventions:
     48/* Translate a string with \ escape tokens to binary equivalent
     49 * Translates in place
     50 *
    2851 * 1.  \x1b translates to CHAR(0x1b)
    2952 * 2.  \27  translates to CHAR(27)
     
    4871#define DEC "0123456789"
    4972
    50 INT literal (CHAR *fsource) {
    51 
    52   register INT wpos,w;
    53   INT          len,oldw;
    54   CHAR        *fdestin,*freeme,wchar;
    55 
    56   if(!fsource ||
    57      !*fsource)
     73UINT literal(PSZ pszBuf)
     74{
     75  INT   wpos;
     76  INT   iBuf;
     77  UINT  cBufBytes;
     78  INT   iBufSave;
     79  PSZ   pszOut;
     80  PSZ   pszWork;
     81  CHAR  wchar;
     82
     83  if(!pszBuf || !*pszBuf)
    5884    return 0;
    59   len = strlen(fsource) + 1;
    60   freeme = fdestin = malloc(len + 1);
    61   memset(fdestin,0,len);              /* start out with zero'd string */
    62 
    63   w = 0;                              /* set index to first character */
    64   while(fsource[w]) {                 /* until end of string */
    65     switch(fsource[w]) {
     85  cBufBytes = strlen(pszBuf) + 1;
     86  pszWork = pszOut = malloc(cBufBytes + 1);
     87
     88  iBuf = 0;                             /* set index to first character */
     89  while(pszBuf[iBuf]) {
     90    switch(pszBuf[iBuf]) {
    6691      case '\\':
    67         switch(fsource[w + 1]) {
    68           case 'x' :                  /* hexadecimal */
    69             wchar = 0;
    70             w += 2;                   /* get past "\x" */
    71             if(index(HEX,(CHAR)toupper(fsource[w])) != -1) {
    72               oldw = w;
    73               while(((wpos = index(HEX,(CHAR)toupper(fsource[w]))) != -1) &&
    74                     w < oldw + 2) {
    75                 wchar = (CHAR)(wchar << 4) + (CHAR)wpos;
    76                 w++;
    77               }
    78             }
    79             else
    80               wchar = 'x';            /* just an x */
    81             w--;
    82             *fdestin++ = wchar;
    83             break;
    84 
    85           case '\\' :                 /* we want a "\" */
    86             w++;
    87             *fdestin++ = '\\';
    88             break;
    89 
    90           case 't' :                  /* tab CHAR */
    91             w++;
    92             *fdestin++ = '\t';
    93             break;
    94 
    95           case 'n' :                  /* new line */
    96             w++;
    97             *fdestin++ = '\n';
    98             break;
    99 
    100           case 'r' :                  /* carr return */
    101             w++;
    102             *fdestin++ = '\r';
    103             break;
    104 
    105           case 'b' :                  /* back space */
    106             w++;
    107             *fdestin++ = '\b';
    108             break;
    109 
    110           case 'f':                   /* formfeed */
    111             w++;
    112             *fdestin++ = '\x0c';
    113             break;
    114 
    115           case 'a':                   /* bell */
    116             w++;
    117             *fdestin++ = '\07';
    118             break;
    119 
    120           case '\'' :                 /* single quote */
    121             w++;
    122             *fdestin++ = '\'';
    123             break;
    124 
    125           case '\"' :                 /* double quote */
    126             w++;
    127             *fdestin++ = '\"';
    128             break;
    129 
    130           default :                   /* decimal */
    131             w++;                      /* get past "\" */
    132             wchar = 0;
    133             if(index(DEC,fsource[w]) != -1) {
    134               oldw = w;
    135               do {                    /* cvt to binary */
    136                 wchar = (CHAR)(wchar * 10 + (fsource[w++] - 48));
    137               } while (index(DEC,fsource[w]) != -1 && w < oldw + 3);
    138               w--;
    139             }
    140             else
    141               wchar = fsource[w];
    142             *fdestin ++ = wchar;
    143             break;
    144         }
    145         break;
     92        switch(pszBuf[iBuf + 1]) {
     93          case 'x' :                    /* hexadecimal */
     94            wchar = 0;
     95            iBuf += 2;                  /* get past "\x" */
     96            if(index(HEX,(CHAR)toupper(pszBuf[iBuf])) != -1) {
     97              iBufSave = iBuf;
     98              while(((wpos = index(HEX,(CHAR)toupper(pszBuf[iBuf]))) != -1) &&
     99                    iBuf < iBufSave + 2) {
     100                wchar = (CHAR)(wchar << 4) + (CHAR)wpos;
     101                iBuf++;
     102              }
     103            }
     104            else
     105              wchar = 'x';              /* just an x */
     106            iBuf--;
     107            *pszOut++ = wchar;
     108            break;
     109
     110          case '\\' :                   /* we want a "\" */
     111            iBuf++;
     112            *pszOut++ = '\\';
     113            break;
     114
     115          case 't' :                    /* tab CHAR */
     116            iBuf++;
     117            *pszOut++ = '\t';
     118            break;
     119
     120          case 'n' :                    /* new line */
     121            iBuf++;
     122            *pszOut++ = '\n';
     123            break;
     124
     125          case 'r' :                    /* carr return */
     126            iBuf++;
     127            *pszOut++ = '\r';
     128            break;
     129
     130          case 'b' :                    /* back space */
     131            iBuf++;
     132            *pszOut++ = '\b';
     133            break;
     134
     135          case 'f':                     /* formfeed */
     136            iBuf++;
     137            *pszOut++ = '\x0c';
     138            break;
     139
     140          case 'a':                     /* bell */
     141            iBuf++;
     142            *pszOut++ = '\07';
     143            break;
     144
     145          case '\'' :                   /* single quote */
     146            iBuf++;
     147            *pszOut++ = '\'';
     148            break;
     149
     150          case '\"' :                   /* double quote */
     151            iBuf++;
     152            *pszOut++ = '\"';
     153            break;
     154
     155          default :                     /* decimal */
     156            iBuf++;                     /* get past "\" */
     157            wchar = 0;
     158            if(index(DEC,pszBuf[iBuf]) != -1) {
     159              iBufSave = iBuf;
     160              do {                      /* cvt to binary */
     161                wchar = (CHAR)(wchar * 10 + (pszBuf[iBuf++] - 48));
     162              } while (index(DEC,pszBuf[iBuf]) != -1 && iBuf < iBufSave + 3);
     163              iBuf--;
     164            }
     165            else
     166              wchar = pszBuf[iBuf];
     167            *pszOut ++ = wchar;
     168            break;
     169        } // switch
     170        break;
    146171
    147172      default :
    148         *fdestin++ = fsource[w];
    149         break;
    150    }
    151    w++;
    152   }
    153   *fdestin = 0;                               /* terminate the string */
    154 
    155   len = fdestin - freeme;
    156   memcpy(fsource,freeme,len + 1);             /* swap 'em */
    157   free(freeme);
    158 
    159   return len;                                 /* return length of string */
    160 }
    161 
    162 
    163 
    164 INT wildcard (const CHAR *fstra,const CHAR *fcarda,const BOOL notfile) {
    165 
    166   /* returns TRUE if match */
    167 
    168   register const CHAR *fstr = fstra,*fcard = fcarda;
    169   register INT         wmatch = TRUE;
     173        *pszOut++ = pszBuf[iBuf];
     174        break;
     175   } // switch
     176   iBuf++;
     177  } // while
     178  *pszOut = 0;  /* terminate the string */
     179
     180  cBufBytes = pszOut - pszWork;         /* Calc string length */
     181  memcpy(pszBuf,pszWork,cBufBytes + 1); /* Overwrite including terminator */
     182  free(pszWork);
     183
     184  return cBufBytes;                     /* return string length */
     185}
     186
     187/* Check wildcard match
     188 * @parm pszBuf Buffer to check
     189 * @parm pszWildCard wildcard to match
     190 * @parm fNotFileSpec TRUE if generic match else filespec match
     191 * @return TRUE if matched else FALSE
     192 */
     193
     194
     195BOOL wildcard(const PSZ pszBuf,const PSZ pszWildCard,const BOOL fNotFileSpec)
     196{
     197  const CHAR *fstr = pszBuf;
     198  PSZ fcard = pszWildCard;
     199  INT         wmatch = TRUE;
    170200
    171201  while(wmatch && *fcard && *fstr) {
    172202    switch(*fcard) {
    173203      case '?' :                        /* character substitution */
    174         fcard++;
    175          if(notfile || (*fstr != '.' && *fstr != '/' && *fstr != '\\'))
    176            fstr++;                      /* skip (match) next character */
    177         break;
     204        fcard++;
     205         if(fNotFileSpec || (*fstr != '.' && *fstr != '/' && *fstr != '\\'))
     206           fstr++;                      /* skip (match) next character */
     207        break;
    178208
    179209      case '*' :
    180         /* find next non-wild character in wildcard */
    181         while(*fcard && (*fcard == '?' || *fcard == '*'))
    182            fcard++;
    183         if(!*fcard)   /* if last char of wildcard is *, it matches */
    184            return TRUE;
    185         /* skip until partition, match, or eos */
    186         while(*fstr && toupper(*fstr) != toupper(*fcard) &&
    187                (notfile || (*fstr != '\\' &&
    188                *fstr != '/' && *fstr != '.')))
    189            fstr++;
    190          if(!notfile && !*fstr)                   /* implicit '.' */
    191            if(*fcard == '.')
    192              fcard++;
    193         break;
     210        /* find next non-wild character in wildcard */
     211        while(*fcard && (*fcard == '?' || *fcard == '*'))
     212           fcard++;
     213        if(!*fcard)   /* if last char of wildcard is *, it matches */
     214           return TRUE;
     215        /* skip until partition, match, or eos */
     216        while(*fstr && toupper(*fstr) != toupper(*fcard) &&
     217               (fNotFileSpec || (*fstr != '\\' &&
     218               *fstr != '/' && *fstr != '.')))
     219           fstr++;
     220         if(!fNotFileSpec && !*fstr)    /* implicit '.' */
     221           if(*fcard == '.')
     222             fcard++;
     223        break;
    194224
    195225      default  :
    196          if(!notfile && ((*fstr == '/' || *fstr == '\\') &&
    197             (*fcard == '/' || *fcard == '\\')))
    198            wmatch = TRUE;
    199         else
    200            wmatch = (toupper(*fstr) == toupper(*fcard));
    201         fstr++;
    202         fcard++;
    203         break;
     226         if(!fNotFileSpec && ((*fstr == '/' || *fstr == '\\') &&
     227            (*fcard == '/' || *fcard == '\\')))
     228           wmatch = TRUE;
     229        else
     230           wmatch = (toupper(*fstr) == toupper(*fcard));
     231        fstr++;
     232        fcard++;
     233        break;
    204234    }
    205235  }
     
    212242
    213243
    214 CHAR * fixup (const CHAR *orig,CHAR *dest,const INT maxlen,const INT datalen) {
    215 
    216   register const CHAR *o = orig;
    217   register CHAR       *d = dest,*tp;
    218   CHAR                 temp[33] = "\\x";
    219 
    220   *d = 0;
    221   if(orig) {
    222     while((o - orig) <
    223            datalen &&
    224            (d - dest) < maxlen) {
    225       if(!isprint(*o)) {
    226         if(*o == '\r') {
    227           *d = '\\';
    228           d++;
    229           *d = 'r';
    230           d++;
    231         }
    232         else if(*o == '\n') {
    233           *d = '\\';
    234           d++;
    235           *d = 'n';
    236           d++;
    237         }
    238         else if(*o == '\b') {
    239           *d = '\\';
    240           d++;
    241           *d = 'b';
    242           d++;
    243         }
    244         else {
    245           sprintf(&temp[2],"%02hx",*o);
    246           tp = temp;
    247           while(*tp)
    248             *d++ = *tp++;
    249         }
    250         o++;
     244// fixup - quote literal character array
     245
     246PSZ fixup(const PCH pachIn, PSZ pszOutBuf, const UINT cBufBytes, const UINT cInBytes)
     247{
     248  PCH   pchIn = pachIn;
     249  PCH   pchOut = pszOutBuf;
     250  PSZ   pszTemp;
     251  static CHAR   szTemp[5] = "\\x";      // Constant prefix
     252
     253  // input is a character array, not a string - may not be null terminated
     254  // cBufBytes is buffer size
     255  if (pachIn) {
     256    // Ensure room for null and possible \ escape
     257    while (pchIn - pachIn < cInBytes &&
     258           pchOut - pszOutBuf + 2 < cBufBytes) {
     259      if(!isprint(*pchIn)) {
     260        if(*pchIn == '\r') {
     261          *pchOut++ = '\\';
     262          *pchOut++ = 'r';
     263        }
     264        else if(*pchIn == '\n') {
     265          *pchOut++ = '\\';
     266          *pchOut++ = 'n';
     267        }
     268        else if(*pchIn == '\b') {
     269          *pchOut++ = '\\';
     270          *pchOut++ = 'b';
     271        }
     272        else {
     273          sprintf(szTemp + 2,"%02hx",*pchIn);
     274          for (pszTemp = szTemp; *pszTemp;)
     275            *pchOut++ = *pszTemp++;
     276        }
     277        pchIn++;
    251278      }
    252       else {
    253         if(*o == '\\') {
    254           *d = '\\';
    255           d++;
    256           *d = '\\';
    257           d++;
    258           o++;
    259         }
    260         else
    261           *d++ = *o++;
     279      else if(*pchIn == '\\') {
     280        *pchOut++ = '\\';
     281        *pchOut++ = '\\';
     282        pchIn++;
    262283      }
    263       *d = 0;
    264     }
    265   }
    266   return dest;
    267 }
    268 
     284      else
     285        *pchOut++ = *pchIn++;
     286    } // while
     287  } // if pachIn
     288  *pchOut = 0;
     289  return pszOutBuf;
     290}
     291
Note: See TracChangeset for help on using the changeset viewer.