Dylan Smith : richedit: Respect the cbSize field on EM_GETPARAFORMAT.

Alexandre Julliard julliard at winehq.org
Fri Jan 16 07:41:53 CST 2009


Module: wine
Branch: master
Commit: f73a34647f4cfb01022a0c3e9f918e46555787c2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f73a34647f4cfb01022a0c3e9f918e46555787c2

Author: Dylan Smith <dylan.ah.smith at gmail.com>
Date:   Thu Jan 15 23:50:20 2009 -0500

richedit: Respect the cbSize field on EM_GETPARAFORMAT.

EM_GETPARAFORMAT previously would overwrite the cbSize field with the
size of PARAFORMAT2, would read past the end of the struct, and might
indicate that PARAFORMAT2 fields are valid using the mask regardless
of the value of cbSize.

---

 dlls/riched20/para.c |   87 ++++++++++++++++++++++++-------------------------
 1 files changed, 43 insertions(+), 44 deletions(-)

diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c
index a118d7d..ecc89d3 100644
--- a/dlls/riched20/para.c
+++ b/dlls/riched20/para.c
@@ -555,74 +555,73 @@ BOOL ME_SetSelectionParaFormat(ME_TextEditor *editor, const PARAFORMAT2 *pFmt)
   return TRUE;
 }
 
-static void ME_GetParaFormat(ME_TextEditor *editor, const ME_DisplayItem *para, PARAFORMAT2 *pFmt)
+static void ME_GetParaFormat(ME_TextEditor *editor,
+                             const ME_DisplayItem *para,
+                             PARAFORMAT2 *pFmt)
 {
-  if (pFmt->cbSize >= sizeof(PARAFORMAT2))
-  {
+  UINT cbSize = pFmt->cbSize;
+  if (pFmt->cbSize >= sizeof(PARAFORMAT2)) {
     *pFmt = *para->member.para.pFmt;
-    return;
+  } else {
+    CopyMemory(pFmt, para->member.para.pFmt, pFmt->cbSize);
+    pFmt->dwMask &= PFM_ALL;
   }
-  CopyMemory(pFmt, para->member.para.pFmt, pFmt->cbSize);  
+  pFmt->cbSize = cbSize;
 }
 
 void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
 {
   ME_DisplayItem *para, *para_end;
-  PARAFORMAT2 tmp;
-  
+  PARAFORMAT2 *curFmt;
+
+  if (pFmt->cbSize < sizeof(PARAFORMAT)) {
+    pFmt->dwMask = 0;
+    return;
+  }
+
   ME_GetSelectionParas(editor, &para, &para_end);
-  
+
   ME_GetParaFormat(editor, para, pFmt);
-  if (para == para_end) return;
-  
+
   /* Invalidate values that change across the selected paragraphs. */
-  do {
-    ZeroMemory(&tmp, sizeof(tmp));
-    tmp.cbSize = sizeof(tmp);
-    ME_GetParaFormat(editor, para, &tmp);
+  while (para != para_end)
+  {
+    para = para->member.para.next_para;
+    curFmt = &para->member.para.pFmt;
 
 #define CHECK_FIELD(m, f) \
-    if (pFmt->f != tmp.f) pFmt->dwMask &= ~(m);
+    if (pFmt->f != curFmt->f) pFmt->dwMask &= ~(m);
 
-    pFmt->dwMask &= ~((pFmt->wEffects ^ tmp.wEffects) << 16);
-    CHECK_FIELD(PFM_NUMBERING, wNumbering);
-    assert(tmp.dwMask & PFM_ALIGNMENT);
     CHECK_FIELD(PFM_NUMBERING, wNumbering);
-    assert(tmp.dwMask & PFM_STARTINDENT);
     CHECK_FIELD(PFM_STARTINDENT, dxStartIndent);
-    assert(tmp.dwMask & PFM_RIGHTINDENT);
     CHECK_FIELD(PFM_RIGHTINDENT, dxRightIndent);
-    assert(tmp.dwMask & PFM_OFFSET);
     CHECK_FIELD(PFM_OFFSET, dxOffset);
     CHECK_FIELD(PFM_ALIGNMENT, wAlignment);
-
-    assert(tmp.dwMask & PFM_TABSTOPS);
     if (pFmt->dwMask & PFM_TABSTOPS) {
-      if (pFmt->cTabCount != tmp.cTabCount ||
-          memcmp(pFmt->rgxTabs, tmp.rgxTabs, tmp.cTabCount*sizeof(int)))
+      if (pFmt->cTabCount != para->member.para.pFmt->cTabCount ||
+          memcmp(pFmt->rgxTabs, curFmt->rgxTabs, curFmt->cTabCount*sizeof(int)))
         pFmt->dwMask &= ~PFM_TABSTOPS;
     }
 
-    CHECK_FIELD(PFM_SPACEBEFORE, dySpaceBefore);
-    CHECK_FIELD(PFM_SPACEAFTER, dySpaceAfter);
-    CHECK_FIELD(PFM_LINESPACING, dyLineSpacing);
-    CHECK_FIELD(PFM_STYLE, sStyle);
-    CHECK_FIELD(PFM_SPACEAFTER, bLineSpacingRule);
-    CHECK_FIELD(PFM_SHADING, wShadingWeight);
-    CHECK_FIELD(PFM_SHADING, wShadingStyle);
-    CHECK_FIELD(PFM_NUMBERINGSTART, wNumberingStart);
-    CHECK_FIELD(PFM_NUMBERINGSTYLE, wNumberingStyle);
-    CHECK_FIELD(PFM_NUMBERINGTAB, wNumberingTab);
-    CHECK_FIELD(PFM_BORDER, wBorderSpace);
-    CHECK_FIELD(PFM_BORDER, wBorderWidth);
-    CHECK_FIELD(PFM_BORDER, wBorders);
-
+    if (pFmt->dwMask >= sizeof(PARAFORMAT2))
+    {
+      pFmt->dwMask &= ~((pFmt->wEffects ^ curFmt->wEffects) << 16);
+      CHECK_FIELD(PFM_SPACEBEFORE, dySpaceBefore);
+      CHECK_FIELD(PFM_SPACEAFTER, dySpaceAfter);
+      CHECK_FIELD(PFM_LINESPACING, dyLineSpacing);
+      CHECK_FIELD(PFM_STYLE, sStyle);
+      CHECK_FIELD(PFM_SPACEAFTER, bLineSpacingRule);
+      CHECK_FIELD(PFM_SHADING, wShadingWeight);
+      CHECK_FIELD(PFM_SHADING, wShadingStyle);
+      CHECK_FIELD(PFM_NUMBERINGSTART, wNumberingStart);
+      CHECK_FIELD(PFM_NUMBERINGSTYLE, wNumberingStyle);
+      CHECK_FIELD(PFM_NUMBERINGTAB, wNumberingTab);
+      CHECK_FIELD(PFM_BORDER, wBorderSpace);
+      CHECK_FIELD(PFM_BORDER, wBorderWidth);
+      CHECK_FIELD(PFM_BORDER, wBorders);
+    }
 #undef CHECK_FIELD
-
-    if (para == para_end)
-      return;
-    para = para->member.para.next_para;
-  } while(1);
+  }
 }
 
 void ME_SetDefaultParaFormat(PARAFORMAT2 *pFmt)




More information about the wine-cvs mailing list