mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-10 13:00:29 +03:00
LibPDF: Try harder to use a RAII object to restore state
Follow-up to #21489. There, I made us use a RAII object. That's great, but if the embedded instruction stream pushes its own graphics state, then an early return would cause us to not process graphics state pop instructions in the embedded stream. To fix this, remember the graphics stack depth before entering the nested instruction stream, and explicitly shrink the stack back to that size upon exit. Enables us to render all pages of https://devstreaming-cdn.apple.com/videos/wwdc/2017/821kjtggolzxsv/821/821_get_started_with_display_p3.pdf without crashing.
This commit is contained in:
parent
c5a4c22fa7
commit
609e640530
Notes:
sideshowbarker
2024-07-18 05:01:22 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/609e640530 Pull-request: https://github.com/SerenityOS/serenity/pull/21498
@ -646,20 +646,26 @@ RENDERER_HANDLER(paint_xobject)
|
||||
|
||||
// Use a RAII object to restore the graphics state, to make sure it gets restored even if
|
||||
// a TRY(handle_operator()) causes us to exit the operators loop early.
|
||||
// Explicitly resize stack size at the end so that if the recursive document contains
|
||||
// `q q unsupportedop Q Q`, we undo the stack pushes from the inner `q q` even if
|
||||
// `unsupportedop` terminates processing the inner instruction stream before `Q Q`
|
||||
// would normally pop state.
|
||||
class ScopedState {
|
||||
public:
|
||||
ScopedState(Renderer& renderer)
|
||||
: m_renderer(renderer)
|
||||
, m_starting_stack_depth(m_renderer.m_graphics_state_stack.size())
|
||||
{
|
||||
MUST(m_renderer.handle_save_state({}));
|
||||
}
|
||||
~ScopedState()
|
||||
{
|
||||
MUST(m_renderer.handle_restore_state({}));
|
||||
m_renderer.m_graphics_state_stack.shrink(m_starting_stack_depth);
|
||||
}
|
||||
|
||||
private:
|
||||
Renderer& m_renderer;
|
||||
size_t m_starting_stack_depth;
|
||||
};
|
||||
ScopedState scoped_state { *this };
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user