Browse files

VBufStorage: Fix crash by not allowing the reusing of nodes with diff…

…ering parents. (#8930)

* VBufStorage: don't allow reusing nodes with differing parents.

* Clarify code comment.
  • Loading branch information...
michaelDCurran committed Nov 9, 2018
1 parent 153b12d commit 244ed4ec042493a1477facf44346ac11cad3a698
Showing with 19 additions and 3 deletions.
  1. +16 −0 nvdaHelper/vbufBase/backend.cpp
  2. +3 −3 nvdaHelper/vbufBase/storage.h
@@ -257,6 +257,10 @@ VBufBackend_t::~VBufBackend_t() {
VBufStorage_controlFieldNode_t* VBufBackend_t::reuseExistingNodeInRender(VBufStorage_controlFieldNode_t* parent, VBufStorage_fieldNode_t* previous, int docHandle, int ID) {
LOG_DEBUG(L"Try to reuse node with docHandle "<<docHandle<<L", and ID "<<ID);
if(!parent) {
LOG_DEBUG(L"Cannot reuse a node at the root");
return nullptr;
if(parent->alwaysRerenderDescendants||parent->alwaysRerenderChildren) {
LOG_DEBUG(L"Won't find a node to reuse as parent says always rerender children");
return nullptr;
@@ -272,6 +276,18 @@ VBufStorage_controlFieldNode_t* VBufBackend_t::reuseExistingNodeInRender(VBufSto
LOG_DEBUG(L"Existing node refuses to be reused");
return nullptr;
// We only allow reusing nodes that share the same parent.
// I.e. we don't allow reusing a node that existed in an entirely different part of the tree.
// If we did, this could possibly cause corruption in the virtualBuffer as a node might move between two unrelated updates.
auto existingParent=existingNode->getParent();
if(!existingParent) {
LOG_DEBUG(L"existing node has no parent. Not reusing.");
return nullptr;
if(existingParent->identifier!=parent->identifier) {
LOG_DEBUG(L"Cannot reuse a node moved from within another parent.");
return nullptr;
if(existingNode->denyReuseIfPreviousSiblingsChanged) {
// This node is not allowed to be reused if any of its previous siblings have changed.
// We work this out by walking back to the previous controlFieldNode in its siblings, and ensuring that it is a reference node that references the existing node's first previous controlFieldNode.
@@ -312,12 +312,12 @@ class VBufStorage_controlFieldNode_t : public VBufStorage_fieldNode_t {
friend class VBufStorage_buffer_t;
* uniquely identifies this control in its buffer.
VBufStorage_controlFieldNodeIdentifier_t identifier;
const VBufStorage_controlFieldNodeIdentifier_t identifier;
* If true, When this node is invalidated in a backend, its parent will be invalidated instead.

0 comments on commit 244ed4e

Please sign in to comment.