Timeline: safeguard agains injecting a poisonous metric factor
This commit is contained in:
parent
90aba4df09
commit
b898f1514b
3 changed files with 157 additions and 15 deletions
|
|
@ -171,7 +171,7 @@ namespace model {
|
|||
|
||||
/** Maximum quantiser to be handled in fractional arithmetics without hazard.
|
||||
* @remark due to the common divisor normalisation, and the typical time computations,
|
||||
* DENOMINATOR * Time::Scale has to stay below INT_MAX, with some safety margin
|
||||
* DENOMINATOR * Time::Scale has to stay below INT_MAX, with some safety margin
|
||||
*/
|
||||
const int64_t LIM_HAZARD{int64_t{1} << 40 };
|
||||
|
||||
|
|
@ -527,9 +527,9 @@ namespace model {
|
|||
REQUIRE (pxWidth > 0);
|
||||
REQUIRE (afterWin_> startWin_);
|
||||
FSecs dur{afterWin_-startWin_};
|
||||
Rat adjMetric = Rat(pxWidth) / dur;
|
||||
Rat adjMetric = detox (Rat(pxWidth) / dur);
|
||||
ENSURE (pxWidth == rational_cast<uint> (adjMetric*dur));
|
||||
return detox (adjMetric);
|
||||
return adjMetric;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -541,7 +541,8 @@ namespace model {
|
|||
uint pxWidth = rational_cast<uint> (px_per_sec_*dur);
|
||||
dur = Rat(pxWidth) / detox (changedMetric);
|
||||
dur = min (dur, MAX_TIMESPAN);
|
||||
dur = max (dur, MICRO_TICK); // prevent window going void
|
||||
dur = max (dur, MICRO_TICK); // prevent window going void
|
||||
dur = detox (dur); // prevent integer wrap in time conversion
|
||||
TimeVar timeDur{dur};
|
||||
// prefer bias towards increased window instead of increased metric
|
||||
if (not isMicroGridAligned (dur))
|
||||
|
|
@ -673,7 +674,7 @@ namespace model {
|
|||
void
|
||||
mutateScale (Rat changedMetric)
|
||||
{
|
||||
changedMetric = min (changedMetric, ZOOM_MAX_RESOLUTION);
|
||||
changedMetric = min (detox(changedMetric), ZOOM_MAX_RESOLUTION);
|
||||
if (changedMetric == px_per_sec_) return;
|
||||
|
||||
uint px{pxWidth()};
|
||||
|
|
@ -687,7 +688,7 @@ namespace model {
|
|||
px_per_sec_ = conformMetricToWindow(px);
|
||||
}
|
||||
else
|
||||
mutateDuration (dur);
|
||||
mutateDuration (dur, px);
|
||||
ensureInvariants (px);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,10 @@ namespace test {
|
|||
safeguard_zero_init();
|
||||
safeguard_reversed_intervals();
|
||||
safeguard_toxic_zoomFactor();
|
||||
safeguard_poisonousMetric();
|
||||
safeguard_extremeZoomOut();
|
||||
safeguard_extremeTimePos();
|
||||
safeguard_extremeOffset();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -546,6 +550,7 @@ namespace test {
|
|||
{
|
||||
Rat poison{_raw(Time::MAX)-101010101010101010, _raw(Time::MAX)+23};
|
||||
CHECK (poison == 206435633551724850_r/307445734561825883);
|
||||
CHECK (2_r/3 < poison and poison < 1); // looks innocuous...
|
||||
CHECK (poison + Time::SCALE < 0); // simple calculations fail due to numeric overflow
|
||||
CHECK (Time(FSecs(poison)) < Time::ZERO); // conversion to µ-ticks also leads to overflow
|
||||
CHECK (-6 == _raw(Time(FSecs(poison))));
|
||||
|
|
@ -566,14 +571,68 @@ namespace test {
|
|||
CHECK (0.671453834f == rational_cast<float> (poison)); // but yields approximately the same effective value
|
||||
CHECK (0.671453834f == rational_cast<float> (detoxed));
|
||||
|
||||
CHECK (detoxed+Time::SCALE == 1172813190450446837_r/1172812402961); // result: we can calculate without failure
|
||||
CHECK (detoxed+Time::SCALE == 1172813190450446837_r/1172812402961); // result: usual calculations without failure
|
||||
CHECK (Time(FSecs(detoxed)) > Time::ZERO); // can convert re-quantised number to µ-ticks
|
||||
CHECK (671453 == _raw(Time(FSecs(detoxed))));
|
||||
// and resulting µ-ticks will be effectively the same
|
||||
CHECK (1906 == _raw(TimeValue(1280 / rational_cast<long double>(poison))));
|
||||
CHECK (1906 == _raw(TimeValue(1280 / rational_cast<long double>(detoxed))));
|
||||
}
|
||||
|
||||
|
||||
/** @test verify ZoomWindow code can handle "poisonous" Zoom-Factor parameters
|
||||
*/
|
||||
void
|
||||
safeguard_poisonousMetric()
|
||||
{
|
||||
|
||||
ZoomWindow win{};
|
||||
CHECK (win.visible() == win.overallSpan()); // by default window spans complete canvas
|
||||
CHECK (win.visible().duration() == _t(23)); // ...and has just some handsome extension
|
||||
CHECK (win.px_per_sec() == 25);
|
||||
CHECK (win.pxWidth() == 575);
|
||||
|
||||
Rat poison{_raw(Time::MAX)-101010101010101010, _raw(Time::MAX)+23};
|
||||
CHECK (0 < poison and poison < 1);
|
||||
win.setMetric (poison); // inject an evil new value for the metric
|
||||
CHECK (win.visible() == win.overallSpan()); // however, nothing happens
|
||||
CHECK (win.visible().duration() == _t(23)); // since the window is confined to overall canvas size
|
||||
CHECK (win.visible() == TimeSpan(_t(0), _t(23))); // Note: this calculation is fail-safe
|
||||
CHECK (win.px_per_sec() == 25);
|
||||
CHECK (win.pxWidth() == 575);
|
||||
|
||||
win.setOverallDuration(Duration(Time::MAX)); // second test: expand canvas to allow for actual adjustment
|
||||
CHECK (win.overallSpan().duration() == TimeValue{307445734561825860}); // now canvas has ample size (half the possible maximum size)
|
||||
CHECK (win.overallSpan().duration() == Time::MAX);
|
||||
CHECK (win.visible().duration() == _t(23)); // while the visible part remains unaltered
|
||||
|
||||
win.setMetric (poison); // Now attempt again to poison the zoom calculations...
|
||||
CHECK (win.overallSpan().duration() == Time::MAX); // overall canvas unchanged
|
||||
CHECK (win.visible().duration() == TimeValue{856350691}); // visible window expanded (a zoom-out, as required)
|
||||
CHECK (win.px_per_sec() == Rat{win.pxWidth()} / _FSecs(win.visible().duration()));
|
||||
float approxPoison = rational_cast<float> (poison); // the provided (poisonous) metric factor...
|
||||
CHECK (approxPoison == 0.671453834f); // ...is approximately the same...
|
||||
float approxNewMetric = rational_cast<float> (win.px_per_sec()); // ...as the actual new metric factor we got
|
||||
CHECK (approxNewMetric == 0.671453893f);
|
||||
CHECK (win.px_per_sec() != poison); // but it is not exactly the same
|
||||
CHECK (win.px_per_sec() < poison); // rather, it is biased towards slightly smaller values
|
||||
|
||||
Rat poisonousDuration = win.pxWidth() / poison; // Now, to demonstrate this "poison" was actually dangerous
|
||||
CHECK (poisonousDuration == 7071251894921995309_r/8257425342068994); // ...when we attempt to calculate the new duration directly....
|
||||
CHECK (Time(poisonousDuration) < Time::ZERO); // ...then a conversion to TimeValue will cause integer wrap
|
||||
CHECK(856.350708f == rational_cast<float> (poisonousDuration)); // yet numerically the duration actually established is almost the same
|
||||
CHECK(856.350708f == rational_cast<float> (_FSecs(win.visible().duration())));
|
||||
CHECK (win.px_per_sec() == 575000000_r/856350691); // the new metric however is comprised of sanitised fractional numbers
|
||||
CHECK (win.pxWidth() == 575); // and the existing pixel width was not changed
|
||||
}
|
||||
|
||||
|
||||
/** @test verify ZoomWindow code can handle extreme zoom-out
|
||||
* to reveal a timeline of epic dimensions....
|
||||
*/
|
||||
void
|
||||
safeguard_extremeZoomOut()
|
||||
{
|
||||
// SHOW_EXPR(win.overallSpan());
|
||||
// SHOW_EXPR(_raw(win.visible().duration()));
|
||||
// SHOW_EXPR(win.px_per_sec());
|
||||
|
|
@ -582,6 +641,22 @@ namespace test {
|
|||
// CHECK (win.px_per_sec() == 25);
|
||||
// CHECK (win.pxWidth() == 575);
|
||||
}
|
||||
|
||||
|
||||
/** @test verify ZoomWindow code can navigate extremal time positions.
|
||||
*/
|
||||
void
|
||||
safeguard_extremeTimePos()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/** @test verify ZoomWindow code is protected against excess scrolling.
|
||||
*/
|
||||
void
|
||||
safeguard_extremeOffset()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39653,14 +39653,23 @@
|
|||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1668703282413" HGAP="-88" ID="ID_1113812536" MODIFIED="1668703442612" TEXT="Input (changedMetric) muß entgiftet werden" VSHIFT="23">
|
||||
<edge COLOR="#f74141" STYLE="linear"/>
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node COLOR="#338800" CREATED="1669473799874" ID="ID_1081409038" MODIFIED="1669473855697" TEXT="detox">
|
||||
<edge COLOR="#5e51c9"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668703200176" ID="ID_1915595988" MODIFIED="1668703230862" TEXT="conformMetricToWindow()">
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668703200176" ID="ID_1915595988" MODIFIED="1669479310199" TEXT="conformMetricToWindow()">
|
||||
<linktarget COLOR="#65253d" DESTINATION="ID_1915595988" ENDARROW="Default" ENDINCLINATION="9;-40;" ID="Arrow_ID_382076752" SOURCE="ID_1175951405" STARTARROW="None" STARTINCLINATION="-11;29;"/>
|
||||
<linktarget COLOR="#6a6a92" DESTINATION="ID_1915595988" ENDARROW="Default" ENDINCLINATION="37;170;" ID="Arrow_ID_1959668732" SOURCE="ID_4317582" STARTARROW="None" STARTINCLINATION="-243;-9;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1668703282413" ID="ID_1976673029" MODIFIED="1668703442613" TEXT="Output muß entgiftet werden">
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1668703282413" ID="ID_1976673029" MODIFIED="1669473783896" TEXT="Output muß entgiftet werden">
|
||||
<edge COLOR="#f74141" STYLE="linear"/>
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node COLOR="#338800" CREATED="1669473816376" HGAP="129" ID="ID_1549431699" MODIFIED="1669473872429" TEXT="detox" VSHIFT="4">
|
||||
<edge COLOR="#5e51c9"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1668703253721" ID="ID_562775888" MODIFIED="1668703454748" TEXT="output ⟶ finaler Metrik-Faktor">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
|
|
@ -39694,6 +39703,7 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668263629246" ID="ID_1257614207" MODIFIED="1668265511791" TEXT="mutateScale (Rat changedMetric)">
|
||||
<arrowlink COLOR="#e62f5c" DESTINATION="ID_651838862" ENDARROW="Default" ENDINCLINATION="115;-4;" ID="Arrow_ID_1930230162" STARTARROW="None" STARTINCLINATION="-189;14;"/>
|
||||
<arrowlink COLOR="#6568c0" DESTINATION="ID_909162669" ENDARROW="Default" ENDINCLINATION="-5;-8;" ID="Arrow_ID_1791222915" STARTARROW="None" STARTINCLINATION="-21;18;"/>
|
||||
<linktarget COLOR="#aa6877" DESTINATION="ID_1257614207" ENDARROW="Default" ENDINCLINATION="271;-11;" ID="Arrow_ID_292335664" SOURCE="ID_1173749705" STARTARROW="None" STARTINCLINATION="314;29;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668265021139" HGAP="52" ID="ID_1943948610" MODIFIED="1668265531172" TEXT="prüfen: sehr kleine Metrik" VSHIFT="-2">
|
||||
|
|
@ -39706,13 +39716,44 @@
|
|||
<icon BUILTIN="clanbomber"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668784031268" ID="ID_1513611206" MODIFIED="1668784041478" TEXT="die bestehende Duration könnte sehr groß sein">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1668784196906" ID="ID_1074723893" MODIFIED="1668784217911" TEXT="mit dem Nenner des changeFactor bereis Überlauf möglich"/>
|
||||
<node CREATED="1668784229969" ID="ID_1956828761" MODIFIED="1668784257285" TEXT="neu errechnete Duration könnte toxisch sein"/>
|
||||
<node CREATED="1668784295985" ID="ID_1396219141" MODIFIED="1668784307787" TEXT="Rechnung in mutateDuration() könnte entgleisen"/>
|
||||
<node CREATED="1668784318075" ID="ID_901869945" MODIFIED="1668784338191" TEXT="wird alles zwar in conformWindowToMetric(changed) aufgefangen..."/>
|
||||
<node CREATED="1668784339323" ID="ID_1591426559" MODIFIED="1668784345302" TEXT="..is aber trotzdem falsch"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1668263638141" ID="ID_909162669" MODIFIED="1668270369633" TEXT="mutateDuration (FSecs duration, uint px =0)">
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1668263638141" ID="ID_909162669" MODIFIED="1669477898780" TEXT="mutateDuration (FSecs duration, uint px =0)">
|
||||
<arrowlink COLOR="#965e8b" DESTINATION="ID_1175951405" ENDARROW="Default" ENDINCLINATION="253;-8;" ID="Arrow_ID_354964355" STARTARROW="None" STARTINCLINATION="302;-12;"/>
|
||||
<linktarget COLOR="#6568c0" DESTINATION="ID_909162669" ENDARROW="Default" ENDINCLINATION="-5;-8;" ID="Arrow_ID_1791222915" SOURCE="ID_1257614207" STARTARROW="None" STARTINCLINATION="-21;18;"/>
|
||||
<node CREATED="1668270374842" HGAP="21" ID="ID_1976979366" MODIFIED="1668270395644" TEXT="delegiert an conformWindowToMetric(Rat)" VSHIFT="9">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1669479155534" ID="ID_620129730" MODIFIED="1669479162094" TEXT="adaptWindowToPixels(px)">
|
||||
<node COLOR="#435e98" CREATED="1669479175476" ID="ID_590715378" MODIFIED="1669479353924" TEXT="Arithmetik erscheint ungefährlich">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1669479204552" ID="ID_29297928" MODIFIED="1669479365083" TEXT="unter der Annahme daß bestehende Metrik sauber ist">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1669479223678" ID="ID_4317582" MODIFIED="1669479361432" TEXT="außerdem: Ausgang durch conformMetricToWindow">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...und das betrachte ich als gutmütig und hinreichend abgesichert...
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#6a6a92" DESTINATION="ID_1915595988" ENDARROW="Default" ENDINCLINATION="37;170;" ID="Arrow_ID_1959668732" STARTARROW="None" STARTINCLINATION="-243;-9;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668263652677" ID="ID_759637608" MODIFIED="1668265848826" TEXT="anchorWindowAtPosition (FSecs canvasOffset)">
|
||||
<linktarget COLOR="#895f96" DESTINATION="ID_759637608" ENDARROW="Default" ENDINCLINATION="124;-7;" ID="Arrow_ID_728050450" SOURCE="ID_1494604965" STARTARROW="None" STARTINCLINATION="168;14;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
@ -39819,11 +39860,36 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1668554900067" ID="ID_1302892550" MODIFIED="1668554974542" TEXT="kritische Wirkpfade">
|
||||
<node CREATED="1668555028046" ID="ID_660534369" MODIFIED="1668555056498" TEXT="sehr kleine Metrix (≙ exterm zoom-out)"/>
|
||||
<node CREATED="1668555072594" ID="ID_742229180" MODIFIED="1668555089126" TEXT="Ansteuern exterm großer Zeit-Positionen"/>
|
||||
<node CREATED="1668555157385" ID="ID_1157546672" MODIFIED="1668555164702" TEXT="Time-wrap nach extremem Offset"/>
|
||||
<node CREATED="1668555183502" ID="ID_1287974241" MODIFIED="1668555191961" TEXT="Einspeisen giftiger Metrik"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1668554900067" HGAP="80" ID="ID_1302892550" MODIFIED="1669473989333" TEXT="kritische Wirkpfade abtesten" VSHIFT="9">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668555028046" ID="ID_660534369" MODIFIED="1669473993482" TEXT="sehr kleine Metrix (≙ exterm zoom-out)">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1669475559599" ID="ID_460741178" MODIFIED="1669475567282" TEXT="setVisiblePos mit giftigem Faktor"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668555072594" ID="ID_742229180" MODIFIED="1669473993488" TEXT="Ansteuern exterm großer Zeit-Positionen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1669475536331" ID="ID_486161883" MODIFIED="1669475548565" TEXT="setVisiblePos mit extremer Time"/>
|
||||
<node CREATED="1669475549345" ID="ID_234786683" MODIFIED="1669475556499" TEXT="setVisiblePos mit extremem Faktor"/>
|
||||
<node CREATED="1669479474484" ID="ID_1657847338" MODIFIED="1669479489366" TEXT="alle Mutatoren, die conformWindowToMetric() verwenden"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668555157385" ID="ID_1157546672" MODIFIED="1669473993486" TEXT="Time-wrap nach extremem Offset">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1668555183502" ID="ID_1287974241" MODIFIED="1669488176332" TEXT="Einspeisen giftiger Metrik">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1669478124298" ID="ID_1987069808" MODIFIED="1669488168358" TEXT="Fall-1 : kappen auf Canvas-Grenzen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1669478154709" ID="ID_499422673" MODIFIED="1669488173372" TEXT="Fall-2 : hinreichend großer Canvas">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1669479930775" ID="ID_196873456" MODIFIED="1669480034941" TEXT="Fall-3 : setVisiblePos mit giftigem faktor">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1669480019215" ID="ID_930072077" MODIFIED="1669480034942" TEXT="Fall-4 : setVisiblePos mit extrem entfernter Position">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1668180030777" ID="ID_1319796356" MODIFIED="1668180136077" TEXT="1 µ-Tick">
|
||||
|
|
|
|||
Loading…
Reference in a new issue