Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
2dcb3c74
Commit
2dcb3c74
authored
Jan 27, 2019
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jan 28, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Validate font data when retrieving supported unicode ranges data.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
3795100b
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
127 additions
and
79 deletions
+127
-79
dwrite_private.h
dlls/dwrite/dwrite_private.h
+10
-1
font.c
dlls/dwrite/font.c
+14
-22
opentype.c
dlls/dwrite/opentype.c
+103
-56
No files found.
dlls/dwrite/dwrite_private.h
View file @
2dcb3c74
...
...
@@ -208,9 +208,18 @@ struct file_stream_desc {
UINT32
face_index
;
};
struct
dwrite_fonttable
{
const
BYTE
*
data
;
void
*
context
;
UINT32
size
;
BOOL
exists
;
};
extern
HRESULT
opentype_analyze_font
(
IDWriteFontFileStream
*
,
BOOL
*
,
DWRITE_FONT_FILE_TYPE
*
,
DWRITE_FONT_FACE_TYPE
*
,
UINT32
*
)
DECLSPEC_HIDDEN
;
extern
HRESULT
opentype_get_font_table
(
struct
file_stream_desc
*
,
UINT32
,
const
void
**
,
void
**
,
UINT32
*
,
BOOL
*
)
DECLSPEC_HIDDEN
;
extern
HRESULT
opentype_cmap_get_unicode_ranges
(
void
*
,
UINT32
,
DWRITE_UNICODE_RANGE
*
,
UINT32
*
)
DECLSPEC_HIDDEN
;
extern
HRESULT
opentype_cmap_get_unicode_ranges
(
const
struct
dwrite_fonttable
*
table
,
unsigned
int
max_count
,
DWRITE_UNICODE_RANGE
*
ranges
,
unsigned
int
*
count
)
DECLSPEC_HIDDEN
;
extern
void
opentype_get_font_properties
(
struct
file_stream_desc
*
,
struct
dwrite_font_props
*
)
DECLSPEC_HIDDEN
;
extern
void
opentype_get_font_metrics
(
struct
file_stream_desc
*
,
DWRITE_FONT_METRICS1
*
,
DWRITE_CARET_METRICS
*
)
DECLSPEC_HIDDEN
;
extern
HRESULT
opentype_get_font_info_strings
(
const
void
*
,
DWRITE_INFORMATIONAL_STRING_ID
,
IDWriteLocalizedStrings
**
)
DECLSPEC_HIDDEN
;
...
...
dlls/dwrite/font.c
View file @
2dcb3c74
...
...
@@ -149,13 +149,6 @@ struct dwrite_font {
struct
dwrite_fontfamily
*
family
;
};
struct
dwrite_fonttable
{
void
*
data
;
void
*
context
;
UINT32
size
;
BOOL
exists
;
};
enum
runanalysis_flags
{
RUNANALYSIS_BOUNDS_READY
=
1
<<
0
,
RUNANALYSIS_BITMAP_READY
=
1
<<
1
,
...
...
@@ -345,7 +338,7 @@ static HRESULT set_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16
return
S_OK
;
}
static
void
*
get_fontface_table
(
IDWriteFontFace4
*
fontface
,
UINT32
tag
,
struct
dwrite_fonttable
*
table
)
static
const
void
*
get_fontface_table
(
IDWriteFontFace4
*
fontface
,
UINT32
tag
,
struct
dwrite_fonttable
*
table
)
{
HRESULT
hr
;
...
...
@@ -381,29 +374,24 @@ static FLOAT get_font_prop_vec_dotproduct(const struct dwrite_font_propvec *left
return
left
->
stretch
*
right
->
stretch
+
left
->
style
*
right
->
style
+
left
->
weight
*
right
->
weight
;
}
static
inline
void
*
get_fontface_cmap
(
struct
dwrite_fontface
*
fontface
)
{
return
get_fontface_table
(
&
fontface
->
IDWriteFontFace4_iface
,
MS_CMAP_TAG
,
&
fontface
->
cmap
);
}
static
inline
void
*
get_fontface_vdmx
(
struct
dwrite_fontface
*
fontface
)
static
const
void
*
get_fontface_vdmx
(
struct
dwrite_fontface
*
fontface
)
{
return
get_fontface_table
(
&
fontface
->
IDWriteFontFace4_iface
,
MS_VDMX_TAG
,
&
fontface
->
vdmx
);
}
static
inline
void
*
get_fontface_gasp
(
struct
dwrite_fontface
*
fontface
,
UINT32
*
size
)
static
const
void
*
get_fontface_gasp
(
struct
dwrite_fontface
*
fontface
,
UINT32
*
size
)
{
void
*
ptr
=
get_fontface_table
(
&
fontface
->
IDWriteFontFace4_iface
,
MS_GASP_TAG
,
&
fontface
->
gasp
);
const
void
*
ptr
=
get_fontface_table
(
&
fontface
->
IDWriteFontFace4_iface
,
MS_GASP_TAG
,
&
fontface
->
gasp
);
*
size
=
fontface
->
gasp
.
size
;
return
ptr
;
}
static
inline
void
*
get_fontface_cpal
(
struct
dwrite_fontface
*
fontface
)
static
const
void
*
get_fontface_cpal
(
struct
dwrite_fontface
*
fontface
)
{
return
get_fontface_table
(
&
fontface
->
IDWriteFontFace4_iface
,
MS_CPAL_TAG
,
&
fontface
->
cpal
);
}
static
inline
void
*
get_fontface_colr
(
struct
dwrite_fontface
*
fontface
)
static
const
void
*
get_fontface_colr
(
struct
dwrite_fontface
*
fontface
)
{
return
get_fontface_table
(
&
fontface
->
IDWriteFontFace4_iface
,
MS_COLR_TAG
,
&
fontface
->
colr
);
}
...
...
@@ -730,9 +718,10 @@ static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace
FLOAT
ppdip
,
DWRITE_MEASURING_MODE
measuring
,
IDWriteRenderingParams
*
params
,
DWRITE_RENDERING_MODE
*
mode
)
{
struct
dwrite_fontface
*
This
=
impl_from_IDWriteFontFace4
(
iface
);
WORD
gasp
,
*
ptr
;
const
WORD
*
ptr
;
UINT32
size
;
FLOAT
ppem
;
WORD
gasp
;
TRACE
(
"(%p)->(%.2f %.2f %d %p %p)
\n
"
,
This
,
emSize
,
ppdip
,
measuring
,
params
,
mode
);
...
...
@@ -910,7 +899,8 @@ static HRESULT WINAPI dwritefontface1_GetUnicodeRanges(IDWriteFontFace4 *iface,
if
(
max_count
&&
!
ranges
)
return
E_INVALIDARG
;
return
opentype_cmap_get_unicode_ranges
(
get_fontface_cmap
(
This
),
max_count
,
ranges
,
count
);
get_fontface_table
(
iface
,
MS_CMAP_TAG
,
&
This
->
cmap
);
return
opentype_cmap_get_unicode_ranges
(
&
This
->
cmap
,
max_count
,
ranges
,
count
);
}
static
BOOL
WINAPI
dwritefontface1_IsMonospacedFont
(
IDWriteFontFace4
*
iface
)
...
...
@@ -1108,8 +1098,9 @@ static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFac
{
struct
dwrite_fontface
*
This
=
impl_from_IDWriteFontFace4
(
iface
);
FLOAT
emthreshold
;
WORD
gasp
,
*
ptr
;
const
WORD
*
ptr
;
UINT32
size
;
WORD
gasp
;
TRACE
(
"(%p)->(%.2f %.2f %.2f %p %d %d %d %p %p %p)
\n
"
,
This
,
emSize
,
dpiX
,
dpiY
,
m
,
is_sideways
,
threshold
,
measuringmode
,
params
,
renderingmode
,
gridfitmode
);
...
...
@@ -1239,8 +1230,9 @@ static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFac
{
struct
dwrite_fontface
*
This
=
impl_from_IDWriteFontFace4
(
iface
);
FLOAT
emthreshold
;
WORD
gasp
,
*
ptr
;
const
WORD
*
ptr
;
UINT32
size
;
WORD
gasp
;
TRACE
(
"(%p)->(%.2f %.2f %.2f %p %d %d %d %p %p %p)
\n
"
,
This
,
emSize
,
dpiX
,
dpiY
,
m
,
is_sideways
,
threshold
,
measuring_mode
,
params
,
rendering_mode
,
gridfit_mode
);
...
...
dlls/dwrite/opentype.c
View file @
2dcb3c74
...
...
@@ -82,16 +82,18 @@ typedef struct {
DWORD
length
;
}
TT_TableRecord
;
typedef
struct
{
struct
cmap_encoding_record
{
WORD
platformID
;
WORD
encodingID
;
DWORD
offset
;
}
CMAP_EncodingRecord
;
};
typedef
struct
{
struct
cmap_header
{
WORD
version
;
WORD
num
T
ables
;
CMAP_EncodingR
ecord
tables
[
1
];
WORD
num
_t
ables
;
struct
cmap_encoding_r
ecord
tables
[
1
];
}
CMAP_Header
;
typedef
struct
{
...
...
@@ -100,25 +102,27 @@ typedef struct {
DWORD
startGlyphID
;
}
CMAP_SegmentedCoverage_group
;
typedef
struct
{
struct
cmap_segmented_coverage
{
WORD
format
;
WORD
reserved
;
DWORD
length
;
DWORD
language
;
DWORD
n
G
roups
;
DWORD
n
um_g
roups
;
CMAP_SegmentedCoverage_group
groups
[
1
];
}
CMAP_SegmentedCoverage
;
};
typedef
struct
{
struct
cmap_segment_mapping
{
WORD
format
;
WORD
length
;
WORD
language
;
WORD
seg
CountX
2
;
WORD
search
R
ange
;
WORD
entry
S
elector
;
WORD
range
S
hift
;
WORD
end
C
ode
[
1
];
}
CMAP_SegmentMapping_0
;
WORD
seg
_count_x
2
;
WORD
search
_r
ange
;
WORD
entry
_s
elector
;
WORD
range
_s
hift
;
WORD
end
_c
ode
[
1
];
};
enum
OPENTYPE_CMAP_TABLE_FORMAT
{
...
...
@@ -874,6 +878,26 @@ struct COLR_LayerRecord
USHORT
paletteIndex
;
};
static
const
void
*
table_read_ensure
(
const
struct
dwrite_fonttable
*
table
,
unsigned
int
offset
,
unsigned
int
size
)
{
if
(
size
>
table
->
size
||
offset
>
table
->
size
-
size
)
return
NULL
;
return
table
->
data
+
offset
;
}
static
WORD
table_read_be_word
(
const
struct
dwrite_fonttable
*
table
,
unsigned
int
offset
)
{
const
WORD
*
ptr
=
table_read_ensure
(
table
,
offset
,
sizeof
(
*
ptr
));
return
ptr
?
GET_BE_WORD
(
*
ptr
)
:
0
;
}
static
DWORD
table_read_be_dword
(
const
struct
dwrite_fonttable
*
table
,
unsigned
int
offset
)
{
const
DWORD
*
ptr
=
table_read_ensure
(
table
,
offset
,
sizeof
(
*
ptr
));
return
ptr
?
GET_BE_DWORD
(
*
ptr
)
:
0
;
}
BOOL
is_face_type_supported
(
DWRITE_FONT_FACE_TYPE
type
)
{
return
(
type
==
DWRITE_FONT_FACE_TYPE_CFF
)
||
...
...
@@ -1137,92 +1161,115 @@ HRESULT opentype_get_font_table(struct file_stream_desc *stream_desc, UINT32 tag
* CMAP
**********/
static
UINT32
opentype_cmap_get_unicode_ranges_count
(
const
CMAP_Header
*
CMAP_Table
)
static
unsigned
int
opentype_cmap_get_unicode_ranges_count
(
const
struct
dwrite_fonttable
*
cmap
)
{
UINT32
count
=
0
;
int
i
;
unsigned
int
i
,
num_tables
,
count
=
0
;
const
struct
cmap_header
*
header
;
for
(
i
=
0
;
i
<
GET_BE_WORD
(
CMAP_Table
->
numTables
);
i
++
)
{
WORD
type
;
WORD
*
table
;
num_tables
=
table_read_be_word
(
cmap
,
FIELD_OFFSET
(
struct
cmap_header
,
num_tables
));
header
=
table_read_ensure
(
cmap
,
0
,
FIELD_OFFSET
(
struct
cmap_header
,
tables
[
num_tables
]));
if
(
GET_BE_WORD
(
CMAP_Table
->
tables
[
i
].
platformID
)
!=
3
)
if
(
!
header
)
return
0
;
for
(
i
=
0
;
i
<
num_tables
;
++
i
)
{
unsigned
int
format
,
offset
;
if
(
GET_BE_WORD
(
header
->
tables
[
i
].
platformID
)
!=
3
)
continue
;
table
=
(
WORD
*
)(((
BYTE
*
)
CMAP_Table
)
+
GET_BE_DWORD
(
CMAP_Table
->
tables
[
i
].
offset
));
type
=
GET_BE_WORD
(
*
table
);
TRACE
(
"table type %i
\n
"
,
type
);
offset
=
GET_BE_DWORD
(
header
->
tables
[
i
].
offset
);
format
=
table_read_be_word
(
cmap
,
offset
);
switch
(
type
)
switch
(
format
)
{
case
OPENTYPE_CMAP_TABLE_SEGMENT_MAPPING
:
{
CMAP_SegmentMapping_0
*
format
=
(
CMAP_SegmentMapping_0
*
)
table
;
count
+=
GET_BE_WORD
(
format
->
segCountX2
)
/
2
;
count
+=
table_read_be_word
(
cmap
,
offset
+
FIELD_OFFSET
(
struct
cmap_segment_mapping
,
seg_count_x2
))
/
2
;
break
;
}
case
OPENTYPE_CMAP_TABLE_SEGMENTED_COVERAGE
:
{
CMAP_SegmentedCoverage
*
format
=
(
CMAP_SegmentedCoverage
*
)
table
;
count
+=
GET_BE_DWORD
(
format
->
nGroups
);
count
+=
table_read_be_dword
(
cmap
,
offset
+
FIELD_OFFSET
(
struct
cmap_segmented_coverage
,
num_groups
));
break
;
}
default:
FIXME
(
"table
type %i unhandled.
\n
"
,
type
);
FIXME
(
"table
format %u is not supported.
\n
"
,
format
);
}
}
return
count
;
}
HRESULT
opentype_cmap_get_unicode_ranges
(
void
*
data
,
UINT32
max_count
,
DWRITE_UNICODE_RANGE
*
ranges
,
UINT32
*
count
)
HRESULT
opentype_cmap_get_unicode_ranges
(
const
struct
dwrite_fonttable
*
cmap
,
unsigned
int
max_count
,
DWRITE_UNICODE_RANGE
*
ranges
,
unsigned
int
*
count
)
{
CMAP_Header
*
CMAP_Table
=
data
;
int
i
,
k
=
0
;
unsigned
int
i
,
num_tables
,
k
=
0
;
const
struct
cmap_header
*
header
;
if
(
!
CMAP_Table
)
if
(
!
cmap
->
exists
)
return
E_FAIL
;
*
count
=
opentype_cmap_get_unicode_ranges_count
(
CMAP_Table
);
*
count
=
opentype_cmap_get_unicode_ranges_count
(
cmap
);
num_tables
=
table_read_be_word
(
cmap
,
FIELD_OFFSET
(
struct
cmap_header
,
num_tables
));
header
=
table_read_ensure
(
cmap
,
0
,
FIELD_OFFSET
(
struct
cmap_header
,
tables
[
num_tables
]));
for
(
i
=
0
;
i
<
GET_BE_WORD
(
CMAP_Table
->
numTables
)
&&
k
<
max_count
;
i
++
)
if
(
!
header
)
return
S_OK
;
for
(
i
=
0
;
i
<
num_tables
&&
k
<
max_count
;
++
i
)
{
WORD
type
;
WORD
*
table
;
int
j
;
unsigned
int
j
,
offset
,
format
;
if
(
GET_BE_WORD
(
CMAP_Table
->
tables
[
i
].
platformID
)
!=
3
)
if
(
GET_BE_WORD
(
header
->
tables
[
i
].
platformID
)
!=
3
)
continue
;
table
=
(
WORD
*
)(((
BYTE
*
)
CMAP_Table
)
+
GET_BE_DWORD
(
CMAP_Table
->
tables
[
i
].
offset
));
type
=
GET_BE_WORD
(
*
table
);
TRACE
(
"table type %i
\n
"
,
type
);
offset
=
GET_BE_DWORD
(
header
->
tables
[
i
].
offset
);
switch
(
type
)
format
=
table_read_be_word
(
cmap
,
offset
);
switch
(
format
)
{
case
OPENTYPE_CMAP_TABLE_SEGMENT_MAPPING
:
{
CMAP_SegmentMapping_0
*
format
=
(
CMAP_SegmentMapping_0
*
)
table
;
UINT16
segment_count
=
GET_BE_WORD
(
format
->
segCountX2
)
/
2
;
UINT16
*
startCode
=
(
WORD
*
)((
BYTE
*
)
format
+
sizeof
(
CMAP_SegmentMapping_0
)
+
(
sizeof
(
WORD
)
*
segment_count
));
unsigned
int
segment_count
=
table_read_be_word
(
cmap
,
offset
+
FIELD_OFFSET
(
struct
cmap_segment_mapping
,
seg_count_x2
))
/
2
;
const
UINT16
*
start_code
=
table_read_ensure
(
cmap
,
offset
,
FIELD_OFFSET
(
struct
cmap_segment_mapping
,
end_code
[
segment_count
])
+
2
/* reservedPad */
+
2
*
segment_count
/* start code array */
);
const
UINT16
*
end_code
=
table_read_ensure
(
cmap
,
offset
,
FIELD_OFFSET
(
struct
cmap_segment_mapping
,
end_code
[
segment_count
]));
if
(
!
start_code
||
!
end_code
)
continue
;
for
(
j
=
0
;
j
<
segment_count
&&
GET_BE_WORD
(
format
->
endCode
[
j
])
<
0xffff
&&
k
<
max_count
;
j
++
,
k
++
)
{
ranges
[
k
].
first
=
GET_BE_WORD
(
startCode
[
j
]);
ranges
[
k
].
last
=
GET_BE_WORD
(
format
->
endCode
[
j
]);
for
(
j
=
0
;
j
<
segment_count
&&
GET_BE_WORD
(
end_code
[
j
])
!=
0xffff
&&
k
<
max_count
;
++
j
,
++
k
)
{
ranges
[
k
].
first
=
GET_BE_WORD
(
start_code
[
j
]);
ranges
[
k
].
last
=
GET_BE_WORD
(
end_code
[
j
]);
}
break
;
}
case
OPENTYPE_CMAP_TABLE_SEGMENTED_COVERAGE
:
{
CMAP_SegmentedCoverage
*
format
=
(
CMAP_SegmentedCoverage
*
)
table
;
for
(
j
=
0
;
j
<
GET_BE_DWORD
(
format
->
nGroups
)
&&
k
<
max_count
;
j
++
,
k
++
)
{
ranges
[
k
].
first
=
GET_BE_DWORD
(
format
->
groups
[
j
].
startCharCode
);
ranges
[
k
].
last
=
GET_BE_DWORD
(
format
->
groups
[
j
].
endCharCode
);
unsigned
int
num_groups
=
table_read_be_dword
(
cmap
,
offset
+
FIELD_OFFSET
(
struct
cmap_segmented_coverage
,
num_groups
));
const
struct
cmap_segmented_coverage
*
coverage
;
coverage
=
table_read_ensure
(
cmap
,
offset
,
FIELD_OFFSET
(
struct
cmap_segmented_coverage
,
groups
[
num_groups
]));
for
(
j
=
0
;
j
<
num_groups
&&
k
<
max_count
;
j
++
,
k
++
)
{
ranges
[
k
].
first
=
GET_BE_DWORD
(
coverage
->
groups
[
j
].
startCharCode
);
ranges
[
k
].
last
=
GET_BE_DWORD
(
coverage
->
groups
[
j
].
endCharCode
);
}
break
;
}
default:
FIXME
(
"table
type %i unhandled.
\n
"
,
type
);
FIXME
(
"table
format %u unhandled.
\n
"
,
format
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment