diff options
author | Michael Stahl <mstahl@redhat.com> | 2017-12-11 20:00:15 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2017-12-11 20:39:33 +0100 |
commit | 8a3bb9356219754af7e651a879b5fc8925a18468 (patch) | |
tree | 6483a8cb622bb8489d98d1975477e7286ef4a395 /xmlhelp | |
parent | 54dfb9ff07a41d9249302ac2ed0a005d0a8114d4 (diff) |
tdf#114242 xmlhelp: fix crash in TVChildTarget::Check()
The ... idiomatic C++ code in TVChildTarget::Check() and
SearchAndInsert() handles ownership in non-obvious ways,
so it's not surprising that it took offense at the recent
conversion to std::unique_ptr. Let's at least try to
prevent it from crashing so quickly.
(regression from 4b69497e36b941d4db62ae8d5bad863d032fdc50)
Change-Id: I0981707a61aee1733e727b1c00346d8ec524362e
Diffstat (limited to 'xmlhelp')
-rw-r--r-- | xmlhelp/source/cxxhelp/inc/tvread.hxx | 2 | ||||
-rw-r--r-- | xmlhelp/source/treeview/tvread.cxx | 36 |
2 files changed, 23 insertions, 15 deletions
diff --git a/xmlhelp/source/cxxhelp/inc/tvread.hxx b/xmlhelp/source/cxxhelp/inc/tvread.hxx index bef027c06399..f4bb0631d30d 100644 --- a/xmlhelp/source/cxxhelp/inc/tvread.hxx +++ b/xmlhelp/source/cxxhelp/inc/tvread.hxx @@ -227,7 +227,7 @@ namespace treeview { static void subst( OUString& instpath ); - bool SearchAndInsert(TVDom* p, TVDom* tvDom); + std::unique_ptr<TVDom> SearchAndInsert(std::unique_ptr<TVDom> p, TVDom* tvDom); void Check(TVDom* tvDom); diff --git a/xmlhelp/source/treeview/tvread.cxx b/xmlhelp/source/treeview/tvread.cxx index d8b95c84bfad..f3fe31b44d46 100644 --- a/xmlhelp/source/treeview/tvread.cxx +++ b/xmlhelp/source/treeview/tvread.cxx @@ -61,11 +61,10 @@ namespace treeview { return children.back().get(); } - TVDom* newChild(TVDom* p) + void newChild(std::unique_ptr<TVDom> p) { - children.emplace_back( p ); - p->parent = this; - return children.back().get(); + children.emplace_back(std::move(p)); + children.back()->parent = this; } TVDom* getParent() const @@ -448,8 +447,13 @@ void TVChildTarget::Check(TVDom* tvDom) TVDom* p = tvDom->children.back().get(); for(auto & k : p->children) - if (!SearchAndInsert(k.get(), tvDom->children[i].get())) - tvDom->children[i]->newChild(k.get()); + { + std::unique_ptr<TVDom> tmp(SearchAndInsert(std::move(k), tvDom->children[i].get())); + if (tmp) + { + tvDom->children[i]->newChild(std::move(tmp)); + } + } tvDom->children.pop_back(); h = true; @@ -458,9 +462,10 @@ void TVChildTarget::Check(TVDom* tvDom) } } -bool TVChildTarget::SearchAndInsert(TVDom* p, TVDom* tvDom) +std::unique_ptr<TVDom> +TVChildTarget::SearchAndInsert(std::unique_ptr<TVDom> p, TVDom* tvDom) { - if (p->isLeaf()) return false; + if (p->isLeaf()) return p; bool h = false; sal_Int32 max = 0; @@ -481,8 +486,8 @@ bool TVChildTarget::SearchAndInsert(TVDom* p, TVDom* tvDom) if (p_int==c_int) { - (*(tvDom->children.insert(i+1, std::unique_ptr<TVDom>(p))))->parent = tvDom; - return true; + (*(tvDom->children.insert(i+1, std::move(p))))->parent = tvDom; + return nullptr; } else if(c_int>max && c_int < p_int) { @@ -491,17 +496,20 @@ bool TVChildTarget::SearchAndInsert(TVDom* p, TVDom* tvDom) } } if (h) - (*(tvDom->children.insert(max_It, std::unique_ptr<TVDom>(p))))->parent = tvDom; + { + (*(tvDom->children.insert(max_It, std::move(p))))->parent = tvDom; + return nullptr; + } else { i = tvDom->children.begin(); - while ((i!=tvDom->children.end()) && (!h)) + while ((i!=tvDom->children.end()) && (p != nullptr)) { - h = SearchAndInsert(p, i->get()); + p = SearchAndInsert(std::move(p), i->get()); ++i; } + return p; } - return h; } Any SAL_CALL |