From 38d937fa587ecd29b58682562495880c784274c4 Mon Sep 17 00:00:00 2001 From: David Dormagen Date: Sat, 13 Jan 2018 15:02:19 +0100 Subject: [PATCH] GetProperties: fixed returning of duplicated property names & too high repair costs var a = {B=1}; var b = new a {B=1}; would include "B" twice in the list of properties. This lead to an actual issue when calculating component value for repairing buildings --- src/script/C4PropList.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/script/C4PropList.cpp b/src/script/C4PropList.cpp index 4603827d9..0a34f57f4 100644 --- a/src/script/C4PropList.cpp +++ b/src/script/C4PropList.cpp @@ -914,8 +914,9 @@ C4PropList *C4PropList::GetPropertyPropList(C4PropertyName n) const C4ValueArray * C4PropList::GetProperties() const { C4ValueArray * a; - int i; - if (GetPrototype()) + int i = 0; + const bool hasInheritedProperties = GetPrototype() != nullptr; + if (hasInheritedProperties) { a = GetPrototype()->GetProperties(); i = a->GetSize(); @@ -929,11 +930,29 @@ C4ValueArray * C4PropList::GetProperties() const const C4Property * p = Properties.First(); while (p) { - assert(p->Key != nullptr && "Proplist key is nullpointer"); - (*a)[i++] = C4VString(p->Key); - assert(((*a)[i - 1].GetType() == C4V_String) && "Proplist key is non-string"); + C4String *newPropertyName = p->Key; + assert(newPropertyName != nullptr && "Proplist key is nullpointer"); + // Do we need to check for duplicate property names? + bool skipProperty = false; + if (hasInheritedProperties) + { + for (size_t j = 0; j < i; ++j) + { + if ((*a)[j].getStr() != newPropertyName) continue; + skipProperty = true; + break; + } + } + if (!skipProperty) + { + (*a)[i++] = C4VString(newPropertyName); + assert(((*a)[i - 1].GetType() == C4V_String) && "Proplist key is non-string"); + } p = Properties.Next(p); } + // We might have added less properties than initially intended. + if (hasInheritedProperties) + a->SetSize(i); return a; }