configmgr/source/xcuparser.cxx | 49 +++++++++++++++++++++-------------------- configmgr/source/xcuparser.hxx | 2 + 2 files changed, 28 insertions(+), 23 deletions(-)
New commits: commit b116c19fc058d5c53f90965de299d000408c1391 Author: Stephan Bergmann <stephan.bergm...@allotropia.de> AuthorDate: Tue Dec 3 14:18:21 2024 +0100 Commit: Stephan Bergmann <stephan.bergm...@allotropia.de> CommitDate: Thu Dec 5 08:50:39 2024 +0100 configmgr: Better handling of finalized vs. non-finalized in the same layer When there are multiple competing configuration settings for the same configuration layer (e.g., in xcu files of two different extensions from the same extension layer), then the setting that is read last always won, even if any of the settings read earlier is marked as finalized. (The reason for originally doing it that way was that it kept the code logic somewhat simple.) However, esp. for a scenario of multiple extensions in one extension layer (bundled, shared, or user), it can be unexpected by a user that a non-finalized setting (that comes from the extension that happens to be read last) can win over a finalized one. Therefore, change the logic accordingly. Now, if any of the competing settings are finalized, the first finalized one that is read wins. Change-Id: I22aeade543a5b26d95d49cfcb561f974cd7a5081 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177737 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de> (cherry picked from commit 7f927322d9b030ceb3b04ae09ea5641e98916f62) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177840 Tested-by: Stephan Bergmann <stephan.bergm...@allotropia.de> diff --git a/configmgr/source/xcuparser.cxx b/configmgr/source/xcuparser.cxx index b54e7aa95f01..c85122354bfb 100644 --- a/configmgr/source/xcuparser.cxx +++ b/configmgr/source/xcuparser.cxx @@ -219,6 +219,10 @@ XcuParser::Operation XcuParser::parseOperation(xmlreader::Span const & text) { "invalid op " + text.convertFromUtf8()); } +bool XcuParser::isAlreadyFinalized(int finalizedLayer) const { + return finalizedLayer != Data::NO_LAYER && finalizedLayer <= valueParser_.getLayer(); +} + void XcuParser::handleComponentData(xmlreader::XmlReader & reader) { OStringBuffer buf(256); buf.append('.'); @@ -301,14 +305,13 @@ void XcuParser::handleComponentData(xmlreader::XmlReader & reader) { throw css::uno::RuntimeException( "invalid operation on root node in " + reader.getUrl()); } - int finalizedLayer = std::min( - finalized ? valueParser_.getLayer() : Data::NO_LAYER, - node->getFinalized()); - node->setFinalized(finalizedLayer); - if (finalizedLayer < valueParser_.getLayer()) { + if (isAlreadyFinalized(node->getFinalized())) { state_.push(State::Ignore(true)); return; } + if (finalized) { + node->setFinalized(valueParser_.getLayer()); + } state_.push(State::Modify(node)); } @@ -367,7 +370,7 @@ void XcuParser::handleItem(xmlreader::XmlReader & reader) { default: break; } - if (finalizedLayer < valueParser_.getLayer()) { + if (isAlreadyFinalized(finalizedLayer)) { state_.push(State::Ignore(true)); return; } @@ -660,14 +663,13 @@ void XcuParser::handlePlainGroupProp( state_.push(State::Ignore(true)); return; } - int finalizedLayer = std::min( - finalized ? valueParser_.getLayer() : Data::NO_LAYER, - property->getFinalized()); - property->setFinalized(finalizedLayer); - if (finalizedLayer < valueParser_.getLayer()) { + if (isAlreadyFinalized(property->getFinalized())) { state_.push(State::Ignore(true)); return; } + if (finalized) { + property->setFinalized(valueParser_.getLayer()); + } if (type != TYPE_ERROR && property->getStaticType() != TYPE_ANY && type != property->getStaticType()) { @@ -703,14 +705,13 @@ void XcuParser::handleLocalizedGroupProp( state_.push(State::Ignore(true)); return; } - int finalizedLayer = std::min( - finalized ? valueParser_.getLayer() : Data::NO_LAYER, - property->getFinalized()); - property->setFinalized(finalizedLayer); - if (finalizedLayer < valueParser_.getLayer()) { + if (isAlreadyFinalized(property->getFinalized())) { state_.push(State::Ignore(true)); return; } + if (finalized) { + property->setFinalized(valueParser_.getLayer()); + } if (type != TYPE_ERROR && property->getStaticType() != TYPE_ANY && type != property->getStaticType()) { @@ -798,14 +799,13 @@ void XcuParser::handleGroupNode( throw css::uno::RuntimeException( "invalid operation on group node in " + reader.getUrl()); } - int finalizedLayer = std::min( - finalized ? valueParser_.getLayer() : Data::NO_LAYER, - child->getFinalized()); - child->setFinalized(finalizedLayer); - if (finalizedLayer < valueParser_.getLayer()) { + if (isAlreadyFinalized(child->getFinalized())) { state_.push(State::Ignore(true)); return; } + if (finalized) { + child->setFinalized(valueParser_.getLayer()); + } state_.push(State::Modify(child)); } @@ -877,12 +877,15 @@ void XcuParser::handleSetNode(xmlreader::XmlReader & reader, SetNode * set) { "set member node " + name + " references undefined template " + templateName + " in " + reader.getUrl()); } + bool alreadyFinalized = false; int finalizedLayer = finalized ? valueParser_.getLayer() : Data::NO_LAYER; int mandatoryLayer = mandatory ? valueParser_.getLayer() : Data::NO_LAYER; NodeMap & members = set->getMembers(); NodeMap::iterator i(members.find(name)); if (i != members.end()) { - finalizedLayer = std::min(finalizedLayer, i->second->getFinalized()); + auto const fin = i->second->getFinalized(); + alreadyFinalized = isAlreadyFinalized(fin); + finalizedLayer = std::min(finalizedLayer, fin); i->second->setFinalized(finalizedLayer); mandatoryLayer = std::min(mandatoryLayer, i->second->getMandatory()); i->second->setMandatory(mandatoryLayer); @@ -891,7 +894,7 @@ void XcuParser::handleSetNode(xmlreader::XmlReader & reader, SetNode * set) { return; } } - if (finalizedLayer < valueParser_.getLayer()) { + if (alreadyFinalized) { state_.push(State::Ignore(true)); return; } diff --git a/configmgr/source/xcuparser.hxx b/configmgr/source/xcuparser.hxx index e50b7b5a0fc8..680b294bd6b3 100644 --- a/configmgr/source/xcuparser.hxx +++ b/configmgr/source/xcuparser.hxx @@ -73,6 +73,8 @@ private: static Operation parseOperation(xmlreader::Span const & text); + bool isAlreadyFinalized(int finalizedLayer) const; + void handleComponentData(xmlreader::XmlReader & reader); void handleItem(xmlreader::XmlReader & reader);