From 81ba39f0d28a9ea9d284b031517ebd0f2684d4ff Mon Sep 17 00:00:00 2001 From: Oleg Oshmyan Date: Fri, 3 Feb 2017 21:34:13 +0200 Subject: Fix parsing of unusual Alignment values in ASS style definitions Handle large and negative values except INT32_MIN like VSFilter. This avoids both overflow and inconsistent internal state. This fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=523. VSFilter handles INT32_MIN like a mix of \an1, \an2 and \an3: * Vertical alignment is bottom. * Lines within the event are center-aligned. * Without \pos or \move, the center of the event is aligned with the right edge of the screen minus MarginR. * With \pos or \move, the left edge of the event is aligned with the position point. * Without \org, the rotation origin is aligned with the horizontal center of the event. * (With \org, the rotation origin is as specified.) If we wanted to emulate this in libass, the cleanest way would be to introduce a new horizontal alignment constant for this purpose that would be used only for ASS style definitions with Alignment INT32_MIN. This commit makes no attempt to do this and instead arbitrarily picks \an2 for style definitions with Alignment -INT_MAX-1, which equals INT32_MIN if int is int32_t. The fact that int is platform-dependent is one of the reasons for this. We could change Alignment to be int32_t instead of int for perfect VSFilter compatibility, but the same applies to many other fields that currently use platform-dependent types. --- libass/ass.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'libass') diff --git a/libass/ass.c b/libass/ass.c index e8cefc5..3a94290 100644 --- a/libass/ass.c +++ b/libass/ass.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -241,12 +242,20 @@ static long long string2timecode(ASS_Library *library, char *p) */ static int numpad2align(int val) { - int res, v; - v = (val - 1) / 3; // 0, 1 or 2 for vertical alignment - if (v != 0) - v = 3 - v; - res = ((val - 1) % 3) + 1; // horizontal alignment - res += v * 4; + if (val < -INT_MAX) + // Pick an alignment somewhat arbitrarily. VSFilter handles + // INT32_MIN as a mix of 1, 2 and 3, so prefer one of those values. + val = 2; + else if (val < 0) + val = -val; + + int res = ((val - 1) % 3) + 1; // horizontal alignment + if (val <= 3) + res |= VALIGN_SUB; + else if (val <= 6) + res |= VALIGN_CENTER; + else + res |= VALIGN_TOP; return res; } -- cgit v1.2.3