Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions Sources/BarcodeView/Models/EAN13.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,18 @@ extension EAN13 {

return digits
}

private static func verifyChecksumDigit(value: String) -> Bool {
let digits = value.map { Int(String($0))! }.dropLast()

let odd = stride(from: 1, to: digits.count, by: 2).map { digits[$0] }.reduce(0, +) * 3
let even = stride(from: 0, to: digits.count, by: 2).map { digits[$0] }.reduce(0, +)

let calculatedChecksum = 10 - ((odd + even) % 10)

return String(calculatedChecksum) == value.last.map({ String($0) })
let digits = value.compactMap { Int(String($0)) }
let lastDigit = digits.last!
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems inherently unsafe if after the compactMap there are zero elements in digits. Previous code was written a long time ago I should have probably made it safer long ago 😂 Haven't looked at this code in awhile so maybe there are other verification steps that make sure it's the proper number of digits but you may want to check that value.count == digits.count

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nrivard yes, I've seen it, but on line 16 you checked digits, so it is actually fine:

guard !verifyChecksum || EAN13.verifyChecksumDigit(value: value), let digits = EAN13.digits(value: value) else { return nil }


let evenSum = stride(from: 1, to: digits.count - 1, by: 2).map { digits[$0] }.reduce(0, +) * 3
let oddSum = stride(from: 0, to: digits.count - 1, by: 2).map { digits[$0] }.reduce(0, +)
let totalSum = evenSum + oddSum

let calculatedCheckDigit = totalSum % 10 == 0 ? 0 : 10 - totalSum % 10

return calculatedCheckDigit == lastDigit
}
}

Expand Down