From 94da1f4ec0790640ebb981043bc3dce6901b2bfa Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Mon, 25 Oct 2021 14:03:59 +0530 Subject: [PATCH 1/2] Check for negative index When accessing array elements, ensure index is a positive integer. --- CardParts/src/Extensions/Array.swift | 5 ++- Example/CardParts.xcodeproj/project.pbxproj | 12 +++++++ Example/Tests/Extensions/ArrayTests.swift | 35 +++++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 Example/Tests/Extensions/ArrayTests.swift diff --git a/CardParts/src/Extensions/Array.swift b/CardParts/src/Extensions/Array.swift index 57317d61..9c7581c0 100644 --- a/CardParts/src/Extensions/Array.swift +++ b/CardParts/src/Extensions/Array.swift @@ -9,11 +9,10 @@ import Foundation extension Array { func safeValue(at index: Int) -> Element? { - if index < self.count { - return self[index] - } else { + guard index >= 0, index < count else { return nil } + return self[index] } } diff --git a/Example/CardParts.xcodeproj/project.pbxproj b/Example/CardParts.xcodeproj/project.pbxproj index 59b5e32a..c1e17695 100644 --- a/Example/CardParts.xcodeproj/project.pbxproj +++ b/Example/CardParts.xcodeproj/project.pbxproj @@ -60,6 +60,7 @@ 80F3C768234ADA7900F5D271 /* CardPartMapViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80F3C767234ADA7900F5D271 /* CardPartMapViewTests.swift */; }; 9A33961F2410208D00167DD5 /* CardPartsBottomSheetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A33961E2410208D00167DD5 /* CardPartsBottomSheetTests.swift */; }; 9A9AE5C323FBA72D0006E1EC /* CardPartBottomSheetCardController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A9AE5C223FBA72D0006E1EC /* CardPartBottomSheetCardController.swift */; }; + A6A6D2CD272463EE00DA453A /* ArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6A6D2CC272463EE00DA453A /* ArrayTests.swift */; }; EB16E38A2396E8FD003F70A2 /* CardParthCustomMarginsCardController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB16E3892396E8FD003F70A2 /* CardParthCustomMarginsCardController.swift */; }; /* End PBXBuildFile section */ @@ -136,6 +137,7 @@ 80F3C767234ADA7900F5D271 /* CardPartMapViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPartMapViewTests.swift; sourceTree = ""; }; 9A33961E2410208D00167DD5 /* CardPartsBottomSheetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPartsBottomSheetTests.swift; sourceTree = ""; }; 9A9AE5C223FBA72D0006E1EC /* CardPartBottomSheetCardController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPartBottomSheetCardController.swift; sourceTree = ""; }; + A6A6D2CC272463EE00DA453A /* ArrayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayTests.swift; sourceTree = ""; }; B21177744B384387575CB614 /* Pods-CardParts_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CardParts_Tests.debug.xcconfig"; path = "Target Support Files/Pods-CardParts_Tests/Pods-CardParts_Tests.debug.xcconfig"; sourceTree = ""; }; E768E0B2422010080EDB1A52 /* Pods-CardParts_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CardParts_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CardParts_Tests/Pods-CardParts_Tests.release.xcconfig"; sourceTree = ""; }; EB16E3892396E8FD003F70A2 /* CardParthCustomMarginsCardController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardParthCustomMarginsCardController.swift; sourceTree = ""; }; @@ -214,6 +216,7 @@ 607FACE81AFB9204008FA782 /* Tests */ = { isa = PBXGroup; children = ( + A6A6D2C92724500F00DA453A /* Extensions */, 61D4706E1FDA709B00F451F0 /* CardPartButtonViewTests.swift */, 61D4706A1FDA709B00F451F0 /* CardPartImageViewTests.swift */, 9A33961E2410208D00167DD5 /* CardPartsBottomSheetTests.swift */, @@ -298,6 +301,14 @@ name = Frameworks; sourceTree = ""; }; + A6A6D2C92724500F00DA453A /* Extensions */ = { + isa = PBXGroup; + children = ( + A6A6D2CC272463EE00DA453A /* ArrayTests.swift */, + ); + path = Extensions; + sourceTree = ""; + }; BABC66A8CBE4FFFB18E62FFE /* Pods */ = { isa = PBXGroup; children = ( @@ -574,6 +585,7 @@ buildActionMask = 2147483647; files = ( 80F3C768234ADA7900F5D271 /* CardPartMapViewTests.swift in Sources */, + A6A6D2CD272463EE00DA453A /* ArrayTests.swift in Sources */, 61D470751FDA709B00F451F0 /* CardPartButtonViewTests.swift in Sources */, 61D470721FDA709B00F451F0 /* CardPartTitleViewTests.swift in Sources */, 55AB80CF20B61E1700B5994B /* CardUtilsTests.swift in Sources */, diff --git a/Example/Tests/Extensions/ArrayTests.swift b/Example/Tests/Extensions/ArrayTests.swift new file mode 100644 index 00000000..f509c66c --- /dev/null +++ b/Example/Tests/Extensions/ArrayTests.swift @@ -0,0 +1,35 @@ +// +// ArrayTests.swift +// CardParts_Tests +// + +import XCTest +@testable import CardParts + +class ArrayExtesionTests: XCTestCase { + + func testSafeValue() { + var array: [Int] + + // when array is empty + array = [] + + XCTAssertNil(array.safeValue(at: -1), "Should be nil for negative index") + XCTAssertNil(array.safeValue(at: 0), "Should be nil for positive index if array is empty") + XCTAssertNil(array.safeValue(at: Int.random(in: 1...100)), "Should be nil for positive index if array is empty") + + // when array is not empty + array = [ + Int.random(in: 0...100), + Int.random(in: 0...100), + Int.random(in: 0...100) + ] + + XCTAssertNil(array.safeValue(at: -1), "Should be nil for negative index") + XCTAssertNil(array.safeValue(at: array.count), "Should be nil for positive index out of range") + + for index in 0.. Date: Mon, 25 Oct 2021 15:13:30 +0530 Subject: [PATCH 2/2] Documentation Add documentation for method `safeValue` --- CardParts/src/Extensions/Array.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CardParts/src/Extensions/Array.swift b/CardParts/src/Extensions/Array.swift index 9c7581c0..eff631d1 100644 --- a/CardParts/src/Extensions/Array.swift +++ b/CardParts/src/Extensions/Array.swift @@ -8,6 +8,9 @@ import Foundation extension Array { + /// read an array element at a given `index` safely + /// - Parameter index: the index of the element to read + /// - Returns: array element at a given `index`. `nil` if index is out of range func safeValue(at index: Int) -> Element? { guard index >= 0, index < count else { return nil