| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
Unused since commit c80f332798238731e1ddf1b541748f3d5c8030f3.
|
|
|
|
|
| |
ass_msg's callback will most likely use vprintf. Passing NULL as %s to
a _printf function is undefined behaviour.
|
|
|
|
|
|
|
| |
We already ensure at creation that all styles have a non-null FontName.
However font family strings are strduped at various places and NULLs
cannot be fully avoided, since already the very first font strdup may
fail, so additional checks are required.
|
|
|
|
|
|
|
| |
We can't parse the style without a valid style_format.
If strdup for FontName or Name or there fallback values fails,
the style is of no use, so discard it. As the removal happens before any
other styles are added, just decreasing n_styles is safe here.
|
|
|
|
|
|
|
|
|
| |
strdup failures for event->Text and event->Effect are already guarded
against in ass_render.c and ass_parse.c.
event->Name is never used, thus also safe.
At this point event_format is guaranteed to be valid, so it doesn't
need to be checked.
|
|
|
|
|
| |
In case of strdup-failure track->event_format can be assigned NULL in
event_format_fallback or in process_events_line
|
|
|
|
|
|
|
|
|
|
|
| |
Strictly speaking this is not neccessary in regular processing as the
event and font fields are intialised with zeroes anyway and there's no
old value to fallback too.
However when processing style overrides, this can prevent a non-null
value being replaced by NULL.
This commit also gets rid of the unneccessary '!= NULL' check. Passing
NULL to free is well defined and safe.
|
|
|
|
|
|
|
|
| |
This way we can ensure that there's always one style in the track (which
some parts of the code already assume) and that this style is actually
valid.
If the style alloc fails, the whole track alloc will fail and we're
likely seriously short on memory anyway
|
|
|
|
|
|
|
|
|
|
| |
In case of files whose size is close to or exceeds SIZE_MAX it was
possible to trigger an overflow while calculating new_size.
Although ASS_REALLOC_ARRAY already deals with the most problematic case
of an overflow yielding new_size == 0, continuing will only yield
garbage fontdata at the end, so we might as well abort right away.
Unrelated: correct return code for mangled lines
|
|
|
|
|
|
|
|
|
|
|
|
| |
size_t is a more sensible type for as it is unsigned and accurately
represents the theoretical limits of object size. int may be larger or
smaller than size_t, which both would lead to problems and potential UB
with signed overflow.
There was no usage of negative values as error flags or similar and
those two fields are not part of the public API, so this change should
be safe.
To stay consistent, also adjust types of related variables in functions.
|
| |
|
| |
|
|
|
|
|
|
| |
Also deal with potential overflows of style and event count.
Since these fields are ints part ofthe public API, but will be cast to
size_t in ASS_REALLOC_ARRAY use the smaller of both limits.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
| |
CoreText's "family name" can use TT_NAME_ID_TYPOGRAPHIC_FAMILY names,
which we ignore for compatibility with VSFilter. As a result, fallback
returns a family name that we then fail to find, and fallback fails.
Return a fuller name (fullname or postscriptname as appropriate)
instead, which should be more reliable.
|
|
|
|
|
|
|
|
|
| |
Contrary to what the comments suggest Segment does not use one
absolute reference point and relative offsets, but two absolute points,
making it practically identical to the previously defined Rect with
a <-> y0, b <-> y1, ha <-> x0, hb <-> x1
For simplicity replace Segment with Rect.
|
| |
|
|
|
|
|
|
|
|
|
| |
Edit by Oleg Oshmyan <chortos@inbox.lv>:
Move the final ass_shaper_shape returns inside the switch.
Add a default case in ass_shaper_shape to proactively placate
static analysers that might decide the switch is not exhaustive
and we therefore don't return a value. We know it is actually
exhaustive as we validate the shaper selection in ass_set_shaper.
|
| |
|
| |
|
|
|
|
| |
That triggers undefined behavior.
|
| |
|
|
|
|
|
|
|
| |
Previously, drawings would get shape_run_id = 0 from calloc.
Most of the time, this separated them from text shape runs,
but drawings immediately following the very first shape run
would get appended to it. Make sure this cannot happen.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A libass-chosen shaping run boundary can coincide with a bidi embedding level
boundary such that the differences in shaper_run_id and emblevel cancel out.
For example:
English עבריתEnglish again (with parentheses)
(with no space after the Hebrew)
has ass_shaper_find_runs split runs after the Hebrew, adding 1 to shape_run_id,
while the RTL embed also ends in the same place, removing 1 from emblevel.
As a result, two shape runs that should be separate merge together.
In this example, this leads to HarfBuzz thinking that "English again (with
parentheses)" is still right-to-left, so it flips the parenthesis glyphs.
To avoid this, don't attempt to add these numbers together. Just require
explicitly that both numbers stay constant, rather than their sum.
|
| |
|
|
|
|
|
|
|
|
|
| |
This removes duplicated code (and a not-fully-correct comment).
This also ensures shaping has breaks whenever the rest
of the pipeline breaks runs (e. g. for bitmap combining).
In particular, this adds missing breaks on karaoke changes,
which the old code didn't actually honor despite the comment.
|
|
|
|
|
|
|
|
|
| |
U+FFFC can not only come from drawings but also be actually contained
in the source text. In that case, handle it like any other character.
This doesn't distinguish source-text U+FFFC from drawings
whose strdup failed. But the whole rest of the pipeline
treats those drawings as plain U+FFFC characters, too.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The "bitmap runs" that are currently used only when combining bitmaps
are also relevant at other stages, mainly for VSFilter compatibility.
They are not currently used because this information is not available
until bitmap combining (except during shaping, which has its own "shape
runs" that duplicate a good chunk of the "bitmap run" logic).
Move some code around to compute run boundaries as early as possible.
This lays the foundation for future commits that will make use this
information in more places where it can simplify code or improve
VSFilter compatibility.
For VSFilter compatibility, rather than break runs immediately upon line
breaks, break runs after line-leading whitespace, even in the first line.
These runs correspond to VSFilter's CWord instances.
|
|
|
|
|
|
|
|
|
|
|
| |
Well, that was easy.
font->desc.family is the raw family name from FontName/\fn,
barring the leading @ for vertical fonts. So, for reference,
even if the script requests two different font names and neither
exists on the system and font fallback picks the same font
for both, is_new_bm_run will treat them as distinct.
This is indeed the desired behaviour that matches VSFilter.
|
| |
|
|
|
|
| |
This matches VSFilter.
|
|
|
|
|
|
|
|
| |
The coordinate computed for the text's top edge was actually used for
the baseline of the text's top line, causing the first line's ascender
to protrude up and the whole text to be shifted up by that ascender.
(Note: in this context, bbox.y_min == text_info->lines[0].asc.)
|
|
|
|
| |
VSFilter does no such thing.
|
| |
|
|
|
|
| |
That's what VSFilter does.
|
|
|
|
|
|
|
|
|
| |
Make Banner default to \q2, but allow explicit line breaks and \q overrides.
Justify the lines according to \a etc., and wrap lines as usual if \q is
overridden, but make sure to keep the left/right edge of the whole event flush
with the edge of the screen at the event's start time as required by Banner.
This is what VSFilter does.
|
|
|
|
|
|
|
|
| |
The "depends on alignment" block is useless: if use_margins, then
the coordinates will be overridden, but if not, then all of the
various x/y2scr... calls delegate to x/y2scr_pos...
Rewrite several lines using FFMIN/FFMAX to keep them short.
|
|
|
|
|
|
|
|
| |
On exotic (or future) platforms, types such as size_t and uint32_t may
be promoted to int, which allows multiplication, addition and left-shift
operations on these types to overflow (and produce undefined behavior).
To avoid this, make sure that the affected arithmetic operators convert
any promoted operands to unsigned int by the usual arithmetic conversions.
|
|
|
|
|
|
| |
For what it's worth, VSFilter does this too, and our mult_alpha
now gives the same results as the corresponding code in VSFilter
for all possible inputs.
|
|
|
|
|
|
|
|
|
|
|
|
| |
This function is passed alpha values from \fade, which are restricted
to nonnegative values but have no upper limit. Given a large value,
the subtraction and the multiply-divide could wrap around or even
overflow (in case of integer promotion to signed int). Overflow
is undesirable due to undefined behavior, and wraparound is also
undesirable due to VSFilter compatibility.
Rewrite the expression as a simpler equivalent that does not need to deal
with negative numbers and works correctly regardless of integer promotion.
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is incompatible with VSFilter, so maybe we
should later change this to use uint32_t instead.
This fixes the multiply-divide if the result fits in int,
but `PlayResX = PlayResY * 4LL / 3;` still overflows if PlayResY
is close to INT_MAX. This should be addressed in a separate commit.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=533.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=603.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We generally support 64-bit timestamps. However, for better
VSFilter compatibility and to avoid overflow, when handling
\t, \move and \fad(e), parse timestamps with 32 bits like
VSFilter does and perform wraparound 32-bit subtraction.
To match VSFilter results when the parsed arguments are large
but the video/event durations are short, clip the current
frame time and event duration to 32 bits during this.
Note: we generally handle large event and video timestamps differently
from VSFilter (which uses 32 bits throughout) regardless of this commit,
so in a sense, this commit actually breaks our saner rendering of long-
duration events while it remains VSFilter-incompatible. (It does not break
large event/video timestamps per se as long as each individual event's
duration fits in 31 bits.) The gain is VSFilter-compatible rendering when
all video/event timestamps fit in 31 bits but override tags have values
that don't (or whose differences don't) fit.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=542.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=602.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=624.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2721.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3880.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11632.
Closes https://github.com/libass/libass/pull/337.
|
|
|
|
|
|
|
|
|
|
|
| |
If t3 is initially negative, it should be set to a value larger
than the duration of the event. This triggers the `now < t3` branch
in interpolate_alpha (if none of the earlier branches are taken).
The same effect can be achieved by setting t3 to the duration itself.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=531.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3905.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11736.
|
|
|
|
|
|
|
|
|
| |
The value may be bigger than INT32_MAX as long as its *integral part* isn't.
Furthermore, make sure to avoid UB on odd platforms where int32_t limits
aren't exactly representable in double, as this isn't too hard. Do assume
that they're representable at all though. We won't necessarily match
x86 values on such platforms, but we will avoid the undefined behavior.
|
|
|
|
|
|
| |
This is a measure to facilitate testing with different script
and video resolutions. The target PNG file size (unscaled)
is used as video size.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With this, our output can no longer change visually if display resolution
is varied via ass_set_frame_size while everything else is kept constant,
e. g. when a video player window is being resized, regardless of API
(mis)use and script/track properties.
In particular, this stops our \blur from affecting a varying portion
of the screen and our 3D transforms involving \frx or \fry from moving
around as display resolution is being changed. FWIW, this makes our
blur and 3D transforms match MPC-HC's when storage size is unset.
They already matched before this commit when ScaledBorderAndShadow
was true, but now they also match when it is false.
This also makes our borders and shadows scale with display resolution,
effectively making ScaledBorderAndShadow a no-op (always true) if storage
size is unset. FWIW, this does *not* agree with MPC-HC, but it just seems
sensible™.
|
| |
|
|
|
|
|
|
| |
ass_font_clear() can now free family string even in a failure case.
Fixes https://github.com/libass/libass/issues/414.
|
|
|
|
|
|
| |
While FreeType uses FT_Pos for 32-bit values,
the real underlying type is signed long,
so labs() is more appropriate here.
|
| |
|
|
|
|
|
| |
This commit removes prefilters altogether at the cost of
enlarged main filter kernel.
|
|
|
|
|
|
|
| |
This commit enforces strict invariant on ASS_Outline
to contain point coordinates into predetermined range.
Fixes https://github.com/libass/libass/issues/431.
|
|
|
|
|
|
|
|
| |
* Bidirectional isolates
* Arabic letter mark
* Invisible plus
* Variation selectors
* Mongolian control characters
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fixes https://github.com/libass/libass/issues/418.
Fixes https://github.com/libass/libass/issues/427.
Fixes https://github.com/mpv-player/mpv/issues/7712.
A longstanding problem we had was that we ignored leading line breaks
in events. We somewhat accidentally assigned line breaks zero height,
and the code in `measure_text` that halved the height of empty lines
explicitly ignored leading empty lines for some reason. #285 fixed both
of these things: the former in e8d98dafb8d4d1fd80e9d398cfbef7db1e2ccb73,
the latter in 5d03af99c6d8f43be973cb6dacb5d6dd0ada33b1.
But life is not so simple!
It turns out that VSFilter [discards metrics of the line break and
leading/trailing spaces for lines that stay nonempty after whitespace
trimming][1]. So we actually handled nonblank (trimmable-space-less)
lines correctly *before* #285 and have been *mishandling* them
since #285 landed, adding the line break's metrics when they should
be ignored. This is not noticeable in plain text, but it affects cases
when a line's contents have a different height from the line breaks:
{\fs96}foo\N{\p1}m 0 0 l 0 1 1 1 1 0{\p0}\Nbar
{\fs96}foo\N{\fs1}bar{\fs96}\Nbaz
(the middle line should be 1px high, not 96px)
[1]: https://github.com/Cyberbeing/xy-VSFilter/blob/3.0.0.306/src/subtitles/RTS.cpp#L1401-L1422
More complicated cases with trimmable spaces have never been
handled correctly, but this is nevertheless a regression.
To fix this:
* move the `trim_whitespace` call before the `measure_text` call
(they seem independent, so this is easy),
* mark trimmed whitespace with a new dedicated flag in addition
to `.skip` so it can be distinguished from invisible glyphs,
* clear accumulated (line-leading-whitespace) metrics
when each line's first non-trimmed-whitespace glyph is found,
* skip trimmed-whitespace glyphs when the line is already proven
nonblank, because they are certainly line-trailing whitespace.
Note: line breaks themselves do have `.skip` and `.is_trimmed_whitespace`.
Note: our `.linebreak` is set on the glyph *after* the line break.
As a result, a nonblank line will include the metrics only of the glyphs
that (would) remain after trimming leading and trailing whitespace
(including the line break), while a blank line includes the metrics of all
glyphs from its first in-line glyph up to and including the terminating
line break (if any).
At the same time, line height is only halved for lines that are truly empty
and don't even contain any whitespace. (Before the halving, the line height
comes from the line break glyph.)
This matches VSFilter.
|
| |
|
|
|
|
|
| |
VSFilter compatibility: VSFilter does no special handling
of invisible control characters and sees the line as nonempty.
|
|
|
|
|
|
|
|
| |
This reverts commit 6c2120a7cb4a6fd648ef37ad8f0d961cbd60f500.
This turned out never to actually be necessary, wasn't actually consistent
with vsfilter, and could result in script authors relying on
accidentally-introduced deviations from vsfilter font matching.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Providing a negative acceleration to \t could result in undefined behavior due
to overflow in float->int conversion. This codifies the same behavior we
currently have on x86, which matches vsfilter's, without actually invoking UB.
Additionally, vsfilter color animations work subtly differently than ours did.
We used to lerp each individual color component's byte value, while vsfilter
performs the lerp on the component _in place within a larger int_. This didn't
result in major issues for most cases, but could probably result in subtle
rounding errors, and gave vastly different results for \t with negative
acceleration.
Negative \t acceleration is probably completely useless, but our behavior was
wacky in a different way from vsfilter's, and I'd rather have portable
wackiness than libass-specific wackiness.
It might still be possible to invoke UB in negative-acceleration \t using tags
other than colors; we should fix those cases as well.
|
|
|
|
|
| |
This provides higher precision in reported weights when using
the fontconfig font provider.
|
|
|
|
|
|
|
|