[PATCH 5/5] dwrite: Validate 'CPAL' data before using it.

Nikolay Sivov nsivov at codeweavers.com
Sat Jan 26 23:55:27 CST 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/dwrite_private.h |  7 ++--
 dlls/dwrite/font.c           |  5 +--
 dlls/dwrite/opentype.c       | 67 ++++++++++++++++++------------------
 3 files changed, 41 insertions(+), 38 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 9f8c941428..6eac1f4f33 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -227,9 +227,10 @@ extern HRESULT opentype_get_font_familyname(struct file_stream_desc*,IDWriteLoca
 extern HRESULT opentype_get_font_facename(struct file_stream_desc*,WCHAR*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
 extern HRESULT opentype_get_typographic_features(IDWriteFontFace*,UINT32,UINT32,UINT32,UINT32*,DWRITE_FONT_FEATURE_TAG*) DECLSPEC_HIDDEN;
 extern BOOL opentype_get_vdmx_size(const void*,INT,UINT16*,UINT16*) DECLSPEC_HIDDEN;
-extern UINT32 opentype_get_cpal_palettecount(const void*) DECLSPEC_HIDDEN;
-extern UINT32 opentype_get_cpal_paletteentrycount(const void*) DECLSPEC_HIDDEN;
-extern HRESULT opentype_get_cpal_entries(const void*,UINT32,UINT32,UINT32,DWRITE_COLOR_F*) DECLSPEC_HIDDEN;
+extern unsigned int opentype_get_cpal_palettecount(const struct dwrite_fonttable *table) DECLSPEC_HIDDEN;
+extern unsigned int opentype_get_cpal_paletteentrycount(const struct dwrite_fonttable *table) DECLSPEC_HIDDEN;
+extern HRESULT opentype_get_cpal_entries(const struct dwrite_fonttable *table, unsigned int palette,
+        unsigned int first_entry_index, unsigned int entry_count, DWRITE_COLOR_F *entries) DECLSPEC_HIDDEN;
 extern BOOL opentype_has_vertical_variants(IDWriteFontFace4*) DECLSPEC_HIDDEN;
 extern UINT32 opentype_get_glyph_image_formats(IDWriteFontFace4*) DECLSPEC_HIDDEN;
 extern DWRITE_CONTAINER_TYPE opentype_analyze_container_type(void const *, UINT32) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 5c0b2a4310..2c51674b0a 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -385,9 +385,10 @@ static const struct dwrite_fonttable *get_fontface_gasp(struct dwrite_fontface *
     return &fontface->gasp;
 }
 
-static const void* get_fontface_cpal(struct dwrite_fontface *fontface)
+static const struct dwrite_fonttable *get_fontface_cpal(struct dwrite_fontface *fontface)
 {
-    return get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_CPAL_TAG, &fontface->cpal);
+    get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_CPAL_TAG, &fontface->cpal);
+    return &fontface->cpal;
 }
 
 static const void* get_fontface_colr(struct dwrite_fontface *fontface)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index 291b41b131..647ac99597 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -843,25 +843,17 @@ static const UINT16 dwriteid_to_opentypeid[DWRITE_INFORMATIONAL_STRING_POSTSCRIP
 };
 
 /* CPAL table */
-struct CPAL_Header_0
+struct cpal_header_0
 {
     USHORT version;
-    USHORT numPaletteEntries;
-    USHORT numPalette;
-    USHORT numColorRecords;
-    ULONG  offsetFirstColorRecord;
-    USHORT colorRecordIndices[1];
+    USHORT num_palette_entries;
+    USHORT num_palettes;
+    USHORT num_color_records;
+    ULONG offset_first_color_record;
+    USHORT color_record_indices[1];
 };
 
-/* for version == 1, this comes after full CPAL_Header_0 */
-struct CPAL_SubHeader_1
-{
-    ULONG  offsetPaletteTypeArray;
-    ULONG  offsetPaletteLabelArray;
-    ULONG  offsetPaletteEntryLabelArray;
-};
-
-struct CPAL_ColorRecord
+struct cpal_color_record
 {
     BYTE blue;
     BYTE green;
@@ -2005,37 +1997,46 @@ done:
     return flags;
 }
 
-UINT32 opentype_get_cpal_palettecount(const void *cpal)
+unsigned int opentype_get_cpal_palettecount(const struct dwrite_fonttable *cpal)
 {
-    const struct CPAL_Header_0 *header = (const struct CPAL_Header_0*)cpal;
-    return header ? GET_BE_WORD(header->numPalette) : 0;
+    return table_read_be_word(cpal, FIELD_OFFSET(struct cpal_header_0, num_palettes));
 }
 
-UINT32 opentype_get_cpal_paletteentrycount(const void *cpal)
+unsigned int opentype_get_cpal_paletteentrycount(const struct dwrite_fonttable *cpal)
 {
-    const struct CPAL_Header_0 *header = (const struct CPAL_Header_0*)cpal;
-    return header ? GET_BE_WORD(header->numPaletteEntries) : 0;
+    return table_read_be_word(cpal, FIELD_OFFSET(struct cpal_header_0, num_palette_entries));
 }
 
-HRESULT opentype_get_cpal_entries(const void *cpal, UINT32 palette, UINT32 first_entry_index, UINT32 entry_count,
-    DWRITE_COLOR_F *entries)
+HRESULT opentype_get_cpal_entries(const struct dwrite_fonttable *cpal, unsigned int palette,
+        unsigned int first_entry_index, unsigned int entry_count, DWRITE_COLOR_F *entries)
 {
-    const struct CPAL_Header_0 *header = (const struct CPAL_Header_0*)cpal;
-    const struct CPAL_ColorRecord *records;
-    UINT32 palettecount, entrycount, i;
+    unsigned int num_palettes, num_palette_entries, i;
+    const struct cpal_color_record *records;
+    const struct cpal_header_0 *header;
+
+    header = table_read_ensure(cpal, 0, sizeof(*header));
+
+    if (!cpal->exists || !header)
+        return DWRITE_E_NOCOLOR;
 
-    if (!header) return DWRITE_E_NOCOLOR;
+    num_palettes = GET_BE_WORD(header->num_palettes);
+    if (palette >= num_palettes)
+        return DWRITE_E_NOCOLOR;
 
-    palettecount = GET_BE_WORD(header->numPalette);
-    if (palette >= palettecount)
+    header = table_read_ensure(cpal, 0, FIELD_OFFSET(struct cpal_header_0, color_record_indices[palette]));
+    if (!header)
         return DWRITE_E_NOCOLOR;
 
-    entrycount = GET_BE_WORD(header->numPaletteEntries);
-    if (first_entry_index + entry_count > entrycount)
+    num_palette_entries = GET_BE_WORD(header->num_palette_entries);
+    if (first_entry_index + entry_count > num_palette_entries)
         return E_INVALIDARG;
 
-    records = (const struct CPAL_ColorRecord*)((BYTE*)cpal + GET_BE_DWORD(header->offsetFirstColorRecord));
-    first_entry_index += GET_BE_WORD(header->colorRecordIndices[palette]);
+    records = table_read_ensure(cpal, GET_BE_DWORD(header->offset_first_color_record),
+            sizeof(*records) * GET_BE_WORD(header->num_color_records));
+    if (!records)
+        return DWRITE_E_NOCOLOR;
+
+    first_entry_index += GET_BE_WORD(header->color_record_indices[palette]);
 
     for (i = 0; i < entry_count; i++) {
         entries[i].u1.r = records[first_entry_index + i].red   / 255.0f;
-- 
2.20.1




More information about the wine-devel mailing list