VirtualBox

Changeset 67391 in vbox


Ignore:
Timestamp:
Jun 14, 2017 12:13:48 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
116116
Message:

IPRT: More ISO maker code.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/mangling.h

    r67364 r67391  
    23152315# define RTUtf16PurgeComplementSet                      RT_MANGLER(RTUtf16PurgeComplementSet)
    23162316# define RTUtf16ToUtf8ExTag                             RT_MANGLER(RTUtf16ToUtf8ExTag)
     2317# define RTUtf16BigToUtf8ExTag                          RT_MANGLER(RTUtf16BigToUtf8ExTag)
    23172318# define RTUtf16ToUtf8Tag                               RT_MANGLER(RTUtf16ToUtf8Tag)
     2319# define RTUtf16BigToUtf8Tag                            RT_MANGLER(RTUtf16BigToUtf8Tag)
    23182320# define RTUtf16ValidateEncoding                        RT_MANGLER(RTUtf16ValidateEncoding)
    23192321# define RTUtf16ValidateEncodingEx                      RT_MANGLER(RTUtf16ValidateEncodingEx)
  • trunk/include/iprt/utf16.h

    r66731 r67391  
    622622 */
    623623RTDECL(int)  RTUtf16ToUtf8Tag(PCRTUTF16 pwszString, char **ppszString, const char *pszTag);
     624
     625/**
     626 * Translate a UTF-16BE string into a UTF-8 allocating the result buffer
     627 * (default tag).
     628 *
     629 * This differs from RTUtf16ToUtf8 in that the input is always a
     630 * big-endian string.
     631 *
     632 * @returns iprt status code.
     633 * @param   pwszString      UTF-16BE string to convert.
     634 * @param   ppszString      Receives pointer of allocated UTF-8 string on
     635 *                          success, and is always set to NULL on failure.
     636 *                          The returned pointer must be freed using RTStrFree().
     637 */
     638#define RTUtf16BigToUtf8(pwszString, ppszString)       RTUtf16BigToUtf8Tag((pwszString), (ppszString), RTSTR_TAG)
     639
     640/**
     641 * Translate a UTF-16BE string into a UTF-8 allocating the result buffer.
     642 *
     643 * This differs from RTUtf16ToUtf8Tag in that the input is always a
     644 * big-endian string.
     645 *
     646 * @returns iprt status code.
     647 * @param   pwszString      UTF-16BE string to convert.
     648 * @param   ppszString      Receives pointer of allocated UTF-8 string on
     649 *                          success, and is always set to NULL on failure.
     650 *                          The returned pointer must be freed using RTStrFree().
     651 * @param   pszTag          Allocation tag used for statistics and such.
     652 */
     653RTDECL(int)  RTUtf16BigToUtf8Tag(PCRTUTF16 pwszString, char **ppszString, const char *pszTag);
    624654
    625655/**
     
    674704 */
    675705RTDECL(int)  RTUtf16ToUtf8ExTag(PCRTUTF16 pwszString, size_t cwcString, char **ppsz, size_t cch, size_t *pcch, const char *pszTag);
     706
     707/**
     708 * Translates UTF-16BE to UTF-8 using buffer provided by the caller or a
     709 * fittingly sized buffer allocated by the function (default tag).
     710 *
     711 * This differs from RTUtf16ToUtf8Ex in that the input is always a
     712 * big-endian string.
     713 *
     714 * @returns iprt status code.
     715 * @param   pwszString      The UTF-16BE string to convert.
     716 * @param   cwcString       The number of RTUTF16 items to translate from pwszString.
     717 *                          The translation will stop when reaching cwcString or the terminator ('\\0').
     718 *                          Use RTSTR_MAX to translate the entire string.
     719 * @param   ppsz            If cch is non-zero, this must either be pointing to a pointer to
     720 *                          a buffer of the specified size, or pointer to a NULL pointer.
     721 *                          If *ppsz is NULL or cch is zero a buffer of at least cch chars
     722 *                          will be allocated to hold the translated string.
     723 *                          If a buffer was requested it must be freed using RTStrFree().
     724 * @param   cch             The buffer size in chars (the type). This includes the terminator.
     725 * @param   pcch            Where to store the length of the translated string,
     726 *                          excluding the terminator. (Optional)
     727 *
     728 *                          This may be set under some error conditions,
     729 *                          however, only for VERR_BUFFER_OVERFLOW and
     730 *                          VERR_NO_STR_MEMORY will it contain a valid string
     731 *                          length that can be used to resize the buffer.
     732 */
     733#define RTUtf16BigToUtf8Ex(pwszString, cwcString, ppsz, cch, pcch) \
     734    RTUtf16BigToUtf8ExTag((pwszString), (cwcString), (ppsz), (cch), (pcch), RTSTR_TAG)
     735
     736/**
     737 * Translates UTF-16BE to UTF-8 using buffer provided by the caller or a
     738 * fittingly sized buffer allocated by the function (custom tag).
     739 *
     740 * This differs from RTUtf16ToUtf8ExTag in that the input is always a
     741 * big-endian string.
     742 *
     743 * @returns iprt status code.
     744 * @param   pwszString      The UTF-16BE string to convert.
     745 * @param   cwcString       The number of RTUTF16 items to translate from pwszString.
     746 *                          The translation will stop when reaching cwcString or the terminator ('\\0').
     747 *                          Use RTSTR_MAX to translate the entire string.
     748 * @param   ppsz            If cch is non-zero, this must either be pointing to a pointer to
     749 *                          a buffer of the specified size, or pointer to a NULL pointer.
     750 *                          If *ppsz is NULL or cch is zero a buffer of at least cch chars
     751 *                          will be allocated to hold the translated string.
     752 *                          If a buffer was requested it must be freed using RTStrFree().
     753 * @param   cch             The buffer size in chars (the type). This includes the terminator.
     754 * @param   pcch            Where to store the length of the translated string,
     755 *                          excluding the terminator. (Optional)
     756 *
     757 *                          This may be set under some error conditions,
     758 *                          however, only for VERR_BUFFER_OVERFLOW and
     759 *                          VERR_NO_STR_MEMORY will it contain a valid string
     760 *                          length that can be used to resize the buffer.
     761 * @param   pszTag          Allocation tag used for statistics and such.
     762 */
     763RTDECL(int) RTUtf16BigToUtf8ExTag(PCRTUTF16 pwszString, size_t cwcString, char **ppsz, size_t cch, size_t *pcch, const char *pszTag);
    676764
    677765/**
  • trunk/src/VBox/Runtime/common/fs/iso9660vfs.cpp

    r67334 r67391  
    16571657}
    16581658
     1659/** Logging helper. */
     1660static char *rtFsIso9660VolGetMaybeUtf16Be(const char *pachField, size_t cchField, char *pszDst, size_t cbDst)
     1661{
     1662    /* Check the format by looking for zero bytes.  ISO-9660 doesn't allow zeros.
     1663       This doesn't have to be a UTF-16BE string.  */
     1664    size_t cFirstZeros  = 0;
     1665    size_t cSecondZeros = 0;
     1666    for (size_t off = 0; off < cchField; off += 2)
     1667    {
     1668        cFirstZeros  += pachField[off]     == '\0';
     1669        cSecondZeros += pachField[off + 1] == '\0';
     1670    }
     1671
     1672    int    rc     = VINF_SUCCESS;
     1673    char  *pszTmp = &pszDst[10];
     1674    size_t cchRet = 0;
     1675    if (cFirstZeros > cSecondZeros)
     1676    {
     1677        /* UTF-16BE / UTC-2BE: */
     1678        if (cchField & 1)
     1679        {
     1680            if (pachField[cchField - 1] == '\0' || pachField[cchField - 1] == ' ')
     1681                cchField--;
     1682            else
     1683                rc = VERR_INVALID_UTF16_ENCODING;
     1684        }
     1685        if (RT_SUCCESS(rc))
     1686        {
     1687            while (   cchField >= 2
     1688                   && pachField[cchField - 1] == ' '
     1689                   && pachField[cchField - 2] == '\0')
     1690                cchField -= 2;
     1691
     1692            rc = RTUtf16BigToUtf8Ex((PCRTUTF16)pachField, cchField / sizeof(RTUTF16), &pszTmp, cbDst - 10 - 1, &cchRet);
     1693        }
     1694        if (RT_SUCCESS(rc))
     1695        {
     1696            pszDst[0] = 'U';
     1697            pszDst[1] = 'T';
     1698            pszDst[2] = 'F';
     1699            pszDst[3] = '-';
     1700            pszDst[4] = '1';
     1701            pszDst[5] = '6';
     1702            pszDst[6] = 'B';
     1703            pszDst[7] = 'E';
     1704            pszDst[8] = ':';
     1705            pszDst[9] = '\'';
     1706            pszDst[10 + cchRet] = '\'';
     1707            pszDst[10 + cchRet + 1] = '\0';
     1708        }
     1709        else
     1710            RTStrPrintf(pszDst, cbDst, "UTF-16BE: %.*Rhxs", cchField, pachField);
     1711    }
     1712    else if (cSecondZeros > 0)
     1713    {
     1714        /* Little endian UTF-16 / UCS-2 (ASSUMES host is little endian, sorry) */
     1715        if (cchField & 1)
     1716        {
     1717            if (pachField[cchField - 1] == '\0' || pachField[cchField - 1] == ' ')
     1718                cchField--;
     1719            else
     1720                rc = VERR_INVALID_UTF16_ENCODING;
     1721        }
     1722        if (RT_SUCCESS(rc))
     1723        {
     1724            while (   cchField >= 2
     1725                   && pachField[cchField - 1] == '\0'
     1726                   && pachField[cchField - 2] == ' ')
     1727                cchField -= 2;
     1728
     1729            rc = RTUtf16ToUtf8Ex((PCRTUTF16)pachField, cchField / sizeof(RTUTF16), &pszTmp, cbDst - 10 - 1, &cchRet);
     1730        }
     1731        if (RT_SUCCESS(rc))
     1732        {
     1733            pszDst[0] = 'U';
     1734            pszDst[1] = 'T';
     1735            pszDst[2] = 'F';
     1736            pszDst[3] = '-';
     1737            pszDst[4] = '1';
     1738            pszDst[5] = '6';
     1739            pszDst[6] = 'L';
     1740            pszDst[7] = 'E';
     1741            pszDst[8] = ':';
     1742            pszDst[9] = '\'';
     1743            pszDst[10 + cchRet] = '\'';
     1744            pszDst[10 + cchRet + 1] = '\0';
     1745        }
     1746        else
     1747            RTStrPrintf(pszDst, cbDst, "UTF-16LE: %.*Rhxs", cchField, pachField);
     1748    }
     1749    else
     1750    {
     1751        /* ASSUME UTF-8/ASCII. */
     1752        while (   cchField > 0
     1753               && pachField[cchField - 1] == ' ')
     1754            cchField--;
     1755        int rc = RTStrValidateEncodingEx(pachField, cchField, RTSTR_VALIDATE_ENCODING_EXACT_LENGTH);
     1756        if (RT_SUCCESS(rc))
     1757            RTStrPrintf(pszDst, cbDst, "UTF-8: '%.*s'", cchField, pachField);
     1758        else
     1759            RTStrPrintf(pszDst, cbDst, "UNK-8: %.*Rhxs", cchField, pachField);
     1760    }
     1761    return pszDst;
     1762}
     1763
    16591764
    16601765/**
     
    16671772    if (LogIs2Enabled())
    16681773    {
     1774        char szTmp[384];
    16691775        Log2(("ISO9660:  fVolumeFlags:              %#RX8\n", pVolDesc->fVolumeFlags));
    1670         Log2(("ISO9660:  achSystemId:               '%.*s'\n", rtFsIso9660VolGetStrippedLength(pVolDesc->achSystemId, sizeof(pVolDesc->achSystemId)), pVolDesc->achSystemId));
    1671         Log2(("ISO9660:  achVolumeId:               '%.*s'\n", rtFsIso9660VolGetStrippedLength(pVolDesc->achVolumeId, sizeof(pVolDesc->achVolumeId)), pVolDesc->achVolumeId));
     1776        Log2(("ISO9660:  achSystemId:               %s\n", rtFsIso9660VolGetMaybeUtf16Be(pVolDesc->achSystemId, sizeof(pVolDesc->achSystemId), szTmp, sizeof(szTmp)) ));
     1777        Log2(("ISO9660:  achVolumeId:               %s\n", rtFsIso9660VolGetMaybeUtf16Be(pVolDesc->achVolumeId, sizeof(pVolDesc->achVolumeId), szTmp, sizeof(szTmp)) ));
    16721778        Log2(("ISO9660:  Unused73:                  {%#RX32,%#RX32}\n", RT_BE2H_U32(pVolDesc->Unused73.be), RT_LE2H_U32(pVolDesc->Unused73.le)));
    16731779        Log2(("ISO9660:  VolumeSpaceSize:           {%#RX32,%#RX32}\n", RT_BE2H_U32(pVolDesc->VolumeSpaceSize.be), RT_LE2H_U32(pVolDesc->VolumeSpaceSize.le)));
     
    16811787        Log2(("ISO9660:  offTypeMPathTable:         %#RX32\n", RT_BE2H_U32(pVolDesc->offTypeMPathTable)));
    16821788        Log2(("ISO9660:  offOptionalTypeMPathTable: %#RX32\n", RT_BE2H_U32(pVolDesc->offOptionalTypeMPathTable)));
    1683         Log2(("ISO9660:  achVolumeSetId:            '%.*s'\n", rtFsIso9660VolGetStrippedLength(pVolDesc->achVolumeSetId, sizeof(pVolDesc->achVolumeSetId)), pVolDesc->achVolumeSetId));
    1684         Log2(("ISO9660:  achPublisherId:            '%.*s'\n", rtFsIso9660VolGetStrippedLength(pVolDesc->achPublisherId, sizeof(pVolDesc->achPublisherId)), pVolDesc->achPublisherId));
    1685         Log2(("ISO9660:  achDataPreparerId:         '%.*s'\n", rtFsIso9660VolGetStrippedLength(pVolDesc->achDataPreparerId, sizeof(pVolDesc->achDataPreparerId)), pVolDesc->achDataPreparerId));
    1686         Log2(("ISO9660:  achApplicationId:          '%.*s'\n", rtFsIso9660VolGetStrippedLength(pVolDesc->achApplicationId, sizeof(pVolDesc->achApplicationId)), pVolDesc->achApplicationId));
    1687         Log2(("ISO9660:  achCopyrightFileId:        '%.*s'\n", rtFsIso9660VolGetStrippedLength(pVolDesc->achCopyrightFileId, sizeof(pVolDesc->achCopyrightFileId)), pVolDesc->achCopyrightFileId));
    1688         Log2(("ISO9660:  achAbstractFileId:         '%.*s'\n", rtFsIso9660VolGetStrippedLength(pVolDesc->achAbstractFileId, sizeof(pVolDesc->achAbstractFileId)), pVolDesc->achAbstractFileId));
    1689         Log2(("ISO9660:  achBibliographicFileId:    '%.*s'\n", rtFsIso9660VolGetStrippedLength(pVolDesc->achBibliographicFileId, sizeof(pVolDesc->achBibliographicFileId)), pVolDesc->achBibliographicFileId));
     1789        Log2(("ISO9660:  achVolumeSetId:            %s\n", rtFsIso9660VolGetMaybeUtf16Be(pVolDesc->achVolumeSetId, sizeof(pVolDesc->achVolumeSetId), szTmp, sizeof(szTmp)) ));
     1790        Log2(("ISO9660:  achPublisherId:            %s\n", rtFsIso9660VolGetMaybeUtf16Be(pVolDesc->achPublisherId, sizeof(pVolDesc->achPublisherId), szTmp, sizeof(szTmp)) ));
     1791        Log2(("ISO9660:  achDataPreparerId:         %s\n", rtFsIso9660VolGetMaybeUtf16Be(pVolDesc->achDataPreparerId, sizeof(pVolDesc->achDataPreparerId), szTmp, sizeof(szTmp)) ));
     1792        Log2(("ISO9660:  achApplicationId:          %s\n", rtFsIso9660VolGetMaybeUtf16Be(pVolDesc->achApplicationId, sizeof(pVolDesc->achApplicationId), szTmp, sizeof(szTmp)) ));
     1793        Log2(("ISO9660:  achCopyrightFileId:        %s\n", rtFsIso9660VolGetMaybeUtf16Be(pVolDesc->achCopyrightFileId, sizeof(pVolDesc->achCopyrightFileId), szTmp, sizeof(szTmp)) ));
     1794        Log2(("ISO9660:  achAbstractFileId:         %s\n", rtFsIso9660VolGetMaybeUtf16Be(pVolDesc->achAbstractFileId, sizeof(pVolDesc->achAbstractFileId), szTmp, sizeof(szTmp)) ));
     1795        Log2(("ISO9660:  achBibliographicFileId:    %s\n", rtFsIso9660VolGetMaybeUtf16Be(pVolDesc->achBibliographicFileId, sizeof(pVolDesc->achBibliographicFileId), szTmp, sizeof(szTmp)) ));
    16901796        Log2(("ISO9660:  BirthTime:                 %.4s-%.2s-%.2s %.2s:%.2s:%.2s.%.2s%+03d\n",
    16911797              pVolDesc->BirthTime.achYear,
  • trunk/src/VBox/Runtime/common/fs/isomaker.cpp

    r67386 r67391  
    259259     * When not NULL, this may be pointing to heap or g_szTransTbl. */
    260260    char                   *pszTransTbl;
    261     /** The system ID (ISO9660PRIMARYVOLDESC::achSystemId).
    262      * Empty if NULL. */
     261    /** The system ID (ISO9660PRIMARYVOLDESC::achSystemId). Empty if NULL.
     262     * When not NULL, this may be pointing to heap of g_szSystemId. */
    263263    char                   *pszSystemId;
    264264    /** The volume ID / label (ISO9660PRIMARYVOLDESC::achVolumeId).
     
    589589/** The default data preparer ID for the joliet volume descriptor. */
    590590static char         g_szPreparerIdJoliet[64]     = "";
     591/** The default system ID the primary ISO-9660 volume descriptor. */
     592static char         g_szSystemId[64] = "";
     593
    591594
    592595
     
    628631    if (g_szPreparerIdPrimaryIso[0] == '\0')
    629632        RTStrPrintf(g_szPreparerIdPrimaryIso, sizeof(g_szPreparerIdPrimaryIso), "IPRT ISO MAKER V%u.%u.%u R%s",
    630                     RTBldCfgVersionMajor(), RTBldCfgVersionMinor(), RTBldCfgVersionBuild(), RTBldCfgRevision());
     633                    RTBldCfgVersionMajor(), RTBldCfgVersionMinor(), RTBldCfgVersionBuild(), RTBldCfgRevisionStr());
    631634    if (g_szPreparerIdJoliet[0] == '\0')
    632635        RTStrPrintf(g_szPreparerIdJoliet, sizeof(g_szPreparerIdJoliet),
    633                     "IPRT ISO Maker v%s r%s", RTBldCfgVersion(), RTBldCfgRevision());
     636                    "IPRT ISO Maker v%s r%s", RTBldCfgVersion(), RTBldCfgRevisionStr());
     637    if (g_szSystemId)
     638    {
     639        RTStrCopy(g_szSystemId, sizeof(g_szSystemId), RTBldCfgTargetDotArch());
     640        RTStrToUpper(g_szSystemId);
     641    }
    634642
    635643    /*
     
    650658        pThis->PrimaryIso.uRockRidgeLevel   = 1;
    651659        pThis->PrimaryIso.pszTransTbl       = (char *)g_szTransTbl;
    652         //pThis->PrimaryIso.pszSystemId       = NULL;
     660        pThis->PrimaryIso.pszSystemId       = g_szSystemId;
    653661        //pThis->PrimaryIso.pszVolumeId       = NULL;
    654662        //pThis->PrimaryIso.pszSetVolumeId    = NULL;
     
    885893    if (pNamespace->pszSystemId)
    886894    {
    887         RTMemFree(pNamespace->pszSystemId);
     895        if (pNamespace->pszSystemId != g_szSystemId)
     896            RTMemFree(pNamespace->pszSystemId);
    888897        pNamespace->pszSystemId = NULL;
    889898    }
     
    30513060 * @param   pszSrc      The source string. NULL is treated like empty string.
    30523061 */
    3053 static void rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(char *pachDst, size_t cchDst, const char *pszSrc)
    3054 {
    3055     size_t const cwcDst = cchDst / sizeof(RTUTF16);
     3062static void rtFsIsoMakerFinalizeCopyAsUtf16BigAndSpacePad(char *pachDst, size_t cchDst, const char *pszSrc)
     3063{
    30563064    size_t cwcSrc = 0;
    30573065    if (pszSrc)
     
    30593067        RTUTF16  wszSrc[256];
    30603068        PRTUTF16 pwszSrc = wszSrc;
    3061         int rc = RTStrToUtf16Ex(pszSrc, RTSTR_MAX, &pwszSrc, RT_ELEMENTS(wszSrc), &cwcSrc);
     3069        int rc = RTStrToUtf16BigEx(pszSrc, RTSTR_MAX, &pwszSrc, RT_ELEMENTS(wszSrc), &cwcSrc);
    30623070        AssertRCStmt(rc, cwcSrc = 0);
    30633071
     
    30663074        memcpy(pachDst, wszSrc, cwcSrc * sizeof(RTUTF16));
    30673075    }
    3068     if (cwcSrc < cwcDst)
    3069     {
    3070         PRTUTF16 pwcDst = (PRTUTF16)pachDst;
    3071         pwcDst += cwcSrc;
    3072         while (cwcSrc < cwcDst)
    3073         {
    3074             *pwcDst++ = ' ';
    3075             cwcSrc++;
    3076         }
     3076
     3077    /* Space padding.  Note! cchDst can be an odd number. */
     3078    size_t cchWritten = cwcSrc * sizeof(RTUTF16);
     3079    if (cchWritten < cchDst)
     3080    {
     3081        while (cchWritten + 2 <= cchDst)
     3082        {
     3083            pachDst[cchWritten++] = '\0';
     3084            pachDst[cchWritten++] = ' ';
     3085        }
     3086        if (cchWritten < cchDst)
     3087            pachDst[cchWritten] = '\0';
    30773088    }
    30783089}
     
    31293140    FORMAT_FIELD(pIsoTs->achCentisecond, Exploded.u32Nanosecond / RT_NS_10MS);
    31303141#undef FORMAT_FIELD
     3142    pIsoTs->offUtc = 0;
     3143}
     3144
     3145/**
     3146 * Formats zero ISO-9660 ascii timestamp (treated as not specified).
     3147 *
     3148 * @param   pIsoTs      The ISO-9660 timestamp destination buffer.
     3149 */
     3150static void rtFsIsoMakerZero9660Timestamp(PISO9660TIMESTAMP pIsoTs)
     3151{
     3152    memset(pIsoTs, '0', RT_OFFSETOF(ISO9660TIMESTAMP, offUtc));
    31313153    pIsoTs->offUtc = 0;
    31323154}
     
    32513273    rtFsIsoMakerTimespecToIso9660Timestamp(&pThis->ImageCreationTime, &pPrimary->BirthTime);
    32523274    rtFsIsoMakerTimespecToIso9660Timestamp(&pThis->ImageCreationTime, &pPrimary->ModifyTime);
    3253     //RT_ZERO(pPrimary->ExpireTime);
    3254     //RT_ZERO(pPrimary->EffectiveTime)
     3275    rtFsIsoMakerZero9660Timestamp(&pPrimary->ExpireTime);
     3276    rtFsIsoMakerZero9660Timestamp(&pPrimary->EffectiveTime);
    32553277    pPrimary->bFileStructureVersion     = ISO9660_FILE_STRUCTURE_VERSION;
    32563278    //pPrimary->bReserved883            = 0;
     
    32683290        memcpy(pJoliet->Hdr.achStdId, ISO9660VOLDESC_STD_ID, sizeof(pJoliet->Hdr.achStdId));
    32693291        pJoliet->fVolumeFlags               = ISO9660SUPVOLDESC_VOL_F_ESC_ONLY_REG;
    3270         rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achSystemId, sizeof(pJoliet->achSystemId), pThis->Joliet.pszSystemId);
    3271         rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achVolumeId, sizeof(pJoliet->achVolumeId),
    3272                                                    pThis->Joliet.pszVolumeId ? pThis->Joliet.pszVolumeId : szImageCreationTime);
     3292        rtFsIsoMakerFinalizeCopyAsUtf16BigAndSpacePad(pJoliet->achSystemId, sizeof(pJoliet->achSystemId), pThis->Joliet.pszSystemId);
     3293        rtFsIsoMakerFinalizeCopyAsUtf16BigAndSpacePad(pJoliet->achVolumeId, sizeof(pJoliet->achVolumeId),
     3294                                                      pThis->Joliet.pszVolumeId ? pThis->Joliet.pszVolumeId : szImageCreationTime);
    32733295        //pJoliet->Unused73                 = {0}
    32743296        //pJoliet->VolumeSpaceSize          = later
     3297        memset(pJoliet->abEscapeSequences, ' ', sizeof(pJoliet->abEscapeSequences));
    32753298        pJoliet->abEscapeSequences[0]       = ISO9660_JOLIET_ESC_SEQ_0;
    32763299        pJoliet->abEscapeSequences[1]       = ISO9660_JOLIET_ESC_SEQ_1;
    3277         pJoliet->abEscapeSequences[1]       = pThis->Joliet.uLevel == 1 ? ISO9660_JOLIET_ESC_SEQ_2_LEVEL_1
     3300        pJoliet->abEscapeSequences[2]       = pThis->Joliet.uLevel == 1 ? ISO9660_JOLIET_ESC_SEQ_2_LEVEL_1
    32783301                                            : pThis->Joliet.uLevel == 2 ? ISO9660_JOLIET_ESC_SEQ_2_LEVEL_2
    32793302                                            :                             ISO9660_JOLIET_ESC_SEQ_2_LEVEL_3;
     
    32903313        //pJoliet->offOptionalTypeMPathTable = {0}
    32913314        //pJoliet->RootDir                  = later
    3292         rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achVolumeSetId, sizeof(pJoliet->achVolumeSetId),
    3293                                                    pThis->Joliet.pszVolumeSetId);
    3294         rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achPublisherId, sizeof(pJoliet->achPublisherId),
    3295                                                    pThis->Joliet.pszPublisherId);
    3296         rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achDataPreparerId, sizeof(pJoliet->achDataPreparerId),
    3297                                                    pThis->Joliet.pszDataPreparerId);
    3298         rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achApplicationId, sizeof(pJoliet->achApplicationId),
    3299                                                    pThis->Joliet.pszApplicationId);
    3300         rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achCopyrightFileId, sizeof(pJoliet->achCopyrightFileId),
    3301                                                    pThis->Joliet.pszCopyrightFileId);
    3302         rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achAbstractFileId, sizeof(pJoliet->achAbstractFileId),
    3303                                                    pThis->Joliet.pszAbstractFileId);
    3304         rtFsIsoMakerFinalizeCopyAsUtf16AndSpacePad(pJoliet->achBibliographicFileId, sizeof(pJoliet->achBibliographicFileId),
    3305                                                    pThis->Joliet.pszBibliographicFileId);
     3315        rtFsIsoMakerFinalizeCopyAsUtf16BigAndSpacePad(pJoliet->achVolumeSetId, sizeof(pJoliet->achVolumeSetId),
     3316                                                      pThis->Joliet.pszVolumeSetId);
     3317        rtFsIsoMakerFinalizeCopyAsUtf16BigAndSpacePad(pJoliet->achPublisherId, sizeof(pJoliet->achPublisherId),
     3318                                                      pThis->Joliet.pszPublisherId);
     3319        rtFsIsoMakerFinalizeCopyAsUtf16BigAndSpacePad(pJoliet->achDataPreparerId, sizeof(pJoliet->achDataPreparerId),
     3320                                                      pThis->Joliet.pszDataPreparerId);
     3321        rtFsIsoMakerFinalizeCopyAsUtf16BigAndSpacePad(pJoliet->achApplicationId, sizeof(pJoliet->achApplicationId),
     3322                                                      pThis->Joliet.pszApplicationId);
     3323        rtFsIsoMakerFinalizeCopyAsUtf16BigAndSpacePad(pJoliet->achCopyrightFileId, sizeof(pJoliet->achCopyrightFileId),
     3324                                                      pThis->Joliet.pszCopyrightFileId);
     3325        rtFsIsoMakerFinalizeCopyAsUtf16BigAndSpacePad(pJoliet->achAbstractFileId, sizeof(pJoliet->achAbstractFileId),
     3326                                                      pThis->Joliet.pszAbstractFileId);
     3327        rtFsIsoMakerFinalizeCopyAsUtf16BigAndSpacePad(pJoliet->achBibliographicFileId, sizeof(pJoliet->achBibliographicFileId),
     3328                                                      pThis->Joliet.pszBibliographicFileId);
    33063329        rtFsIsoMakerTimespecToIso9660Timestamp(&pThis->ImageCreationTime, &pJoliet->BirthTime);
    33073330        rtFsIsoMakerTimespecToIso9660Timestamp(&pThis->ImageCreationTime, &pJoliet->ModifyTime);
    3308         //RT_ZERO(pJoliet->ExpireTime);
    3309         //RT_ZERO(pJoliet->EffectiveTime)
     3331        rtFsIsoMakerZero9660Timestamp(&pJoliet->ExpireTime);
     3332        rtFsIsoMakerZero9660Timestamp(&pJoliet->EffectiveTime);
    33103333        pJoliet->bFileStructureVersion      = ISO9660_FILE_STRUCTURE_VERSION;
    33113334        //pJoliet->bReserved883             = 0;
     
    33443367    pPrimary->VolumeSpaceSize.be        = RT_H2BE_U32(pThis->cbFinalizedImage / RTFSISOMAKER_SECTOR_SIZE);
    33453368    pPrimary->VolumeSpaceSize.le        = RT_H2LE_U32(pThis->cbFinalizedImage / RTFSISOMAKER_SECTOR_SIZE);
    3346     pPrimary->cbPathTable.be            = RT_H2BE_U32(pThis->JolietDirs.cbPathTable);
    3347     pPrimary->cbPathTable.le            = RT_H2LE_U32(pThis->JolietDirs.cbPathTable);
    3348     pPrimary->offTypeLPathTable         = RT_H2LE_U32(pThis->JolietDirs.offPathTableL);
    3349     pPrimary->offTypeMPathTable         = RT_H2BE_U32(pThis->JolietDirs.offPathTableM);
     3369    pPrimary->cbPathTable.be            = RT_H2BE_U32(pThis->PrimaryIsoDirs.cbPathTable);
     3370    pPrimary->cbPathTable.le            = RT_H2LE_U32(pThis->PrimaryIsoDirs.cbPathTable);
     3371    pPrimary->offTypeLPathTable         = RT_H2LE_U32(pThis->PrimaryIsoDirs.offPathTableL);
     3372    pPrimary->offTypeMPathTable         = RT_H2BE_U32(pThis->PrimaryIsoDirs.offPathTableM);
    33503373    pPrimary->RootDir.DirRec.cbDirRec           = sizeof(pPrimary->RootDir);
    33513374    pPrimary->RootDir.DirRec.cExtAttrBlocks     = 0;
  • trunk/src/VBox/Runtime/common/string/utf-16.cpp

    r66731 r67391  
    375375 * @param   cwc         The max length of the UTF-16 string to consider.
    376376 * @param   pcch        Where to store the length (excluding '\\0') of the UTF-8 string. (cch == cb, btw)
     377 *
     378 * @note    rtUtf16BigCalcUtf8Length is a copy of this.
    377379 */
    378380static int rtUtf16CalcUtf8Length(PCRTUTF16 pwsz, size_t cwc, size_t *pcch)
     
    385387        if (!wc)
    386388            break;
    387         else if (wc < 0xd800 || wc > 0xdfff)
     389        if (wc < 0xd800 || wc > 0xdfff)
    388390        {
    389391            if (wc < 0x80)
     
    433435
    434436/**
     437 * Validate the UTF-16BE encoding and calculates the length of an UTF-8
     438 * encoding.
     439 *
     440 * @returns iprt status code.
     441 * @param   pwsz        The UTF-16 string.
     442 * @param   cwc         The max length of the UTF-16BE string to consider.
     443 * @param   pcch        Where to store the length (excluding '\\0') of the UTF-8 string. (cch == cb, btw)
     444 *
     445 * @note    Code is a copy of rtUtf16CalcUtf8Length, but with two RT_BE2H_U16
     446 *          invocations inserted.
     447 */
     448static int rtUtf16BigCalcUtf8Length(PCRTUTF16 pwsz, size_t cwc, size_t *pcch)
     449{
     450    int     rc = VINF_SUCCESS;
     451    size_t  cch = 0;
     452    while (cwc > 0)
     453    {
     454        RTUTF16 wc = *pwsz++; cwc--;
     455        if (!wc)
     456            break;
     457        wc = RT_BE2H_U16(wc);
     458        if (wc < 0xd800 || wc > 0xdfff)
     459        {
     460            if (wc < 0x80)
     461                cch++;
     462            else if (wc < 0x800)
     463                cch += 2;
     464            else if (wc < 0xfffe)
     465                cch += 3;
     466            else
     467            {
     468                RTStrAssertMsgFailed(("endian indicator! wc=%#x\n", wc));
     469                rc = VERR_CODE_POINT_ENDIAN_INDICATOR;
     470                break;
     471            }
     472        }
     473        else
     474        {
     475            if (wc >= 0xdc00)
     476            {
     477                RTStrAssertMsgFailed(("Wrong 1st char in surrogate! wc=%#x\n", wc));
     478                rc = VERR_INVALID_UTF16_ENCODING;
     479                break;
     480            }
     481            if (cwc <= 0)
     482            {
     483                RTStrAssertMsgFailed(("Invalid length! wc=%#x\n", wc));
     484                rc = VERR_INVALID_UTF16_ENCODING;
     485                break;
     486            }
     487            wc = *pwsz++; cwc--;
     488            wc = RT_BE2H_U16(wc);
     489            if (wc < 0xdc00 || wc > 0xdfff)
     490            {
     491                RTStrAssertMsgFailed(("Wrong 2nd char in surrogate! wc=%#x\n", wc));
     492                rc = VERR_INVALID_UTF16_ENCODING;
     493                break;
     494            }
     495            cch += 4;
     496        }
     497    }
     498
     499
     500    /* done */
     501    *pcch = cch;
     502    return rc;
     503}
     504
     505
     506/**
    435507 * Recodes an valid UTF-16 string as UTF-8.
    436508 *
     
    442514 * @param   cch         The size of the UTF-8 buffer, excluding the terminator.
    443515 * @param   pcch        Where to store the number of octets actually encoded.
     516 * @note    rtUtf16BigRecodeAsUtf8 is a copy of this.
    444517 */
    445518static int rtUtf16RecodeAsUtf8(PCRTUTF16 pwsz, size_t cwc, char *psz, size_t cch, size_t *pcch)
     
    452525        if (!wc)
    453526            break;
    454         else if (wc < 0xd800 || wc > 0xdfff)
     527        if (wc < 0xd800 || wc > 0xdfff)
    455528        {
    456529            if (wc < 0x80)
     
    542615
    543616
     617/**
     618 * Recodes an valid UTF-16BE string as UTF-8.
     619 *
     620 * @returns iprt status code.
     621 * @param   pwsz        The UTF-16BE string.
     622 * @param   cwc         The number of RTUTF16 characters to process from pwsz. The recoding
     623 *                      will stop when cwc or '\\0' is reached.
     624 * @param   psz         Where to store the UTF-8 string.
     625 * @param   cch         The size of the UTF-8 buffer, excluding the terminator.
     626 * @param   pcch        Where to store the number of octets actually encoded.
     627 *
     628 * @note    Copy of rtUtf16RecodeAsUtf8 with a few RT_BE2H_U16 invocations
     629 *          insterted.
     630 */
     631static int rtUtf16BigRecodeAsUtf8(PCRTUTF16 pwsz, size_t cwc, char *psz, size_t cch, size_t *pcch)
     632{
     633    unsigned char  *pwch = (unsigned char *)psz;
     634    int             rc = VINF_SUCCESS;
     635    while (cwc > 0)
     636    {
     637        RTUTF16 wc = *pwsz++; cwc--;
     638        if (!wc)
     639            break;
     640        wc = RT_BE2H_U16(wc);
     641        if (wc < 0xd800 || wc > 0xdfff)
     642        {
     643            if (wc < 0x80)
     644            {
     645                if (RT_UNLIKELY(cch < 1))
     646                {
     647                    RTStrAssertMsgFailed(("Buffer overflow! 1\n"));
     648                    rc = VERR_BUFFER_OVERFLOW;
     649                    break;
     650                }
     651                cch--;
     652                *pwch++ = (unsigned char)wc;
     653            }
     654            else if (wc < 0x800)
     655            {
     656                if (RT_UNLIKELY(cch < 2))
     657                {
     658                    RTStrAssertMsgFailed(("Buffer overflow! 2\n"));
     659                    rc = VERR_BUFFER_OVERFLOW;
     660                    break;
     661                }
     662                cch -= 2;
     663                *pwch++ = 0xc0 | (wc >> 6);
     664                *pwch++ = 0x80 | (wc & 0x3f);
     665            }
     666            else if (wc < 0xfffe)
     667            {
     668                if (RT_UNLIKELY(cch < 3))
     669                {
     670                    RTStrAssertMsgFailed(("Buffer overflow! 3\n"));
     671                    rc = VERR_BUFFER_OVERFLOW;
     672                    break;
     673                }
     674                cch -= 3;
     675                *pwch++ = 0xe0 | (wc >> 12);
     676                *pwch++ = 0x80 | ((wc >> 6) & 0x3f);
     677                *pwch++ = 0x80 | (wc & 0x3f);
     678            }
     679            else
     680            {
     681                RTStrAssertMsgFailed(("endian indicator! wc=%#x\n", wc));
     682                rc = VERR_CODE_POINT_ENDIAN_INDICATOR;
     683                break;
     684            }
     685        }
     686        else
     687        {
     688            if (wc >= 0xdc00)
     689            {
     690                RTStrAssertMsgFailed(("Wrong 1st char in surrogate! wc=%#x\n", wc));
     691                rc = VERR_INVALID_UTF16_ENCODING;
     692                break;
     693            }
     694            if (cwc <= 0)
     695            {
     696                RTStrAssertMsgFailed(("Invalid length! wc=%#x\n", wc));
     697                rc = VERR_INVALID_UTF16_ENCODING;
     698                break;
     699            }
     700            RTUTF16 wc2 = *pwsz++; cwc--;
     701            wc2 = RT_BE2H_U16(wc2);
     702            if (wc2 < 0xdc00 || wc2 > 0xdfff)
     703            {
     704                RTStrAssertMsgFailed(("Wrong 2nd char in surrogate! wc=%#x\n", wc));
     705                rc = VERR_INVALID_UTF16_ENCODING;
     706                break;
     707            }
     708            uint32_t CodePoint = 0x10000
     709                               + (  ((wc & 0x3ff) << 10)
     710                                  | (wc2 & 0x3ff));
     711            if (RT_UNLIKELY(cch < 4))
     712            {
     713                RTStrAssertMsgFailed(("Buffer overflow! 4\n"));
     714                rc = VERR_BUFFER_OVERFLOW;
     715                break;
     716            }
     717            cch -= 4;
     718            *pwch++ = 0xf0 | (CodePoint >> 18);
     719            *pwch++ = 0x80 | ((CodePoint >> 12) & 0x3f);
     720            *pwch++ = 0x80 | ((CodePoint >>  6) & 0x3f);
     721            *pwch++ = 0x80 | (CodePoint & 0x3f);
     722        }
     723    }
     724
     725    /* done */
     726    *pwch = '\0';
     727    *pcch = (char *)pwch - psz;
     728    return rc;
     729}
     730
     731
    544732
    545733RTDECL(int)  RTUtf16ToUtf8Tag(PCRTUTF16 pwszString, char **ppszString, const char *pszTag)
     
    582770
    583771
     772RTDECL(int)  RTUtf16BigToUtf8Tag(PCRTUTF16 pwszString, char **ppszString, const char *pszTag)
     773{
     774    /*
     775     * Validate input.
     776     */
     777    Assert(VALID_PTR(ppszString));
     778    Assert(VALID_PTR(pwszString));
     779    *ppszString = NULL;
     780
     781    /*
     782     * Validate the UTF-16 string and calculate the length of the UTF-8 encoding of it.
     783     */
     784    size_t cch;
     785    int rc = rtUtf16BigCalcUtf8Length(pwszString, RTSTR_MAX, &cch);
     786    if (RT_SUCCESS(rc))
     787    {
     788        /*
     789         * Allocate buffer and recode it.
     790         */
     791        char *pszResult = (char *)RTMemAllocTag(cch + 1, pszTag);
     792        if (pszResult)
     793        {
     794            rc = rtUtf16BigRecodeAsUtf8(pwszString, RTSTR_MAX, pszResult, cch, &cch);
     795            if (RT_SUCCESS(rc))
     796            {
     797                *ppszString = pszResult;
     798                return rc;
     799            }
     800
     801            RTMemFree(pszResult);
     802        }
     803        else
     804            rc = VERR_NO_STR_MEMORY;
     805    }
     806    return rc;
     807}
     808RT_EXPORT_SYMBOL(RTUtf16BigToUtf8Tag);
     809
     810
    584811RTDECL(int)  RTUtf16ToUtf8ExTag(PCRTUTF16 pwszString, size_t cwcString, char **ppsz, size_t cch, size_t *pcch, const char *pszTag)
    585812{
     
    587814     * Validate input.
    588815     */
    589     Assert(VALID_PTR(pwszString));
    590     Assert(VALID_PTR(ppsz));
    591     Assert(!pcch || VALID_PTR(pcch));
     816    AssertPtr(pwszString);
     817    AssertPtr(ppsz);
     818    AssertPtrNull(pcch);
    592819
    593820    /*
     
    640867
    641868
     869RTDECL(int)  RTUtf16BigToUtf8ExTag(PCRTUTF16 pwszString, size_t cwcString, char **ppsz, size_t cch, size_t *pcch, const char *pszTag)
     870{
     871    /*
     872     * Validate input.
     873     */
     874    AssertPtr(pwszString);
     875    AssertPtr(ppsz);
     876    AssertPtrNull(pcch);
     877
     878    /*
     879     * Validate the UTF-16BE string and calculate the length of the UTF-8 encoding of it.
     880     */
     881    size_t cchResult;
     882    int rc = rtUtf16BigCalcUtf8Length(pwszString, cwcString, &cchResult);
     883    if (RT_SUCCESS(rc))
     884    {
     885        if (pcch)
     886            *pcch = cchResult;
     887
     888        /*
     889         * Check buffer size / Allocate buffer and recode it.
     890         */
     891        bool fShouldFree;
     892        char *pszResult;
     893        if (cch > 0 && *ppsz)
     894        {
     895            fShouldFree = false;
     896            if (RT_UNLIKELY(cch <= cchResult))
     897                return VERR_BUFFER_OVERFLOW;
     898            pszResult = *ppsz;
     899        }
     900        else
     901        {
     902            *ppsz = NULL;
     903            fShouldFree = true;
     904            cch = RT_MAX(cch, cchResult + 1);
     905            pszResult = (char *)RTStrAllocTag(cch, pszTag);
     906        }
     907        if (pszResult)
     908        {
     909            rc = rtUtf16BigRecodeAsUtf8(pwszString, cwcString, pszResult, cch - 1, &cch);
     910            if (RT_SUCCESS(rc))
     911            {
     912                *ppsz = pszResult;
     913                return rc;
     914            }
     915
     916            if (fShouldFree)
     917                RTStrFree(pszResult);
     918        }
     919        else
     920            rc = VERR_NO_STR_MEMORY;
     921    }
     922    return rc;
     923}
     924RT_EXPORT_SYMBOL(RTUtf16BigToUtf8ExTag);
     925
     926
    642927RTDECL(size_t) RTUtf16CalcUtf8Len(PCRTUTF16 pwsz)
    643928{
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette