Blob Blame History Raw
From 15db8cdb57161d57af8307bf85aeda02ea69ddde Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fl=C3=B6ssie?= <floessie.mail@gmail.com>
Date: Sun, 5 Apr 2020 11:26:47 +0200
Subject: [PATCH] Guard accesses to `Crop::crop_ratios` (#5701)

---
 rtgui/crop.cc | 125 +++++++++++++++++++++++++++++++++++---------------
 rtgui/crop.h  |  11 ++---
 2 files changed, 92 insertions(+), 44 deletions(-)

diff --git a/rtgui/crop.cc b/rtgui/crop.cc
index d9d496523..f092f07a5 100644
--- a/rtgui/crop.cc
+++ b/rtgui/crop.cc
@@ -16,6 +16,8 @@
  *  You should have received a copy of the GNU General Public License
  *  along with RawTherapee.  If not, see <https://www.gnu.org/licenses/>.
  */
+#include <vector>
+
 #include "crop.h"
 
 #include "options.h"
@@ -46,39 +48,82 @@ inline void get_custom_ratio(int w, int h, double &rw, double &rh)
 
 } // namespace
 
+class Crop::CropRatios final
+{
+public:
+    CropRatios() :
+        ratios{
+            {M("GENERAL_ASIMAGE"), 0.0},
+            {M("GENERAL_CURRENT"), -1.0},
+            {"3:2", 3.0 / 2.0},                 // L1.5,        P0.666...
+            {"4:3", 4.0 / 3.0},                 // L1.333...,   P0.75
+            {"16:9", 16.0 / 9.0},               // L1.777...,   P0.5625
+            {"16:10", 16.0 / 10.0},             // L1.6,        P0.625
+            {"1:1", 1.0 / 1.0},                 // L1,          P1
+            {"2:1", 2.0 / 1.0},                 // L2,          P0.5
+            {"3:1", 3.0 / 1.0},                 // L3,          P0.333...
+            {"4:1", 4.0 / 1.0},                 // L4,          P0.25
+            {"5:1", 5.0 / 1.0},                 // L5,          P0.2
+            {"6:1", 6.0 / 1.0},                 // L6,          P0.1666...
+            {"7:1", 7.0 / 1.0},                 // L7,          P0.142...
+            {"4:5", 4.0 / 5.0},                 // L1.25,       P0.8
+            {"5:7", 5.0 / 7.0},                 // L1.4,        P0.714...
+            {"6:7", 6.0 / 7.0},                 // L1.166...,   P0.857...
+            {"6:17", 6.0 / 17.0},               // L2.833...,   P0.352...
+            {"24:65 - XPAN", 24.0 / 65.0},      // L2.708...,   P0.369...
+            {"1.414 - DIN EN ISO 216", 1.414},  // L1.414,      P0.707...
+            {"3.5:5", 3.5 / 5.0},               // L1.428...,   P0.7
+            {"8.5:11 - US Letter", 8.5 / 11.0}, // L1.294...,   P0.772...
+            {"9.5:12", 9.5 / 12.0},             // L1.263...,   P0.791...
+            {"10:12", 10.0 / 12.0},             // L1.2,        P0.833...
+            {"11:14", 11.0 / 14.0},             // L1.272...,   P0.785...
+            {"11:17 - Tabloid", 11.0 / 17.0},   // L1.545...,   P0.647...
+            {"13:19", 13.0 / 19.0},             // L1.461...,   P0.684...
+            {"17:22", 17.0 / 22.0},             // L1.294...,   P0.772...
+            {"45:35 - ePassport", 45.0 / 35.0}, // L1.285,...   P0.777...
+            {"64:27", 64.0 / 27.0},             // L2.370...,   P0.421...
+        }
+    {
+    }
+
+    std::vector<Glib::ustring> getLabels() const
+    {
+        std::vector<Glib::ustring> res;
+
+        res.reserve(ratios.size());
+
+        for (const auto& ratio : ratios) {
+            res.push_back(ratio.label);
+        }
+
+        return res;
+    }
+
+    double getValue(std::size_t index) const
+    {
+        return
+            index < ratios.size()
+                ? ratios[index].value
+                : ratios[0].value;
+    }
+
+    void updateCurrentRatio(double value)
+    {
+        ratios[1].value = value;
+    }
+
+private:
+    struct CropRatio {
+        Glib::ustring label;
+        double value;
+    };
+
+    std::vector<CropRatio> ratios;
+};
+
 Crop::Crop():
     FoldableToolPanel(this, "crop", M("TP_CROP_LABEL"), false, true),
-    crop_ratios{
-        {M("GENERAL_ASIMAGE"), 0.0},
-        {M("GENERAL_CURRENT"), -1.0},
-        {"3:2", 3.0 / 2.0},                 // L1.5,        P0.666...
-        {"4:3", 4.0 / 3.0},                 // L1.333...,   P0.75
-        {"16:9", 16.0 / 9.0},               // L1.777...,   P0.5625
-        {"16:10", 16.0 / 10.0},             // L1.6,        P0.625
-        {"1:1", 1.0 / 1.0},                 // L1,          P1
-        {"2:1", 2.0 / 1.0},                 // L2,          P0.5
-        {"3:1", 3.0 / 1.0},                 // L3,          P0.333...
-        {"4:1", 4.0 / 1.0},                 // L4,          P0.25
-        {"5:1", 5.0 / 1.0},                 // L5,          P0.2
-        {"6:1", 6.0 / 1.0},                 // L6,          P0.1666...
-        {"7:1", 7.0 / 1.0},                 // L7,          P0.142...
-        {"4:5", 4.0 / 5.0},                 // L1.25,       P0.8
-        {"5:7", 5.0 / 7.0},                 // L1.4,        P0.714...
-        {"6:7", 6.0 / 7.0},                 // L1.166...,   P0.857...
-        {"6:17", 6.0 / 17.0},               // L2.833...,   P0.352...
-        {"24:65 - XPAN", 24.0 / 65.0},      // L2.708...,   P0.369...
-        {"1.414 - DIN EN ISO 216", 1.414},  // L1.414,      P0.707...
-        {"3.5:5", 3.5 / 5.0},               // L1.428...,   P0.7
-        {"8.5:11 - US Letter", 8.5 / 11.0}, // L1.294...,   P0.772...
-        {"9.5:12", 9.5 / 12.0},             // L1.263...,   P0.791...
-        {"10:12", 10.0 / 12.0},             // L1.2,        P0.833...
-        {"11:14", 11.0 / 14.0},             // L1.272...,   P0.785...
-        {"11:17 - Tabloid", 11.0 / 17.0},   // L1.545...,   P0.647...
-        {"13:19", 13.0 / 19.0},             // L1.461...,   P0.684...
-        {"17:22", 17.0 / 22.0},             // L1.294...,   P0.772...
-        {"45:35 - ePassport", 45.0 / 35.0}, // L1.285,...   P0.777...
-        {"64:27", 64.0 / 27.0},             // L2.370...,   P0.421...
-    },
+    crop_ratios(new CropRatios),
     opt(0),
     wDirty(true),
     hDirty(true),
@@ -229,8 +274,8 @@ Crop::Crop():
     // ppigrid END
 
     // Populate the combobox
-    for (const auto& crop_ratio : crop_ratios) {
-        ratio->append (crop_ratio.label);
+    for (const auto& label : crop_ratios->getLabels()) {
+        ratio->append (label);
     }
 
     ratio->set_active (0);
@@ -354,7 +399,10 @@ void Crop::read (const ProcParams* pp, const ParamsEdited* pedited)
         setDimensions (pp->crop.x + pp->crop.w, pp->crop.y + pp->crop.h);
     }
 
-    const bool flip_orientation = pp->crop.fixratio && crop_ratios[ratio->get_active_row_number()].value > 0 && crop_ratios[ratio->get_active_row_number()].value < 1.0;
+    const bool flip_orientation =
+        pp->crop.fixratio
+        && crop_ratios->getValue(ratio->get_active_row_number()) > 0
+        && crop_ratios->getValue(ratio->get_active_row_number()) < 1.0;
 
     if (pp->crop.orientation == "Landscape") {
         orientation->set_active (flip_orientation ? 1 : 0);
@@ -469,7 +517,10 @@ void Crop::write (ProcParams* pp, ParamsEdited* pedited)
     }
 
     // for historical reasons we store orientation different if ratio is written as 2:3 instead of 3:2, but in GUI 'landscape' is always long side horizontal regardless of the ratio is written short or long side first.
-    const bool flip_orientation = fixr->get_active() && crop_ratios[ratio->get_active_row_number()].value > 0 && crop_ratios[ratio->get_active_row_number()].value < 1.0;
+    const bool flip_orientation =
+        fixr->get_active()
+        && crop_ratios->getValue(ratio->get_active_row_number()) > 0
+        && crop_ratios->getValue(ratio->get_active_row_number()) < 1.0;
 
     if (orientation->get_active_row_number() == 0) {
         pp->crop.orientation = flip_orientation ? "Portrait" : "Landscape";
@@ -1501,7 +1552,7 @@ double Crop::getRatio () const
         return r;
     }
 
-    r = crop_ratios[ratio->get_active_row_number()].value;
+    r = crop_ratios->getValue(ratio->get_active_row_number());
     if (!r) {
         r = maxh <= maxw ? float(maxh)/float(maxw) : float(maxw)/float(maxh);
     }
@@ -1539,5 +1590,5 @@ void Crop::updateCurrentRatio()
     double rw, rh;
     get_custom_ratio(w->get_value(), h->get_value(), rw, rh);
     customRatioLabel->set_text(Glib::ustring::compose("%1:%2", rw, rh));
-    crop_ratios[1].value = double(w->get_value())/double(h->get_value());
+    crop_ratios->updateCurrentRatio(static_cast<double>(w->get_value()) / static_cast<double>(h->get_value()));
 }
diff --git a/rtgui/crop.h b/rtgui/crop.h
index b9221a803..c6636b917 100644
--- a/rtgui/crop.h
+++ b/rtgui/crop.h
@@ -18,7 +18,7 @@
  */
 #pragma once
 
-#include <vector>
+#include <memory>
 
 #include <gtkmm.h>
 
@@ -91,16 +91,13 @@ class Crop final :
     void rotateCrop         (int deg, bool hflip, bool vflip);
 
 private:
-    struct CropRatio {
-        Glib::ustring label;
-        double value;
-    };
-
-    std::vector<CropRatio> crop_ratios;
+    class CropRatios;
 
     void adjustCropToRatio();
     void updateCurrentRatio();
 
+    const std::unique_ptr<CropRatios> crop_ratios;
+
     Gtk::CheckButton* fixr;
     MyComboBoxText* ratio;
     MyComboBoxText* orientation;