From dd7427f51a939a6905ff3776e02103c24c220550 Mon Sep 17 00:00:00 2001 From: Mike Solar Date: Fri, 17 Jul 2026 13:07:43 +0800 Subject: [PATCH] fix: bugs surfaced by new gtest coverage - html.cpp: rgba() colors parsed with setRedF/GreenF/BlueF (0-1) while the writer emits 0-255 integers, so semi-transparent text colors lost their RGB on round-trip; parse with integer setters instead - CLIProgressDialog: percentage padding compared normalized progress (0.0-1.0) against 10/100, so padding was always fully applied; compute the percentage first - TimelineUndoPointer BlockTrimCommand: remove_block_from_graph_ was never initialized (UB on redo) - TimelineUndoGeneral TransitionRemoveCommand: track_ was never initialized; GetRelevantProject() could dereference it before redo() - ProjectLoadTask::Run(): failure path deleted project_ without resetting it, leaving GetLoadedProject() dangling --- app/cli/cliprogress/cliprogressdialog.cpp | 11 ++++++++--- app/common/html.cpp | 6 +++--- app/task/project/load/load.cpp | 1 + app/timeline/timelineundogeneral.h | 2 ++ app/timeline/timelineundopointer.h | 1 + 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/app/cli/cliprogress/cliprogressdialog.cpp b/app/cli/cliprogress/cliprogressdialog.cpp index 694c605f8..8d6859a01 100644 --- a/app/cli/cliprogress/cliprogressdialog.cpp +++ b/app/cli/cliprogress/cliprogressdialog.cpp @@ -86,15 +86,20 @@ void CLIProgressDialog::Update() std::cout << "] "; - if (progress_ < 100) { + // Pad the percentage so single/double/triple digit values all occupy the + // same width. Note progress_ is normalized (0.0-1.0), so the percentage + // must be computed before comparing against 10/100. + const int percent = qRound(progress_ * 100.0); + + if (percent < 100) { std::cout << " "; } - if (progress_ < 10) { + if (percent < 10) { std::cout << " "; } - std::cout << qRound(progress_ * 100.0) << "% " << std::endl << std::flush; + std::cout << percent << "% " << std::endl << std::flush; } void CLIProgressDialog::SetProgress(double p) diff --git a/app/common/html.cpp b/app/common/html.cpp index d4b754304..7ddae2070 100644 --- a/app/common/html.cpp +++ b/app/common/html.cpp @@ -356,9 +356,9 @@ QTextCharFormat Html::ReadCharFormat(const QXmlStreamAttributes &attributes) QStringList rgba = vals_only.split(','); if (rgba.size() == 4) { QColor c; - c.setRedF(rgba.at(0).toDouble()); - c.setGreenF(rgba.at(1).toDouble()); - c.setBlueF(rgba.at(2).toDouble()); + c.setRed(rgba.at(0).toInt()); // Writer emits 0-255 RGB (CSS rgba() convention) + c.setGreen(rgba.at(1).toInt()); + c.setBlue(rgba.at(2).toInt()); c.setAlphaF(rgba.at(3).toDouble()); fmt.setForeground(c); } diff --git a/app/task/project/load/load.cpp b/app/task/project/load/load.cpp index 9bda7edad..ddec65094 100644 --- a/app/task/project/load/load.cpp +++ b/app/task/project/load/load.cpp @@ -82,6 +82,7 @@ bool ProjectLoadTask::Run() return true; } else { delete project_; + project_ = nullptr; return false; } } diff --git a/app/timeline/timelineundogeneral.h b/app/timeline/timelineundogeneral.h index 7196aed8f..c6fa73714 100644 --- a/app/timeline/timelineundogeneral.h +++ b/app/timeline/timelineundogeneral.h @@ -25,6 +25,7 @@ #include "config/config.h" #include "node/block/clip/clip.h" #include "node/block/gap/gap.h" +#include "node/block/transition/transition.h" #include "node/output/track/track.h" #include "node/output/track/tracklist.h" #include "node/output/viewer/viewer.h" @@ -201,6 +202,7 @@ class TransitionRemoveCommand : public UndoCommand { public: TransitionRemoveCommand(TransitionBlock *block, bool remove_from_graph) : block_(block) + , track_(block->track()) , remove_from_graph_(remove_from_graph) , remove_command_(nullptr) { diff --git a/app/timeline/timelineundopointer.h b/app/timeline/timelineundopointer.h index d2057d609..9dbd78183 100644 --- a/app/timeline/timelineundopointer.h +++ b/app/timeline/timelineundopointer.h @@ -52,6 +52,7 @@ public: , mode_(mode) , deleted_adjacent_command_(nullptr) , trim_is_a_roll_edit_(false) + , remove_block_from_graph_(true) { }