[sfnt] Avoid undefined shifts in `COLR` v1 paint parsing * src/sfnt/ttcolr.c (read_paint, tt_face_get_paint): Tighten shift behavior by using multiplication, mostly using macros from ftcalc.h. Fixes: https://bugs.chromium.org/p/chromium/issues/detail?id=1269168
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c
index deec80b..8f5cc8b 100644
--- a/src/sfnt/ttcolr.c
+++ b/src/sfnt/ttcolr.c
@@ -27,6 +27,7 @@
*/
+#include <freetype/internal/ftcalc.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftstream.h>
#include <freetype/tttags.h>
@@ -509,12 +510,12 @@
* In order to support variations expose these as FT_Fixed 16.16 values so
* that we can support fractional values after interpolation.
*/
- apaint->u.linear_gradient.p0.x = FT_NEXT_SHORT( p ) << 16;
- apaint->u.linear_gradient.p0.y = FT_NEXT_SHORT( p ) << 16;
- apaint->u.linear_gradient.p1.x = FT_NEXT_SHORT( p ) << 16;
- apaint->u.linear_gradient.p1.y = FT_NEXT_SHORT( p ) << 16;
- apaint->u.linear_gradient.p2.x = FT_NEXT_SHORT( p ) << 16;
- apaint->u.linear_gradient.p2.y = FT_NEXT_SHORT( p ) << 16;
+ apaint->u.linear_gradient.p0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.linear_gradient.p0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.linear_gradient.p1.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.linear_gradient.p1.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.linear_gradient.p2.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.linear_gradient.p2.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
return 1;
}
@@ -525,13 +526,13 @@
&apaint->u.radial_gradient.colorline ) )
return 0;
- apaint->u.radial_gradient.c0.x = FT_NEXT_SHORT( p ) << 16;
- apaint->u.radial_gradient.c0.y = FT_NEXT_SHORT( p ) << 16;
+ apaint->u.radial_gradient.c0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.radial_gradient.c0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
apaint->u.radial_gradient.r0 = FT_NEXT_USHORT( p ) << 16;
- apaint->u.radial_gradient.c1.x = FT_NEXT_SHORT( p ) << 16;
- apaint->u.radial_gradient.c1.y = FT_NEXT_SHORT( p ) << 16;
+ apaint->u.radial_gradient.c1.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.radial_gradient.c1.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
apaint->u.radial_gradient.r1 = FT_NEXT_USHORT( p ) << 16;
@@ -544,11 +545,15 @@
&apaint->u.sweep_gradient.colorline ) )
return 0;
- apaint->u.sweep_gradient.center.x = FT_NEXT_SHORT( p ) << 16;
- apaint->u.sweep_gradient.center.y = FT_NEXT_SHORT( p ) << 16;
+ apaint->u.sweep_gradient.center.x =
+ INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.sweep_gradient.center.y =
+ INT_TO_FIXED( FT_NEXT_SHORT( p ) );
- apaint->u.sweep_gradient.start_angle = FT_NEXT_SHORT( p ) << 2;
- apaint->u.sweep_gradient.end_angle = FT_NEXT_SHORT( p ) << 2;
+ apaint->u.sweep_gradient.start_angle =
+ F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.sweep_gradient.end_angle =
+ F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
return 1;
}
@@ -591,8 +596,8 @@
apaint->u.translate.paint.p = child_table_p;
apaint->u.translate.paint.insert_root_transform = 0;
- apaint->u.translate.dx = FT_NEXT_SHORT( p ) << 16;
- apaint->u.translate.dy = FT_NEXT_SHORT( p ) << 16;
+ apaint->u.translate.dx = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.translate.dy = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
return 1;
}
@@ -610,14 +615,14 @@
apaint->u.scale.paint.insert_root_transform = 0;
/* All scale paints get at least one scale value. */
- apaint->u.scale.scale_x = FT_NEXT_SHORT( p ) << 2;
+ apaint->u.scale.scale_x = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
/* Non-uniform ones read an extra y value. */
if ( apaint->format ==
FT_COLR_PAINTFORMAT_SCALE ||
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER )
- apaint->u.scale.scale_y = FT_NEXT_SHORT( p ) << 2;
+ apaint->u.scale.scale_y = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
else
apaint->u.scale.scale_y = apaint->u.scale.scale_x;
@@ -628,8 +633,8 @@
(FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER )
{
- apaint->u.scale.center_x = FT_NEXT_SHORT ( p ) << 16;
- apaint->u.scale.center_y = FT_NEXT_SHORT ( p ) << 16;
+ apaint->u.scale.center_x = INT_TO_FIXED( FT_NEXT_SHORT ( p ) );
+ apaint->u.scale.center_y = INT_TO_FIXED( FT_NEXT_SHORT ( p ) );
}
else
{
@@ -651,17 +656,13 @@
apaint->u.rotate.paint.p = child_table_p;
apaint->u.rotate.paint.insert_root_transform = 0;
- /* The angle is specified as F2DOT14 and our output type is an FT_Fixed,
- * shift by 2 positions. */
- apaint->u.rotate.angle = FT_NEXT_SHORT( p ) << 2;
+ apaint->u.rotate.angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER )
{
- /* The center is specified as Int16 in font units, shift by 16 bits to
- * convert to our FT_Fixed output type. */
- apaint->u.rotate.center_x = FT_NEXT_SHORT( p ) << 16;
- apaint->u.rotate.center_y = FT_NEXT_SHORT( p ) << 16;
+ apaint->u.rotate.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.rotate.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
}
else
{
@@ -681,14 +682,14 @@
apaint->u.skew.paint.p = child_table_p;
apaint->u.skew.paint.insert_root_transform = 0;
- apaint->u.skew.x_skew_angle = FT_NEXT_SHORT( p ) << 2;
- apaint->u.skew.y_skew_angle = FT_NEXT_SHORT( p ) << 2;
+ apaint->u.skew.x_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.skew.y_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
if ( (FT_PaintFormat_Internal)apaint->format ==
FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER )
{
- apaint->u.skew.center_x = FT_NEXT_SHORT( p ) << 16;
- apaint->u.skew.center_y = FT_NEXT_SHORT( p ) << 16;
+ apaint->u.skew.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.skew.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
}
else
{
@@ -1094,9 +1095,9 @@
if ( face->root.internal->transform_flags & 2 )
{
paint->u.transform.affine.dx =
- face->root.internal->transform_delta.x << 10;
+ face->root.internal->transform_delta.x * ( 1 << 10 );
paint->u.transform.affine.dy =
- face->root.internal->transform_delta.y << 10;
+ face->root.internal->transform_delta.y * ( 1 << 10 );
}
else
{