[Bug 32495] New: Incorrect behavior in ScriptGetLogicalWidths() / ScriptApplyLogicalWidth() (buffer overrun)

wine-bugs at winehq.org wine-bugs at winehq.org
Thu Dec 20 13:32:39 CST 2012


http://bugs.winehq.org/show_bug.cgi?id=32495

             Bug #: 32495
           Summary: Incorrect behavior in ScriptGetLogicalWidths() /
                    ScriptApplyLogicalWidth() (buffer overrun)
           Product: Wine
           Version: 1.5.19
          Platform: x86
        OS/Version: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: usp10
        AssignedTo: wine-bugs at winehq.org
        ReportedBy: disposable593-wine at yahoo.com
    Classification: Unclassified


Currently, ScriptGetLogicalWidths() and ScriptApplyLogicalWidth() are
incorrectly implemented, leading to wrong glyph positioning in one of my
applications.

**ScriptGetLogicalWidths(): The current implementation simply copies the input
to the output array, incorrectly assuming nbchar==nbglyphs. If there are fewer
glyphs than characters, this causes a buffer overrun, potentially leading to
application crashes. (The problem does and will become more prevalent as the
implementation of shaping is improved over time.)

**ScriptApplyLogicalWidths(): The functions fails to apply justification and
simply returns the unjustified widths.

Below I include what I believe are correct implementations. I have taken care
that the results agree with those returned by the Microsoft implementations. (I
have never seen or been in contact with the original Microsoft code, though, so
the following code is "clean" and may be used for any purpose.)




HRESULT WINAPI ScriptGetLogicalWidths(const SCRIPT_ANALYSIS *sa, int nbchars,
int nbglyphs,
                                      const int *glyph_width, const WORD
*log_clust,
                                      const SCRIPT_VISATTR *sva, int *widths)
{
    int rtl, i;

//    TRACE("(%p, %d, %d, %p, %p, %p, %p)\n",
//          sa, nbchars, nbglyphs, glyph_width, log_clust, sva, widths);

    rtl = sa->fRTL && !sa->fLogicalOrder;

    for (i = 0; i < nbchars; )
    {
        int w = 0, i2, j, j2;

        j = log_clust[i];
        i2 = i;
        do i2++; while (i2 < nbchars && log_clust[i2] == j);
        j2 = i2 < nbchars ? log_clust[i2] : rtl? -1 : nbglyphs;

        for ( ; j != j2; rtl? j--:j++)
            w += glyph_width[j];

        for ( ; i < i2; i++)
            w -= widths[i] = w / (i2-i);
    }

    return S_OK;
}



HRESULT WINAPI ScriptApplyLogicalWidth(const int *dx, int num_chars, int
num_glyphs,
                                       const WORD *log_clust, const
SCRIPT_VISATTR *sva,
                                       const int *advance, const
SCRIPT_ANALYSIS *sa,
                                       ABC *abc, int *justify)
{

    int rtl, i;

//    FIXME("(%p, %d, %d, %p, %p, %p, %p, %p, %p)\n",
//          dx, num_chars, num_glyphs, log_clust, sva, advance, sa, abc,
justify);

    rtl = sa->fRTL && !sa->fLogicalOrder;

    if (abc) abc->abcB = - abc->abcA - abc->abcC;

    for (i = 0; i < num_chars; )
    {
        int w = 0, j, j1, j2;

        j1 = log_clust[i];
        do w += dx[i++]; while (i < num_chars && log_clust[i] == j1);
        j2 = i < num_chars ? log_clust[i] : rtl? -1 : num_glyphs;

        for (j = j1; j != j2; rtl? j--:j++)
            w -= advance[j];

        for (j = j1; j != j2; rtl? j--:j++)
        {
            w -= justify[j] = w / (rtl? j-j2:j2-j);
            justify[j] += advance[j];
            if (abc) abc->abcB += justify[j];
        }
    }

    return S_OK;
}

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list