Hand-written, based on the text example in Appendix G.2 in
the PDF 1.7 spec, with the xref table fixed up by `mutool clean`:
mutool clean -dggg Tests/LibPDF/text.pdf Tests/LibPDF/text.pdf
Per 5177.Type2.pdf 3.1 "Type 2 Charstring Organization",
a glyph's charstring looks like:
w? {hs* vs* cm* hm* mt subpath}? {mt subpath}* endchar
The `w?` is the width of the glyph, but it's optional. So all
possible commands after it (hstem* vstem* cntrmask hintmask
moveto endchar) check if there's an extra number at the start
and interpret it as a width, for the very first command we read.
This was done by having an `is_first_command` local bool that
got set to false after the first command. That didn't work with
subrs: If the first command was a call to a subr that just pushed
a bunch of numbers, then the second command after it is the actual
first command.
Instead, move that bool into the state. Set it to false the
first time we try to read a width, since that means we just read
a command that could've been prefixed by a width.
Previously, certain crafted input could cause the JS parser to hang, as
it repeatedly tried to parse an EOF token after hitting an "invalid
destructuring assignment target" error. This change ensures that we
stop parsing after hitting this error condition.
Images can have multiple filters, each one of them is processed
sequentially. Only the last one will be relevant for the image format
(DCT or JPXDecode), so use the last filter instead of the first one to
detect that property.
For valid PDFs, this makes no difference.
For invalid PDFs, we now assert during the cast in resolve_to() instead
of returning a PDFError. However, most PDFs are valid, and even for
invalid PDFs, we'd previously keep the old color space around when
getting the PDF error and then usually assert later when the old
color space got passed a color with an unexpected number of components
(since the components were for the new color space).
Doesn't affect any of the > 2000 PDFs I use for testing locally,
is less code, and should make for less surprising asserts when it
does happen.
Namely, for CalGrayColorSpace, CalRGBColorSpace, LabColorSpace.
Fixes a crash rendering any page of Adobe's 5014.CIDFont_Spec.pdf
(which uses CalRGBColorSpace with an indirect dict: The dict is
object `92 0`, and many color spaces are inline objects referring
to it).
Since we already call `Painter::flush()` in `PageHost::paint()` we do
not need to do that again in `PaintingCommandExecutorGPU` destructor.
This makes GPU painting run noticeably faster because `flush()` does
expensive `glReadPixels()` call.
Array.length is magical (since it has to reflect the number of elements
in the object's property storage).
We now handle it specially in jitted code, giving us a massive speed-up
on Kraken/ai-astar.js (and probably many other things as well) :^)
Until now, the unwind context stack has not been maintained by jitted
code, which meant we were unable to support the `with` statement.
This is a first step towards supporting that by making jitted code
call out to C++ to update the unwind context stack when entering/leaving
unwind contexts.
We also introduce a new "Catch" bytecode instruction that moves the
current exception into the accumulator. It's always emitted at the start
of a "catch" block.
The differencing predictor is a different way to encode pixels in TIFF
images. Every pixel is encoded as a difference with the previous column
of the image, except the first column, obviously.
This parameter is materialized by a new tag for which reading was also
implemented.
Some users of the LZW algorithm use a different value to determine when
the size of the code changes. GIF increments the size when the number of
elements in the table is equal to 2^code_size while TIFF does it for a
count of 2^code_size - 1.
This patch adds the parameter m_offset_for_size_change with a default
value of 0 and our decoder will increment the code size when we reach
a table length of 2^code_size + m_offset_for_size_change. This allows us
to support both situations.
Previously, it was possible for a `TextDescriptionTagData` object with
an incorrect Macintosh ScriptCode description length to cause a buffer
overflow.
Audio loaders currently always output two channels, even if they were
encoded as mono. Therefore, we have to hardcode the channel count in
our audio plugin to avoid crashing until we can handle mono or multi-
channel audio better.
Fixes#21898
I didn't find example code for this and the AI assistant did very
poorly on this as well. So I had to write it all by myself!
It can be much more efficient I think, but I think the overall
shape is maybe roughly fine.
This only tracks whether the relevant steps should be executed at some
future (but very soon) time. This time will eventually be whenever the
"update animations and send events" procedure is invoked.