diff -u freetype-2.8.1/debian/changelog freetype-2.8.1/debian/changelog --- freetype-2.8.1/debian/changelog +++ freetype-2.8.1/debian/changelog @@ -1,3 +1,12 @@ +freetype (2.8.1-2ubuntu2) bionic; urgency=medium + + * d/p/0001-truetype-Fix-mmvar-array-pointers.patch, + d/p/0001-truetype-Fix-mmvar-array-pointers-part-2.patch: cherry-picks + from upstream to fix unaligned access on armhf, detected via harfbuzz + build-time test failure. + + -- Steve Langasek Thu, 12 Apr 2018 20:27:12 -0700 + freetype (2.8.1-2ubuntu1) bionic; urgency=low * Merge from Debian unstable. Remaining changes: diff -u freetype-2.8.1/debian/patches-freetype/series freetype-2.8.1/debian/patches-freetype/series --- freetype-2.8.1/debian/patches-freetype/series +++ freetype-2.8.1/debian/patches-freetype/series @@ -6,0 +7,2 @@ +0001-truetype-Fix-mmvar-array-pointers.patch +0001-truetype-Fix-mmvar-array-pointers-part-2.patch only in patch2: unchanged: --- freetype-2.8.1.orig/debian/patches-freetype/0001-truetype-Fix-mmvar-array-pointers-part-2.patch +++ freetype-2.8.1/debian/patches-freetype/0001-truetype-Fix-mmvar-array-pointers-part-2.patch @@ -0,0 +1,260 @@ +From b19cdc9c8164cd81801024b024ce132bcb4a29f1 Mon Sep 17 00:00:00 2001 +From: Werner Lemberg +Date: Thu, 21 Sep 2017 11:02:35 +0200 +Subject: [PATCH] [truetype] Fix `mmvar' array pointers, part 2. + +The previous commit was incomplete. + +* src/truetype/ttgxvar.c: Properly initialize sub-array offsets for +`master' also. +--- + ChangeLog | 9 ++++ + src/truetype/ttgxvar.c | 129 ++++++++++++++++++++++++++----------------------- + 2 files changed, 78 insertions(+), 60 deletions(-) + +Index: freetype-2.8.1/src/truetype/ttgxvar.c +=================================================================== +--- freetype-2.8.1.orig/src/truetype/ttgxvar.c ++++ freetype-2.8.1/src/truetype/ttgxvar.c +@@ -1940,11 +1940,11 @@ + TT_Get_MM_Var( TT_Face face, + FT_MM_Var* *master ) + { +- FT_Stream stream = face->root.stream; +- FT_Memory memory = face->root.memory; ++ FT_Stream stream = face->root.stream; ++ FT_Memory memory = face->root.memory; + FT_ULong table_len; +- FT_Error error = FT_Err_Ok; +- FT_ULong fvar_start; ++ FT_Error error = FT_Err_Ok; ++ FT_ULong fvar_start = 0; + FT_UInt i, j; + FT_MM_Var* mmvar = NULL; + FT_Fixed* next_coords; +@@ -1954,10 +1954,20 @@ + FT_Fixed* c; + FT_Var_Named_Style* ns; + GX_FVar_Head fvar_head; +- FT_Bool usePsName; ++ FT_Bool usePsName = 0; + FT_UInt num_instances; ++ FT_UInt num_axes; + FT_UShort* axis_flags; + ++ FT_Offset mmvar_size; ++ FT_Offset axis_flags_size; ++ FT_Offset axis_size; ++ FT_Offset namedstyle_size; ++ FT_Offset next_coords_size; ++ FT_Offset next_name_size; ++ ++ FT_Bool need_init; ++ + static const FT_Frame_Field fvar_fields[] = + { + +@@ -1995,16 +2005,10 @@ + /* read the font data and set up the internal representation */ + /* if not already done */ + +- if ( !face->blend ) +- { +- FT_Offset mmvar_size; +- FT_Offset axis_flags_size; +- FT_Offset axis_size; +- FT_Offset namedstyle_size; +- FT_Offset next_coords_size; +- FT_Offset next_name_size; +- ++ need_init = !face->blend; + ++ if ( need_init ) ++ { + FT_TRACE2(( "FVAR " )); + + /* both `fvar' and `gvar' must be present */ +@@ -2045,36 +2049,43 @@ + if ( FT_NEW( face->blend ) ) + goto Exit; + +- /* `num_instances' holds the number of all named instances, */ +- /* including the default instance which might be missing */ +- /* in fvar's table of named instances */ +- num_instances = face->root.style_flags >> 16; +- +- /* prepare storage area for MM data; this cannot overflow */ +- /* 32-bit arithmetic because of the size limits used in the */ +- /* `fvar' table validity check in `sfnt_init_face' */ +- +- /* the various `*_size' variables, which we also use as */ +- /* offsets into the `mmlen' array, must be multiples of the */ +- /* pointer size (except the last one); without such an */ +- /* alignment there might be runtime errors due to */ +- /* misaligned addresses */ ++ num_axes = fvar_head.axisCount; ++ } ++ else ++ num_axes = face->blend->num_axis; ++ ++ /* `num_instances' holds the number of all named instances, */ ++ /* including the default instance which might be missing */ ++ /* in fvar's table of named instances */ ++ num_instances = face->root.style_flags >> 16; ++ ++ /* prepare storage area for MM data; this cannot overflow */ ++ /* 32-bit arithmetic because of the size limits used in the */ ++ /* `fvar' table validity check in `sfnt_init_face' */ ++ ++ /* the various `*_size' variables, which we also use as */ ++ /* offsets into the `mmlen' array, must be multiples of the */ ++ /* pointer size (except the last one); without such an */ ++ /* alignment there might be runtime errors due to */ ++ /* misaligned addresses */ + #undef ALIGN_SIZE + #define ALIGN_SIZE( n ) \ + ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) ) + +- mmvar_size = ALIGN_SIZE( sizeof ( FT_MM_Var ) ); +- axis_flags_size = ALIGN_SIZE( fvar_head.axisCount * +- sizeof ( FT_UShort ) ); +- axis_size = ALIGN_SIZE( fvar_head.axisCount * +- sizeof ( FT_Var_Axis ) ); +- namedstyle_size = ALIGN_SIZE( num_instances * +- sizeof ( FT_Var_Named_Style ) ); +- next_coords_size = ALIGN_SIZE( num_instances * +- fvar_head.axisCount * +- sizeof ( FT_Fixed ) ); +- next_name_size = fvar_head.axisCount * 5; ++ mmvar_size = ALIGN_SIZE( sizeof ( FT_MM_Var ) ); ++ axis_flags_size = ALIGN_SIZE( num_axes * ++ sizeof ( FT_UShort ) ); ++ axis_size = ALIGN_SIZE( num_axes * ++ sizeof ( FT_Var_Axis ) ); ++ namedstyle_size = ALIGN_SIZE( num_instances * ++ sizeof ( FT_Var_Named_Style ) ); ++ next_coords_size = ALIGN_SIZE( num_instances * ++ num_axes * ++ sizeof ( FT_Fixed ) ); ++ next_name_size = num_axes * 5; + ++ if ( need_init ) ++ { + face->blend->mmvar_len = mmvar_size + + axis_flags_size + + axis_size + +@@ -2090,7 +2101,7 @@ + /* the data gets filled in later on */ + + mmvar->num_axis = +- fvar_head.axisCount; ++ num_axes; + mmvar->num_designs = + ~0U; /* meaningless in this context; each glyph */ + /* may have a different number of designs */ +@@ -2111,12 +2122,12 @@ + for ( i = 0; i < num_instances; i++ ) + { + mmvar->namedstyle[i].coords = next_coords; +- next_coords += fvar_head.axisCount; ++ next_coords += num_axes; + } + + next_name = (FT_String*)( (char*)mmvar->namedstyle + + namedstyle_size + next_coords_size ); +- for ( i = 0; i < fvar_head.axisCount; i++ ) ++ for ( i = 0; i < num_axes; i++ ) + { + mmvar->axis[i].name = next_name; + next_name += 5; +@@ -2128,7 +2139,7 @@ + goto Exit; + + a = mmvar->axis; +- for ( i = 0; i < fvar_head.axisCount; i++ ) ++ for ( i = 0; i < num_axes; i++ ) + { + GX_FVar_Axis axis_rec; + +@@ -2178,7 +2189,7 @@ + /* named instance coordinates are stored as design coordinates; */ + /* we have to convert them to normalized coordinates also */ + if ( FT_NEW_ARRAY( face->blend->normalized_stylecoords, +- fvar_head.axisCount * num_instances ) ) ++ num_axes * num_instances ) ) + goto Exit; + + if ( fvar_head.instanceCount && !face->blend->avar_loaded ) +@@ -2198,14 +2209,14 @@ + { + /* PostScript names add 2 bytes to the instance record size */ + if ( FT_FRAME_ENTER( ( usePsName ? 6L : 4L ) + +- 4L * fvar_head.axisCount ) ) ++ 4L * num_axes ) ) + goto Exit; + + ns->strid = FT_GET_USHORT(); + (void) /* flags = */ FT_GET_USHORT(); + + c = ns->coords; +- for ( j = 0; j < fvar_head.axisCount; j++, c++ ) ++ for ( j = 0; j < num_axes; j++, c++ ) + *c = FT_GET_LONG(); + + /* valid psid values are 6, [256;32767], and 0xFFFF */ +@@ -2214,11 +2225,8 @@ + else + ns->psid = 0xFFFF; + +- ft_var_to_normalized( face, +- fvar_head.axisCount, +- ns->coords, +- nsc ); +- nsc += fvar_head.axisCount; ++ ft_var_to_normalized( face, num_axes, ns->coords, nsc ); ++ nsc += num_axes; + + FT_FRAME_EXIT(); + } +@@ -2267,7 +2275,7 @@ + + a = mmvar->axis; + c = ns->coords; +- for ( j = 0; j < fvar_head.axisCount; j++, a++, c++ ) ++ for ( j = 0; j < num_axes; j++, a++, c++ ) + *c = a->def; + } + } +@@ -2288,23 +2296,24 @@ + FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); + + axis_flags = +- (FT_UShort*)&( mmvar[1] ); ++ (FT_UShort*)( (char*)mmvar + mmvar_size ); + mmvar->axis = +- (FT_Var_Axis*)&( axis_flags[mmvar->num_axis] ); ++ (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size ); + mmvar->namedstyle = +- (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] ); ++ (FT_Var_Named_Style*)( (char*)mmvar->axis+ axis_size ); + +- next_coords = +- (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] ); ++ next_coords = (FT_Fixed*)( (char*)mmvar->namedstyle + ++ namedstyle_size ); + for ( n = 0; n < mmvar->num_namedstyles; n++ ) + { + mmvar->namedstyle[n].coords = next_coords; +- next_coords += mmvar->num_axis; ++ next_coords += num_axes; + } + + a = mmvar->axis; +- next_name = (FT_String*)next_coords; +- for ( n = 0; n < mmvar->num_axis; n++ ) ++ next_name = (FT_String*)( (char*)mmvar->namedstyle + ++ namedstyle_size + next_coords_size ); ++ for ( n = 0; n < num_axes; n++ ) + { + a->name = next_name; + only in patch2: unchanged: --- freetype-2.8.1.orig/debian/patches-freetype/0001-truetype-Fix-mmvar-array-pointers.patch +++ freetype-2.8.1/debian/patches-freetype/0001-truetype-Fix-mmvar-array-pointers.patch @@ -0,0 +1,105 @@ +From 3b3cb32dd2340d86d3165961a4bb3dbd44353075 Mon Sep 17 00:00:00 2001 +From: Werner Lemberg +Date: Thu, 21 Sep 2017 09:03:20 +0200 +Subject: [PATCH] [truetype] Fix `mmvar' array pointers. + +Without this change, clang's AddressSanitizer reports many runtime +errors due to misaligned addresses. + +* src/truetype/ttgxvar.c (TT_Get_MM_Var): Use multiples of pointer +size for sub-array offsets into `mmvar'. +--- + ChangeLog | 10 +++++++++ + src/truetype/ttgxvar.c | 56 ++++++++++++++++++++++++++++++++++++++------------ + 2 files changed, 53 insertions(+), 13 deletions(-) + +Index: freetype-2.8.1/src/truetype/ttgxvar.c +=================================================================== +--- freetype-2.8.1.orig/src/truetype/ttgxvar.c ++++ freetype-2.8.1/src/truetype/ttgxvar.c +@@ -1997,6 +1997,14 @@ + + if ( !face->blend ) + { ++ FT_Offset mmvar_size; ++ FT_Offset axis_flags_size; ++ FT_Offset axis_size; ++ FT_Offset namedstyle_size; ++ FT_Offset next_coords_size; ++ FT_Offset next_name_size; ++ ++ + FT_TRACE2(( "FVAR " )); + + /* both `fvar' and `gvar' must be present */ +@@ -2045,13 +2053,34 @@ + /* prepare storage area for MM data; this cannot overflow */ + /* 32-bit arithmetic because of the size limits used in the */ + /* `fvar' table validity check in `sfnt_init_face' */ +- face->blend->mmvar_len = +- sizeof ( FT_MM_Var ) + +- fvar_head.axisCount * sizeof ( FT_UShort ) + +- fvar_head.axisCount * sizeof ( FT_Var_Axis ) + +- num_instances * sizeof ( FT_Var_Named_Style ) + +- num_instances * fvar_head.axisCount * sizeof ( FT_Fixed ) + +- fvar_head.axisCount * 5; ++ ++ /* the various `*_size' variables, which we also use as */ ++ /* offsets into the `mmlen' array, must be multiples of the */ ++ /* pointer size (except the last one); without such an */ ++ /* alignment there might be runtime errors due to */ ++ /* misaligned addresses */ ++#undef ALIGN_SIZE ++#define ALIGN_SIZE( n ) \ ++ ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) ) ++ ++ mmvar_size = ALIGN_SIZE( sizeof ( FT_MM_Var ) ); ++ axis_flags_size = ALIGN_SIZE( fvar_head.axisCount * ++ sizeof ( FT_UShort ) ); ++ axis_size = ALIGN_SIZE( fvar_head.axisCount * ++ sizeof ( FT_Var_Axis ) ); ++ namedstyle_size = ALIGN_SIZE( num_instances * ++ sizeof ( FT_Var_Named_Style ) ); ++ next_coords_size = ALIGN_SIZE( num_instances * ++ fvar_head.axisCount * ++ sizeof ( FT_Fixed ) ); ++ next_name_size = fvar_head.axisCount * 5; ++ ++ face->blend->mmvar_len = mmvar_size + ++ axis_flags_size + ++ axis_size + ++ namedstyle_size + ++ next_coords_size + ++ next_name_size; + + if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) + goto Exit; +@@ -2071,21 +2100,22 @@ + + /* alas, no public field in `FT_Var_Axis' for axis flags */ + axis_flags = +- (FT_UShort*)&( mmvar[1] ); ++ (FT_UShort*)( (char*)mmvar + mmvar_size ); + mmvar->axis = +- (FT_Var_Axis*)&( axis_flags[fvar_head.axisCount] ); ++ (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size ); + mmvar->namedstyle = +- (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] ); ++ (FT_Var_Named_Style*)( (char*)mmvar->axis + axis_size ); + +- next_coords = +- (FT_Fixed*)&( mmvar->namedstyle[num_instances] ); ++ next_coords = (FT_Fixed*)( (char*)mmvar->namedstyle + ++ namedstyle_size ); + for ( i = 0; i < num_instances; i++ ) + { + mmvar->namedstyle[i].coords = next_coords; + next_coords += fvar_head.axisCount; + } + +- next_name = (FT_String*)next_coords; ++ next_name = (FT_String*)( (char*)mmvar->namedstyle + ++ namedstyle_size + next_coords_size ); + for ( i = 0; i < fvar_head.axisCount; i++ ) + { + mmvar->axis[i].name = next_name;