Commit 11128e23 authored by Martin Storsjö's avatar Martin Storsjö Committed by Alexandre Julliard

wineps.drv: Avoid invalid unaligned accesses.

While armv7 generally tolerates unaligned loads/stores in most cases, the compiler is free to use the ldrd/strd instructions, for loading/storing two consecutive 32 bit registers, and this requires the destination to be aligned to a 4 byte boundary. When packing a number of variable length structures, make sure that each actual struct gets aligned at the right address boundary. This fixes crashes in DllMain of wineps.drv, when built for armv7, since 351e58dc. Signed-off-by: 's avatarMartin Storsjö <martin@martin.st>
parent adf5f5fd
...@@ -133,6 +133,10 @@ static BOOL import_ntf_from_reg(void) ...@@ -133,6 +133,10 @@ static BOOL import_ntf_from_reg(void)
return ret; return ret;
} }
#define DWORD_ALIGN(x) (((x) + 3) & ~3)
#define ntf_strsize(str) DWORD_ALIGN(strlen(str) + 1)
#define ntf_wcssize(str) DWORD_ALIGN((wcslen(str) + 1) * sizeof(WCHAR))
static BOOL convert_afm_to_ntf(void) static BOOL convert_afm_to_ntf(void)
{ {
int i, count, size, off, metrics_size; int i, count, size, off, metrics_size;
...@@ -176,8 +180,8 @@ static BOOL convert_afm_to_ntf(void) ...@@ -176,8 +180,8 @@ static BOOL convert_afm_to_ntf(void)
list = (void *)(data + header->glyph_set_off + sizeof(*list) * count); list = (void *)(data + header->glyph_set_off + sizeof(*list) * count);
list->name_off = off + sizeof(*glyph_set); list->name_off = off + sizeof(*glyph_set);
list->size = sizeof(*glyph_set) + strlen(glyph_set_name) + 1 + sizeof(*cp) + list->size = sizeof(*glyph_set) + ntf_strsize(glyph_set_name) + sizeof(*cp) +
sizeof(short) * afmle->afm->NumofMetrics; DWORD_ALIGN(sizeof(short) * afmle->afm->NumofMetrics);
list->off = off; list->off = off;
size += list->size; size += list->size;
new_data = realloc(data, size); new_data = realloc(data, size);
...@@ -196,7 +200,7 @@ static BOOL convert_afm_to_ntf(void) ...@@ -196,7 +200,7 @@ static BOOL convert_afm_to_ntf(void)
glyph_set->name_off = sizeof(*glyph_set); glyph_set->name_off = sizeof(*glyph_set);
glyph_set->glyph_count = afmle->afm->NumofMetrics; glyph_set->glyph_count = afmle->afm->NumofMetrics;
glyph_set->cp_count = 1; glyph_set->cp_count = 1;
glyph_set->cp_off = glyph_set->name_off + strlen(glyph_set_name) + 1; glyph_set->cp_off = glyph_set->name_off + ntf_strsize(glyph_set_name);
glyph_set->glyph_set_off = glyph_set->cp_off + sizeof(*cp); glyph_set->glyph_set_off = glyph_set->cp_off + sizeof(*cp);
strcpy(data + off + glyph_set->name_off, glyph_set_name); strcpy(data + off + glyph_set->name_off, glyph_set_name);
cp = (void *)(data + off + glyph_set->cp_off); cp = (void *)(data + off + glyph_set->cp_off);
...@@ -205,12 +209,11 @@ static BOOL convert_afm_to_ntf(void) ...@@ -205,12 +209,11 @@ static BOOL convert_afm_to_ntf(void)
*(WCHAR*)(data + off + glyph_set->glyph_set_off + i * sizeof(short)) = afmle->afm->Metrics[i].UV; *(WCHAR*)(data + off + glyph_set->glyph_set_off + i * sizeof(short)) = afmle->afm->Metrics[i].UV;
off = size; off = size;
metrics_size = sizeof(IFIMETRICS) + metrics_size = sizeof(IFIMETRICS) + ntf_wcssize(afmle->afm->FamilyName);
(wcslen(afmle->afm->FamilyName) + 1) * sizeof(WCHAR);
list = (void *)(data + header->font_mtx_off + sizeof(*list) * count); list = (void *)(data + header->font_mtx_off + sizeof(*list) * count);
list->name_off = off + sizeof(*font_mtx); list->name_off = off + sizeof(*font_mtx);
list->size = sizeof(*font_mtx) + strlen(afmle->afm->FontName) + 1 + list->size = sizeof(*font_mtx) + ntf_strsize(afmle->afm->FontName) +
strlen(glyph_set_name) + 1 + metrics_size + ntf_strsize(glyph_set_name) + metrics_size +
(afmle->afm->IsFixedPitch ? 0 : sizeof(*width_range) * afmle->afm->NumofMetrics); (afmle->afm->IsFixedPitch ? 0 : sizeof(*width_range) * afmle->afm->NumofMetrics);
list->off = off; list->off = off;
size += list->size; size += list->size;
...@@ -227,9 +230,9 @@ static BOOL convert_afm_to_ntf(void) ...@@ -227,9 +230,9 @@ static BOOL convert_afm_to_ntf(void)
font_mtx = (void *)(data + off); font_mtx = (void *)(data + off);
font_mtx->size = size - off; font_mtx->size = size - off;
font_mtx->name_off = sizeof(*font_mtx); font_mtx->name_off = sizeof(*font_mtx);
font_mtx->glyph_set_name_off = font_mtx->name_off + strlen(afmle->afm->FontName) + 1; font_mtx->glyph_set_name_off = font_mtx->name_off + ntf_strsize(afmle->afm->FontName);
font_mtx->glyph_count = afmle->afm->NumofMetrics; font_mtx->glyph_count = afmle->afm->NumofMetrics;
font_mtx->metrics_off = font_mtx->glyph_set_name_off + strlen(glyph_set_name) + 1; font_mtx->metrics_off = font_mtx->glyph_set_name_off + ntf_strsize(glyph_set_name);
font_mtx->width_count = afmle->afm->IsFixedPitch ? 0 : afmle->afm->NumofMetrics; font_mtx->width_count = afmle->afm->IsFixedPitch ? 0 : afmle->afm->NumofMetrics;
font_mtx->width_off = font_mtx->metrics_off + metrics_size; font_mtx->width_off = font_mtx->metrics_off + metrics_size;
font_mtx->def_width = afmle->afm->Metrics[0].WX; font_mtx->def_width = afmle->afm->Metrics[0].WX;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment