fix: memory-safety and playback regressions found via ASan

- nodeparamview: add visited set to get_distance_between_nodes, fixing
  unbounded recursion (stack overflow) when the node graph has a cycle
- viewerdisplay: give texture_ a consistent owner via assign_texture();
  borrowed queue textures are now retained, created ones freed, fixing
  a dangling pointer that corrupted the heap and crashed in the GL driver
- playbackcache: resignal_requests() iterates a copy, handlers may
  clear_request_range() while iterating (ASan container-overflow)
- preview C API: preview request ticket lambdas captured the request
  state raw; after oakengine_preview_request_free the ticket outlived
  the request and the finished callback wrote into freed memory
  (heap-use-after-free). The finished flag is now a shared_ptr captured
  weakly by the callbacks
- playback: oak_playback_frame regains a timestamp (num/den) filled
  from olive::Frame; the viewer queue append no longer uses Rational()
  for every frame, which made append_timewise drop all but the first
  frame and froze the picture during playback
- mainwindow: open_node_in_viewer refuses sequence nodes; sequences
  already have the Sequence Viewer, and saved layouts could otherwise
  resurrect a redundant floating Viewer bound to the sequence
This commit is contained in:
2026-08-01 19:14:31 +08:00
parent 66d761b4b7
commit a4dfc62f0f
8 changed files with 120 additions and 30 deletions
+8
View File
@@ -318,6 +318,14 @@ void MainWindow::open_folder(OakEngineNode *i, bool floating)
void MainWindow::open_node_in_viewer(OakEngineNode *node)
{
// Sequences already have the dedicated Sequence Viewer. Opening a
// floating Viewer on a Sequence just duplicates it and looks like the
// two viewers' controls are swapped. This also filters out stale
// <viewer> entries pointing at sequences in saved project layouts.
if (!node || oak::Node(node).is_sequence()) {
return;
}
ViewerPanel *existing = nullptr;
for (auto it = viewer_panels_.cbegin(); it != viewer_panels_.cend(); it++) {