mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-01 15:24:13 +02:00
Reject non-finite values when loading a wire
A wire read "nan" or "inf" for its position, its segment lengths and its label position without checking them: QString::toDouble() accepts all three as numbers. PR #792 and #996 closed this gap for elements, terminals and texts; wires were left out. The worst case is a segment length: a single "nan" passes the check that the segments add up to the distance between the two terminals, because every comparison with NaN is false. The whole path then turns to NaN: on 2612_ats_singlephase.qet one bad length out of six was saved back as six "nan" vertical segments, and the next save dropped them and routed the wire automatically, so each save changed the file. Now: - a non-finite segment length is skipped like any unreadable one, so the path fails the coherence check and the wire is routed automatically at load, as already happens for "inf"; - a non-finite wire position is read as 0; - a non-finite label position or rotation is ignored, as if the label had not been moved or rotated. Found by the mutation sweep (python3 -m simulator sweep, mutators inject_nan_coordinate / inject_inf_coordinate). The 24 example projects resave byte-identical with and without this change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1099,8 +1099,10 @@ bool Conductor::fromXml(QDomElement &dom_element)
|
||||
m_uuid = QUuid::createUuid();
|
||||
}
|
||||
|
||||
setPos(dom_element.attribute("x", nullptr).toDouble(),
|
||||
dom_element.attribute("y", nullptr).toDouble());
|
||||
//"nan" and "inf" parse as numbers; a non-finite position is kept at 0
|
||||
const qreal x = dom_element.attribute("x", nullptr).toDouble();
|
||||
const qreal y = dom_element.attribute("y", nullptr).toDouble();
|
||||
setPos(qIsFinite(x) ? x : 0, qIsFinite(y) ? y : 0);
|
||||
|
||||
bool retval = pathFromXml(dom_element);
|
||||
|
||||
@@ -1229,7 +1231,10 @@ bool Conductor::pathFromXml(const QDomElement &e) {
|
||||
// cette longueur doit etre un reel
|
||||
bool ok;
|
||||
qreal segment_length = current_segment.attribute("length").toDouble(&ok);
|
||||
if (!ok) continue;
|
||||
// toDouble() accepts "nan" and "inf". A NaN length would also pass
|
||||
// the coherence check below (every comparison with NaN is false)
|
||||
// and turn the whole path into NaN.
|
||||
if (!ok || !qIsFinite(segment_length)) continue;
|
||||
|
||||
if (current_segment.attribute("orientation") == "horizontal") {
|
||||
segments_x << segment_length;
|
||||
|
||||
@@ -69,13 +69,17 @@ Conductor *ConductorTextItem::parentConductor() const
|
||||
@param e
|
||||
*/
|
||||
void ConductorTextItem::fromXml(const QDomElement &e) {
|
||||
if (e.hasAttribute("userx")) {
|
||||
setPos(e.attribute("userx").toDouble(),
|
||||
e.attribute("usery").toDouble());
|
||||
//A non-finite ("nan", "inf") position or rotation is ignored,
|
||||
//as if the text had never been moved or rotated
|
||||
const qreal x = e.attribute("userx").toDouble();
|
||||
const qreal y = e.attribute("usery").toDouble();
|
||||
if (e.hasAttribute("userx") && qIsFinite(x) && qIsFinite(y)) {
|
||||
setPos(x, y);
|
||||
moved_by_user_ = true;
|
||||
}
|
||||
if (e.hasAttribute("rotation")) {
|
||||
setRotation(e.attribute("rotation").toDouble());
|
||||
const qreal rotation = e.attribute("rotation").toDouble();
|
||||
if (e.hasAttribute("rotation") && qIsFinite(rotation)) {
|
||||
setRotation(rotation);
|
||||
rotate_by_user_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user