Ignore:
Timestamp:
Sep 26, 2016, 2:01:27 AM (9 years ago)
Author:
dmik
Message:

Fix processing of command line provided by kLIBC executables.

This fixes two problems:

  • Breaking arguments with spaces into multiple arguments instead of one.
  • Losing double quotes which are part of argument's contents.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/wprocess.cpp

    r22015 r22131  
    15501550    APIRET  rc;                         /* OS/2 return code. */
    15511551    BOOL    fQuotes;                    /* Flag used to remember if the exe filename should be in quotes. */
     1552    BOOL    fKLIBC;
    15521553    LPWSTR *argvW;
    15531554    int     i;
     
    16341635        {
    16351636            psz2 = pib_pchcmd + strlen(pib_pchcmd) + 1;
     1637#ifdef __KLIBC__
     1638            /* kLIBC spawn() detects if the process it starts is a kLIBC process
     1639             * and uses special hidden command line arguments to pass additional
     1640             * info to it which are then removed before passing arguments to
     1641             * main(). Since we don't have global argc/argv pointers in kLIBC,
     1642             * we can't access them here and have to cut out these hidden args
     1643             * Yes, it's implementation dependent -- needs to be changed when
     1644             * kLIBC 0.7 (which contains glibal argc/argv) comes out.
     1645             */
     1646            fKLIBC = strcmp(psz2, __KLIBC_ARG_SIGNATURE) == 0;
     1647            if (fKLIBC)
     1648                psz2 += strlen(psz2) + 1;
     1649#else
     1650            fKLIBC = FALSE;
     1651#endif
    16361652            while (*psz2 != '\0')
    16371653            {
    1638                 register int cchTmp = strlen(psz2) + 1; /* + 1 is for terminator (psz2) and space (cch). */
    1639                 psz2 += cchTmp;
    1640                 cch += cchTmp;
     1654                /* if the first byte is a kLIBC flag, skip it */
     1655                if (fKLIBC)
     1656                    psz2++;
     1657                ULONG cchTmp = strlen(psz2);
     1658                BOOL fArgQuotes = fKLIBC ? strchr(psz2, ' ') != NULL : FALSE;
     1659                ULONG nSlashes = 0;
     1660                if (fKLIBC)
     1661                {
     1662                    /* calculate quotes to escape them with '\' */
     1663                    while (*psz2)
     1664                        if (*psz2++ == '"')
     1665                            ++nSlashes;
     1666                    ++psz2;
     1667                }
     1668                else
     1669                {
     1670                    psz2 += cchTmp + 1;
     1671                }
     1672                cch += cchTmp + 1 /* space */ + (fArgQuotes ? 2 : 0) + nSlashes;
    16411673            }
     1674            ++cch; /* terminating null */
    16421675        }
    16431676
     
    16681701        {
    16691702            psz2 = pib_pchcmd + strlen(pib_pchcmd) + 1;
    1670 
    1671 #ifdef __KLIBC__
    1672             // kLIBC spawn() detects if the process it starts is a kLIBC process
    1673             // and uses special hidden command line arguments to pass additional
    1674             // info to it which are then removed before passing arguments to
    1675             // main(). Since we don't have global argc/argv pointers in kLIBC,
    1676             // we can't access them here and have to cut out these hidden args
    1677             // Yes, it's implementation dependent -- needs to be changed when
    1678             // kLIBC 0.7 (which contains glibal argc/argv) comes out.
    1679             bool isKLIBC = strcmp(psz2, __KLIBC_ARG_SIGNATURE) == 0;
    1680             if (isKLIBC)
     1703            /* See above */
     1704            if (fKLIBC)
    16811705                psz2 += strlen(psz2) + 1;
    1682 #endif
    16831706            while (*psz2 != '\0')
    16841707            {
    1685 #ifdef __KLIBC__
    1686                 // if the first byte is a kLIBC flag, skip it
    1687                 if (isKLIBC)
     1708                /* if the first byte is a kLIBC flag, skip it */
     1709                if (fKLIBC)
    16881710                    psz2++;
    1689 #endif
    1690                 register int cchTmp = strlen(psz2) + 1; /* + 1 is for terminator (psz). */
     1711                ULONG cchTmp = strlen(psz2);
     1712                BOOL fArgQuotes = fKLIBC ? strchr(psz2, ' ') != NULL : FALSE;
    16911713                *psz++ = ' ';           /* add space */
    1692                 memcpy(psz, psz2, cchTmp);
    1693                 psz2 += cchTmp;
    1694                 psz += cchTmp - 1;
     1714                if (fArgQuotes)
     1715                    *psz++ = '"';
     1716                if (fKLIBC)
     1717                {
     1718                    while (*psz2)
     1719                    {
     1720                        /* escape quotes with '\' */
     1721                        if (*psz2 == '"')
     1722                            *psz++ = '\\';
     1723                        *psz++ = *psz2++;
     1724                    }
     1725                    psz2++;
     1726                }
     1727                else
     1728                {
     1729                    memcpy(psz, psz2, cchTmp);
     1730                    psz += cchTmp;
     1731                    psz2 += cchTmp + 1;
     1732                }
     1733                if (fArgQuotes)
     1734                    *psz++ = '"';
    16951735            }
     1736            *psz = '\0';
    16961737        }
    16971738    }
Note: See TracChangeset for help on using the changeset viewer.