]> granicus.if.org Git - libass/commit
Fix buffer overread in parse_tag when end points to a space
authorOleg Oshmyan <chortos@inbox.lv>
Wed, 28 Dec 2016 19:14:21 +0000 (21:14 +0200)
committerOleg Oshmyan <chortos@inbox.lv>
Wed, 28 Dec 2016 22:36:38 +0000 (00:36 +0200)
commit3ebd1945b44327450fec3fdd164f591921c3f281
treed02cd29d84fef3bd3d9f197395226c477c799b05
parentca0ea14cba8b37eb6af8593d8e4adedbc906389f
Fix buffer overread in parse_tag when end points to a space

When parse_tag is invoked recursively to handle the animated tags inside
a \t tag, the `end` argument is taken from the `end` field of a struct arg
in the enclosing parse_tag. When struct arg is filled by push_arg, this
field is always right-trimmed using rskip_spaces. Ultimately, the inner
parse_tag invokation sees its `end` argument point not to the ')' or '}'
of the \t as it expects but rather to the spaces preceding the ')' or '}'.

At this point, when parse_tag calls skip_spaces, which is ignorant of the
end pointer, it happily skips over the spaces preceding the ')', moving the
pointer past `end`. Subsequent `pointer != end` comparisons in parse_tag
fail (as in fact `pointer > end`), and parse_tag thinks it is still inside
the substring to be parsed.

This is harmless in many cases, but given either of the following inputs,
parse_tag reads past the end of the actual buffer that stores the string:

    {\t(\ }
    {\t(\ )(}

After this commit, parse_tag knows that `end` can point to a sequence of
spaces and avoids calling skip_spaces on `end`, thus avoiding the overread.

Discovered by OSS-Fuzz.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=194.
libass/ass_parse.c