Skip to content

Commit aabcfc6

Browse files
validate child index in YGNodeSwapChild and YGNodeInsertChild
1 parent 4a59d09 commit aabcfc6

2 files changed

Lines changed: 52 additions & 0 deletions

File tree

tests/YGNodeChildTest.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8+
#include <stdexcept>
9+
810
#include <gtest/gtest.h>
911
#include <yoga/Yoga.h>
1012

@@ -66,3 +68,43 @@ TEST(YogaTest, removed_child_can_be_reused_with_valid_layout) {
6668

6769
YGNodeFreeRecursive(root);
6870
}
71+
72+
TEST(YogaTest, swap_child_with_out_of_bounds_index_is_rejected) {
73+
YGNodeRef root = YGNodeNew();
74+
YGNodeRef child = YGNodeNew();
75+
YGNodeInsertChild(root, child, 0);
76+
77+
// Replacing an existing index works.
78+
YGNodeRef replacement = YGNodeNew();
79+
YGNodeSwapChild(root, replacement, 0);
80+
ASSERT_EQ(replacement, YGNodeGetChild(root, 0));
81+
82+
// An index past the last child is rejected rather than reading and writing
83+
// out of bounds on the underlying children vector.
84+
YGNodeRef stray = YGNodeNew();
85+
ASSERT_THROW(YGNodeSwapChild(root, stray, 1), std::logic_error);
86+
87+
YGNodeFree(stray);
88+
YGNodeFree(child);
89+
YGNodeFreeRecursive(root);
90+
}
91+
92+
TEST(YogaTest, insert_child_with_out_of_bounds_index_is_rejected) {
93+
YGNodeRef root = YGNodeNew();
94+
95+
YGNodeRef first = YGNodeNew();
96+
YGNodeInsertChild(root, first, 0);
97+
98+
// Appending at the end (index == child count) is allowed.
99+
YGNodeRef second = YGNodeNew();
100+
YGNodeInsertChild(root, second, 1);
101+
ASSERT_EQ(2u, YGNodeGetChildCount(root));
102+
103+
// An index beyond the end is rejected rather than constructing an invalid
104+
// iterator into the children vector.
105+
YGNodeRef stray = YGNodeNew();
106+
ASSERT_THROW(YGNodeInsertChild(root, stray, 5), std::logic_error);
107+
108+
YGNodeFree(stray);
109+
YGNodeFreeRecursive(root);
110+
}

yoga/YGNode.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ void YGNodeInsertChild(
142142
!owner->hasMeasureFunc(),
143143
"Cannot add child: Nodes with measure functions cannot have children.");
144144

145+
yoga::assertFatalWithNode(
146+
owner,
147+
index <= owner->getChildCount(),
148+
"Cannot insert child: index out of bounds.");
149+
145150
owner->insertChild(child, index);
146151
child->setOwner(owner);
147152
owner->markDirtyAndPropagate();
@@ -154,6 +159,11 @@ void YGNodeSwapChild(
154159
auto owner = resolveRef(ownerRef);
155160
auto child = resolveRef(childRef);
156161

162+
yoga::assertFatalWithNode(
163+
owner,
164+
index < owner->getChildCount(),
165+
"Cannot swap child: index out of bounds.");
166+
157167
owner->replaceChild(child, index);
158168
child->setOwner(owner);
159169
}

0 commit comments

Comments
 (0)