From 929908f28728c217ab4a16c8596e0957295f4d67 Mon Sep 17 00:00:00 2001 From: Vojtech Novak Date: Sun, 3 Mar 2019 20:27:42 -0800 Subject: [PATCH] make sure to check array bounds in VirtualizedSectionList (#23710) Summary: SectionList accesses items outside of the array bounds. This was discovered when using mobx, which warns you: `[mobx.array] Attempt to read an array index (${index}) that is out of bounds`. This is because `section.data[itemIndex + 1]` goes beyond array length. This PR adds an array length check and simplifies the code a bit to avoid repetitive `this.props.` Pull Request resolved: https://github.com/facebook/react-native/pull/23710 Differential Revision: D14298557 Pulled By: cpojer fbshipit-source-id: fee3422ad5b053d91a097c5842f46e78a149c3d5 --- Libraries/Lists/VirtualizedSectionList.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/Libraries/Lists/VirtualizedSectionList.js b/Libraries/Lists/VirtualizedSectionList.js index e314871c4e..7cb2af4dff 100644 --- a/Libraries/Lists/VirtualizedSectionList.js +++ b/Libraries/Lists/VirtualizedSectionList.js @@ -221,9 +221,9 @@ class VirtualizedSectionList extends React.PureComponent< trailingSection?: ?SectionT, } { let itemIndex = index; - const defaultKeyExtractor = this.props.keyExtractor; - for (let ii = 0; ii < this.props.sections.length; ii++) { - const section = this.props.sections[ii]; + const {sections} = this.props; + for (let ii = 0; ii < sections.length; ii++) { + const section = sections[ii]; const key = section.key || String(ii); itemIndex -= 1; // The section adds an item for the header if (itemIndex >= section.data.length + 1) { @@ -234,7 +234,7 @@ class VirtualizedSectionList extends React.PureComponent< key: key + ':header', index: null, header: true, - trailingSection: this.props.sections[ii + 1], + trailingSection: sections[ii + 1], }; } else if (itemIndex === section.data.length) { return { @@ -242,18 +242,21 @@ class VirtualizedSectionList extends React.PureComponent< key: key + ':footer', index: null, header: false, - trailingSection: this.props.sections[ii + 1], + trailingSection: sections[ii + 1], }; } else { - const keyExtractor = section.keyExtractor || defaultKeyExtractor; + const keyExtractor = section.keyExtractor || this.props.keyExtractor; return { section, key: key + ':' + keyExtractor(section.data[itemIndex], itemIndex), index: itemIndex, leadingItem: section.data[itemIndex - 1], - leadingSection: this.props.sections[ii - 1], - trailingItem: section.data[itemIndex + 1], - trailingSection: this.props.sections[ii + 1], + leadingSection: sections[ii - 1], + trailingItem: + section.data.length > itemIndex + 1 + ? section.data[itemIndex + 1] + : undefined, + trailingSection: sections[ii + 1], }; } }