mirror of
https://github.com/darlinghq/xcbuild.git
synced 2025-02-21 17:00:49 +00:00
Do cycle check on recursive inheritSpecification call
This commit is contained in:
parent
75c3135b0b
commit
a7e954ab36
@ -131,7 +131,7 @@ public:
|
||||
|
||||
private:
|
||||
void addSpecification(PBX::Specification::shared_ptr const &specification);
|
||||
bool inheritSpecification(PBX::Specification::shared_ptr const &specification);
|
||||
bool inheritSpecification(PBX::Specification::shared_ptr const &specification, std::vector<PBX::Specification::shared_ptr>);
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
|
@ -285,7 +285,7 @@ addSpecification(PBX::Specification::shared_ptr const &spec)
|
||||
}
|
||||
|
||||
bool Manager::
|
||||
inheritSpecification(PBX::Specification::shared_ptr const &specification)
|
||||
inheritSpecification(PBX::Specification::shared_ptr const &specification, std::vector<PBX::Specification::shared_ptr> visited)
|
||||
{
|
||||
if (specification->basedOnIdentifier() && specification->basedOnDomain() && specification->base() == nullptr) {
|
||||
/* Find the base specification. */
|
||||
@ -308,8 +308,22 @@ inheritSpecification(PBX::Specification::shared_ptr const &specification)
|
||||
* <any>:identifier and potentially find foo:identifier again.
|
||||
*/
|
||||
auto I = std::find_if(candidates.begin(), candidates.end(),
|
||||
[&specification](PBX::Specification::shared_ptr const &spec) -> bool {
|
||||
return specification != spec;
|
||||
[&specification, &visited](PBX::Specification::shared_ptr const &spec) -> bool {
|
||||
for (auto duplicate : visited) {
|
||||
// check if specification exists in current inheritance chain.
|
||||
if (specification == duplicate) {
|
||||
return false;
|
||||
}
|
||||
// check if base candidate already inherited from specification in question.
|
||||
auto base = duplicate->base();
|
||||
while (base) {
|
||||
if (specification == base) {
|
||||
return false;
|
||||
}
|
||||
base = base->base();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if (I != candidates.end()) {
|
||||
base = *I;
|
||||
@ -330,7 +344,10 @@ inheritSpecification(PBX::Specification::shared_ptr const &specification)
|
||||
* Ensure the base specification itself has been inherited. Since inheritance
|
||||
* copies values from the base, the base must have its own values set first.
|
||||
*/
|
||||
if (!inheritSpecification(base)) {
|
||||
visited.push_back(base);
|
||||
bool success = inheritSpecification(base, visited);
|
||||
visited.pop_back();
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -439,7 +456,8 @@ registerDomains(Filesystem const *filesystem, std::vector<std::pair<std::string,
|
||||
* Inherit from existing and newly added specifications.
|
||||
*/
|
||||
for (PBX::Specification::shared_ptr const &specification : specifications) {
|
||||
if (!inheritSpecification(specification)) {
|
||||
std::vector<PBX::Specification::shared_ptr> visited { specification };
|
||||
if (!inheritSpecification(specification, visited)) {
|
||||
/* Unfortunately, not much useful error handling to do here. */
|
||||
continue;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ Specification()
|
||||
bool Specification::
|
||||
operator==(Specification const &rhs) const
|
||||
{
|
||||
return _identifier == rhs._identifier && _domain == rhs._domain;
|
||||
return _identifier.compare(rhs._identifier) == 0 && _domain.compare(rhs._domain) == 0;
|
||||
}
|
||||
|
||||
bool Specification::
|
||||
|
Loading…
x
Reference in New Issue
Block a user