From e7c69cb5d258321abef9cfb22056fcb8cae402fa Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 31 Jul 2026 15:21:59 -0500 Subject: [PATCH] Protect PVUnion selector in deserialize --- src/factory/PVUnion.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/factory/PVUnion.cpp b/src/factory/PVUnion.cpp index 8d917d4..787a5ba 100644 --- a/src/factory/PVUnion.cpp +++ b/src/factory/PVUnion.cpp @@ -161,21 +161,26 @@ void PVUnion::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol) } else { - int32 previousSelector = selector; - selector = static_cast(SerializeHelper::readSize(pbuffer, pcontrol)); - if (selector != UNDEFINED_INDEX) + int32 index = static_cast(SerializeHelper::readSize(pbuffer, pcontrol)); + if (index == UNDEFINED_INDEX) { - if (selector != previousSelector) + selector = index; + value.reset(); + } + else if (index < 0 || size_t(index) >= unionPtr->getFields().size()) + throw std::runtime_error("union index out of bounds"); + else + { + if (selector != index) { - FieldConstPtr field = unionPtr->getField(selector); + selector = index; + FieldConstPtr field = unionPtr->getField(index); // try to reuse existing field instance if (!value.get() || *value->getField() != *field) value = pvDataCreate->createPVField(field); } value->deserialize(pbuffer, pcontrol); } - else - value.reset(); } }