taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

commit cca98ab52cc17281ed8eaffaf2258ddfff14ec3d
parent a70e87859e6f553966fbf640bee2fe35c2e2676b
Author: Marc Stibane <marc@taler.net>
Date:   Mon, 29 Jun 2026 10:07:01 +0200

ensure NFC read data doesn't try to read outside the buffer

Diffstat:
MTalerWallet1/Helper/apdu.swift | 27+++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/TalerWallet1/Helper/apdu.swift b/TalerWallet1/Helper/apdu.swift @@ -220,6 +220,7 @@ class APDU { return lenData } // 00b0000002 + guard commandApdu.count >= 2 else { return A_ERROR } /// Sixth (and seventh) Command: Read the NDEF File // 00b0 00 02 3b, and 00b0 00 3d 27 if NDEF_READ_BINARY == commandApdu[0..<2] { let count = commandApdu.count @@ -227,9 +228,8 @@ class APDU { var arrayApdu = Array<UInt8>(repeating: 0, count: count) _ = arrayApdu.withUnsafeMutableBytes { commandApdu.copyBytes(to: $0) } - let wantedLength = Int(arrayApdu[4]) - let offset = Int(arrayApdu[3]) + (Int(arrayApdu[2]) << 8) - logger.info("NDEF_READ_BINARY offset \(offset), length \(wantedLength) triggered. Our Response: data + A_OKAY") + let wantedLength = UInt(arrayApdu[4]) + let offset = UInt(arrayApdu[3]) + (UInt(arrayApdu[2]) << 8) var data = NDEF_RECORD_HEADER_SHORT // 2 bytes let uriCount8 = UInt8((uriCount + 1) & 0xff) @@ -241,11 +241,22 @@ class APDU { data.append(zeroData) // 1 byte data.append(talerUri.data(using: .utf8)!) - var result = Data(fromData: data, - offset: Int(offset) - 2, // subtract 2 length bytes - size: wantedLength) - result.append(A_OKAY) // 2 bytes - + var result = A_ERROR + let lengthBytes = UInt(2) + // ensure wanted data starts after two length bytes + if offset >= lengthBytes { + // Swift.Data doesn't have the length bytes within the data + let diffOffset = offset - lengthBytes + let count = UInt(data.count) + // ensure wanted data doesn't exceed buffer + if diffOffset + wantedLength <= count { + logger.info("NDEF_READ_BINARY offset \(offset), length \(wantedLength) triggered. Our Response: data + A_OKAY") + result = Data(fromData: data, + offset: diffOffset, + size: wantedLength) + result.append(A_OKAY) // 2 bytes + } + } readCapabilityContainerCheck = false return result }