Ignore:
Timestamp:
Sep 26, 2016, 1:46:17 PM (9 years ago)
Author:
pr
Message:

Fix quoting and allow escapes. Bug 1244.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/branch-1-0/src/helpers/stringh.c

    r335 r427  
    2323
    2424/*
    25  *      Copyright (C) 1997-2006 Ulrich M”ller.
     25 *      Copyright (C) 1997-2016 Ulrich M”ller.
    2626 *      Parts Copyright (C) 1991-1999 iMatix Corporation.
    2727 *      This file is part of the "XWorkplace helpers" source package.
     
    180180}
    181181
     182/*
     183 *@@ strhCopyBuf:
     184 *      copies pcszSource to pszTarget, taking
     185 *      its length into account.
     186 *
     187 *      Returns:
     188 *
     189 *      --  NO_ERROR
     190 *
     191 *      --  ERROR_INVALID_PARAMETER: pcszSource is
     192 *          null or points to a null byte.
     193 *
     194 *      --  ERROR_FILENAME_EXCED_RANGE: pcszSource
     195 *          is too long to fit into pszTarget.
     196 *
     197 *@@added V1.0.1 (2003-01-05) [umoeller]
     198 */
     199
     200APIRET strhCopyBuf(PSZ pszTarget,
     201                   PCSZ pcszSource,
     202                   ULONG cbTarget)
     203{
     204    ULONG cb;
     205    if (!pcszSource || !*pcszSource)
     206        return ERROR_INVALID_PARAMETER;
     207    cb = strlen(pcszSource) + 1;
     208    if (cb > cbTarget)
     209        return ERROR_FILENAME_EXCED_RANGE;
     210
     211    memcpy(pszTarget,
     212           pcszSource,
     213           cb);
     214    return NO_ERROR;
     215}
     216
    182217#ifdef __DEBUG_MALLOC_ENABLED__
    183218
     
    220255 *@@ strhdup:
    221256 *      like strdup, but this one doesn't crash if pszSource
    222  *      is NULL, but returns NULL also. In addition, this
     257 *      is NULL. Instead, this returns NULL if pcszSource is
     258 *      NULL or points to a null byte. In addition, this
    223259 *      can report the length of the string (V0.9.16).
    224260 *
     
    376412
    377413/*
     414 *@@ strlcpy:
     415 *      copies src to string dst of size siz.  At most siz-1 characters
     416 *      will be copied.  Always NUL terminates, unless siz == 0.
     417 *
     418 *      Returns strlen(src); if retval >= siz, truncation occurred.
     419 *
     420 *      Taken from the OpenBSD sources at
     421 *
     422 +          ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.c
     423 *
     424 *      Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
     425 *      All rights reserved.
     426 *
     427 *      OpenBSD licence applies (see top of that file).
     428 *
     429 *@@added V1.0.1 (2003-01-29) [umoeller]
     430 */
     431
     432size_t strlcpy(char *dst,
     433               const char *src,
     434               size_t siz)
     435{
     436    register char       *d = dst;
     437    register const char *s = src;
     438    register size_t     n = siz;
     439
     440    /* Copy as many bytes as will fit */
     441    if (n != 0 && --n != 0)
     442    {
     443        do
     444        {
     445            if ((*d++ = *s++) == 0)
     446                break;
     447        } while (--n != 0);
     448    }
     449
     450    /* Not enough room in dst, add NUL and traverse rest of src */
     451    if (n == 0)
     452    {
     453        if (siz != 0)
     454            *d = '\0';      /* NUL-terminate dst */
     455        while (*s++)
     456            ;
     457    }
     458
     459    return (s - src - 1);    /* count does not include NUL */
     460}
     461
     462/*
     463 *@@ strlcat:
     464 *      appends src to string dst of size siz. Unlike strncat,
     465 *      siz is the full size of dst, not space left. At most
     466 *      siz-1 characters will be copied.  Always NUL terminates,
     467 *      unless siz <= strlen(dst).
     468 *
     469 *      Returns strlen(src) + MIN(siz, strlen(initial dst)),
     470 *      in other words, strlen(dst) after the concatenation.
     471 *      If retval >= siz, truncation occurred.
     472 *
     473 *      Taken from the OpenBSD sources at
     474 *
     475 +          ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcat.c
     476 *
     477 *      Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
     478 *      All rights reserved.
     479 *
     480 *      OpenBSD licence applies (see top of that file).
     481 *
     482 *@@added V1.0.1 (2003-01-29) [umoeller]
     483 */
     484
     485size_t strlcat(char *dst,
     486               const char *src,
     487               size_t siz)
     488{
     489    register char       *d = dst;
     490    register const char *s = src;
     491    register size_t     n = siz;
     492    size_t              dlen;
     493
     494    /* Find the end of dst and adjust bytes left but don't go past end */
     495    while (n-- != 0 && *d != '\0')
     496        d++;
     497    dlen = d - dst;
     498    n = siz - dlen;
     499
     500    if (n == 0)
     501        return(dlen + strlen(s));
     502    while (*s != '\0')
     503    {
     504        if (n != 1)
     505        {
     506            *d++ = *s;
     507            n--;
     508        }
     509        s++;
     510    }
     511    *d = '\0';
     512
     513    return (dlen + (s - src));   /* count does not include NUL */
     514}
     515
     516/*
    378517 *@@ strhlen:
    379518 *      like strlen, but doesn't crash on
     
    407546{
    408547    if (pcsz) //  && *pcsz) // V0.9.18 (2002-03-27) [umoeller]
    409         return (strlen(pcsz) + 1);
     548        return strlen(pcsz) + 1;
    410549
    411550    return 0;
     
    420559                CHAR c)
    421560{
    422     PSZ         p = (PSZ)pszSearch;
    423     ULONG       ulCount = 0;
     561    PCSZ    p = pszSearch;
     562    ULONG   ulCount = 0;
    424563    while (TRUE)
    425564    {
    426         p = strchr(p, c);
    427         if (p)
    428         {
    429             ulCount++;
    430             p++;
    431         }
    432         else
    433             break;
    434     }
    435     return ulCount;
     565        if (!(p = strchr(p, c)))
     566            return ulCount;
     567
     568        ulCount++;
     569        p++;
     570    }
    436571}
    437572
     
    10281163        *pulOffset = prc - pcszSearchIn;
    10291164
    1030     return ((PSZ)prc);
     1165    return (PSZ)prc;
    10311166}
    10321167
     
    11311266
    11321267/*
     1268 *@@ strhKillChar:
     1269 *      removes the first occurence of c in psz
     1270 *      by overwriting it with the following characters.
     1271 *
     1272 *      For this to work, you _must_ pass in strlen(psz)
     1273 *      in the ULONG pointed to by ulLength. If
     1274 *
     1275 *      Returns TRUE only if c was actually found. In
     1276 *      that case, *pulLength is decremented.
     1277 *
     1278 *@@added V1.0.1 (2003-01-30) [umoeller]
     1279 */
     1280
     1281BOOL strhKillChar(PSZ psz,
     1282                  CHAR c,
     1283                  PULONG pulLength)
     1284{
     1285    PSZ p;
     1286    if (p = strchr(psz, c))
     1287    {
     1288        // "string~rest"
     1289        //  ÀÄÄÄÄÄÙ 6 chars (p - pszBuf)
     1290        //  ÀÄÄÄÄÄÄÄÄÄÄÙ 11 chars (ulLen)
     1291        //        ^ p (pszBuf + 6)
     1292        //  ^ pszBuf
     1293        memmove(p,                      // pszBuf + 6
     1294                p + 1,                  // pszBuf + 7
     1295                // include null byte
     1296                  *pulLength            // 11
     1297                - (p - psz));           // - 6 = 5
     1298        --(*pulLength);
     1299
     1300        return TRUE;
     1301    }
     1302
     1303    return FALSE;
     1304}
     1305
     1306/*
    11331307 * strhFindAttribValue:
    11341308 *      searches for pszAttrib in pszSearchIn; if found,
     
    11481322 *@@changed WarpIN V1.0.11 (2006-08-29) [pr]: handle attrib names in quoted strings @@fixes 718
    11491323 *@@changed WarpIN V1.0.12 (2006-09-07) [pr]: fix attrib handling again @@fixes 718 @@fixes 836
     1324 *@@changed WarpIN V1.0.23 (2016-09-23) [pr]: fix single quote handling and allow escaping @@fixes 1244
    11501325 */
    11511326
     
    11571332           ulLength = strlen(pszSearchIn);
    11581333    BOOL   fInQuote = FALSE;
     1334    CHAR   cQuote = '\0', cPrev = '\0';
    11591335
    11601336    // use alloca(), so memory is freed on function exit
     
    11651341    for (p = pszSearchIn2;   *p == '\'' || *p == '"'  || *p == ' '
    11661342                          || *p == '\n' || *p == '\r' || *p == '\t'; p++);
    1167     for (pszStart = p; *p; p++)
     1343    for (pszStart = p; *p; cPrev = *(p++))
    11681344    {
    11691345        if (fInQuote)
    11701346        {
    11711347            // V1.0.12 (2006-09-07) [pr]: allow end of line to terminate a (broken) quote
    1172             if (*p == '"' || *p == '\n' || *p == '\r')
     1348            if ((*p == cQuote && cPrev != '\\') || *p == '\n' || *p == '\r')
    11731349                fInQuote = FALSE;
    11741350        }
    11751351        else
    11761352        {
    1177             if (*p == '"')
     1353            if (*p == '"' || *p == '\'')
     1354            {
    11781355                fInQuote = TRUE;
     1356                cQuote = *p;
     1357            }
    11791358            else
    11801359            {
     
    12741453 *@@added V0.9.0 [umoeller]
    12751454 *@@changed V1.0.13 (2006-09-10) [pr]: improved parsing
     1455 *@@changed WarpIN V1.0.23 (2016-09-23) [pr]: allow escaping @@fixes 1244
    12761456 */
    12771457
     
    12891469    {
    12901470        // determine end character to search for: a space
    1291         CHAR cEnd = ' ';
     1471        CHAR cEnd = ' ', cPrev = '\0';
    12921472        // V1.0.3 (2004-11-10) [pr]: @@fixes 461
    12931473        // V1.0.13 (2006-09-10) [pr]: optimized
    1294         if ((*pParam == '\"') || (*pParam == '\''))
     1474        if ((*pParam == '"') || (*pParam == '\''))
    12951475        {
    12961476            // or, if the data is enclosed in quotes, a quote or single quote
     
    13101490            if (   (   (cEnd == ' ')
    13111491                    && ((*pParam == ' ') || (*pParam == '\r') || (*pParam == '\n')))
    1312                 || (*pParam == cEnd)
     1492                || ((*pParam == cEnd) && (cPrev != '\\'))
    13131493               )
    13141494                // end character found
     
    13251505                    break;
    13261506            }
     1507
    13271508            ulCount++;
    1328             pParam++;
    1329         }
    1330 
    1331         // copy attribute to new buffer
    1332         if (ulCount)
    1333         {
    1334             prc = (PSZ)malloc(ulCount+1);
    1335             memcpy(prc, pParam2, ulCount);
    1336             *(prc+ulCount) = 0;
     1509            cPrev = *(pParam++);
     1510        }
     1511
     1512        // copy attribute to new buffer, de-escaping if necessary
     1513        if (ulCount && (prc = (PSZ) malloc(ulCount+1)))
     1514        {
     1515            ULONG i = 0, j = 0;
     1516
     1517            for(cPrev = '\0'; i < ulCount; ++i, ++j)
     1518            {
     1519                if (cEnd != ' ' && pParam2[i] == cEnd && cPrev == '\\')
     1520                    --j;
     1521
     1522                cPrev = prc[j] = pParam2[i];
     1523            }
     1524
     1525            prc[j] = '\0';
    13371526        }
    13381527    }
     
    18312020
    18322021    if (pattern_size == 0)              //  Empty patterns match at start
    1833         return ((void *)block);
     2022        return (void*)block;
    18342023
    18352024    //  Build the shift table unless we're continuing a previous search
     
    18772066            // If we found a match, return the start address
    18782067            if (match_size >= pattern_size)
    1879                 return ((void*)(match_base));
     2068                return (void*)match_base;
    18802069
    18812070        }
     
    19352124
    19362125    if (pattern_size == 0)              //  Empty string matches at start
    1937         return (char *) string;
     2126        return (char*)string;
    19382127
    19392128    //  Build the shift table
     
    19732162            //  If we found a match, return the start address
    19742163            if (match_size >= pattern_size)
    1975                 return ((char *)(match_base));
     2164                return (char*)match_base;
    19762165          }
    19772166      }
     2167
    19782168    return NULL;                      //  Found nothing
    19792169}
    19802170
     2171
Note: See TracChangeset for help on using the changeset viewer.