summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin T. H. Sandsmark <martin.sandsmark@kde.org>2016-11-05 16:12:01 (GMT)
committerMartin T. H. Sandsmark <martin.sandsmark@kde.org>2016-11-09 12:24:04 (GMT)
commit3ff022527e53cd5daa6fe8589de81b5988457945 (patch)
treefe2e2c5079fcd066f7054a711afbc6636c3b45e0
parenta5ca90345378262825b2450ff89db7addcf89309 (diff)
Fix randomization in color scheme
Use the new std::random APIs in c++11 for generating random numbers, which is much safer and doesn't abuse qsrand(). This also means we don't need to copy in the QUuid::createUuid() code anymore, which generated a warning in ubsan. REVIEW: 129342
-rw-r--r--src/ColorScheme.cpp50
-rw-r--r--src/Session.cpp37
2 files changed, 37 insertions, 50 deletions
diff --git a/src/ColorScheme.cpp b/src/ColorScheme.cpp
index a85072b..af17077 100644
--- a/src/ColorScheme.cpp
+++ b/src/ColorScheme.cpp
@@ -30,6 +30,9 @@
#include <KLocalizedString>
#include <KConfigGroup>
+// STL
+#include <random>
+
namespace
{
const int FGCOLOR_INDEX = 0;
@@ -226,29 +229,46 @@ ColorEntry ColorScheme::colorEntry(int index , uint randomSeed) const
{
Q_ASSERT(index >= 0 && index < TABLE_COLORS);
- if (randomSeed != 0)
- qsrand(randomSeed);
-
ColorEntry entry = colorTable()[index];
- if (randomSeed != 0 &&
- _randomTable != 0 &&
- !_randomTable[index].isNull()) {
- const RandomizationRange& range = _randomTable[index];
+ if (randomSeed == 0 || _randomTable == 0 || _randomTable[index].isNull()) {
+ return entry;
+ }
+
+
+ const RandomizationRange& range = _randomTable[index];
- int hueDifference = range.hue ? (qrand() % range.hue) - range.hue / 2 : 0;
- int saturationDifference = range.saturation ? (qrand() % range.saturation) - range.saturation / 2 : 0;
- int valueDifference = range.value ? (qrand() % range.value) - range.value / 2 : 0;
+ // 32-bit Mersenne Twister
+ // Can't use default_random_engine, because in GCC this maps to
+ // minstd_rand0 which always gives us 0 on the first number.
+ std::mt19937 randomEngine(randomSeed);
- QColor& color = entry.color;
+ int hueDifference = 0;
+ if (range.hue) {
+ std::uniform_int_distribution<int> dist(0, range.hue);
+ hueDifference = dist(randomEngine);
+ }
- int newHue = qAbs((color.hue() + hueDifference) % MAX_HUE);
- int newValue = qMin(qAbs(color.value() + valueDifference) , 255);
- int newSaturation = qMin(qAbs(color.saturation() + saturationDifference) , 255);
+ int saturationDifference = 0;
+ if (range.saturation) {
+ std::uniform_int_distribution<int> dist(0, range.saturation);
+ saturationDifference = dist(randomEngine) - range.saturation / 2;
+ }
- color.setHsv(newHue, newSaturation, newValue);
+ int valueDifference = 0;
+ if (range.value) {
+ std::uniform_int_distribution<int> dist(0, range.value);
+ valueDifference = dist(randomEngine) - range.value / 2;
}
+ QColor& color = entry.color;
+
+ int newHue = qAbs((color.hue() + hueDifference) % MAX_HUE);
+ int newValue = qMin(qAbs(color.value() + valueDifference) , 255);
+ int newSaturation = qMin(qAbs(color.saturation() + saturationDifference) , 255);
+
+ color.setHsv(newHue, newSaturation, newValue);
+
return entry;
}
void ColorScheme::getColorTable(ColorEntry* table , uint randomSeed) const
diff --git a/src/Session.cpp b/src/Session.cpp
index 4ecec95..3269550 100644
--- a/src/Session.cpp
+++ b/src/Session.cpp
@@ -63,39 +63,6 @@ using namespace Konsole;
int Session::lastSessionId = 0;
static bool show_disallow_certain_dbus_methods_message = true;
-// HACK This is copied out of QUuid::createUuid with reseeding forced.
-// Required because color schemes repeatedly seed the RNG...
-// ...with a constant.
-QUuid createUuid()
-{
- static const int intbits = sizeof(int) * 8;
- static int randbits = 0;
- if (!randbits) {
- int max = RAND_MAX;
- do {
- ++randbits;
- } while ((max = max >> 1));
- }
-
- qsrand(uint(QDateTime::currentDateTimeUtc().toTime_t()));
- qrand(); // Skip first
-
- QUuid result;
- uint* data = &(result.data1);
- int chunks = 16 / sizeof(uint);
- while (chunks--) {
- uint randNumber = 0;
- for (int filled = 0; filled < intbits; filled += randbits)
- randNumber |= qrand() << filled;
- *(data + chunks) = randNumber;
- }
-
- result.data4[0] = (result.data4[0] & 0x3F) | 0x80; // UV_DCE
- result.data3 = (result.data3 & 0x0FFF) | 0x4000; // UV_Random
-
- return result;
-}
-
Session::Session(QObject* parent) :
QObject(parent)
, _shellProcess(0)
@@ -117,7 +84,7 @@ Session::Session(QObject* parent) :
, _zmodemProgress(0)
, _hasDarkBackground(false)
{
- _uniqueIdentifier = createUuid();
+ _uniqueIdentifier = QUuid::createUuid();
//prepare DBus communication
new SessionAdaptor(this);
@@ -426,7 +393,7 @@ void Session::run()
qWarning() << "No command line arguments specified.";
}
if (_uniqueIdentifier.isNull()) {
- _uniqueIdentifier = createUuid();
+ _uniqueIdentifier = QUuid::createUuid();
}
const int CHOICE_COUNT = 3;