Skip to content
Open
Show file tree
Hide file tree
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
7 changes: 5 additions & 2 deletions receipt_utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ export class ReceiptUtility {
ASN1HEX.getVblen = function(s, idx) {
const c = ASN1HEX.getL(s, idx)
const oldResult = prevGetVblenFunction(s, idx)
// Round up to the remaining length in the string, measured in bytes (2 hex values per byte)
// Round up to the remaining length in the string, measured in bytes (2 hex values per byte).
// The value starts after the tag and length octets, so measure from the value index rather
// than the tag index. jsrsasign 11.1.2 added a "c + getVblen * 2 > s.length" bounds check in
// getChildIdx; measuring from idx overshoots by the header length and trips that check.
if (oldResult === 0 && c === '80') {
return (s.length - idx) / 2
return (s.length - ASN1HEX.getVidx(s, idx)) / 2
}
return oldResult
}
Expand Down
8 changes: 8 additions & 0 deletions tests/unit-tests/receipt_utility.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@ describe('Receipt Utility Tets', () => {
const extracted_transaction_id = receipt_utility.extractTransactionIdFromTransactionReceipt(receipt)
expect(extracted_transaction_id).toBe("33993399")
})
it('should parse an indefinite length xcode receipt without throwing a too short ASN.1 value error', async () => {
// Regression test for the "too short ASN.1 value" bounds check added to jsrsasign getChildIdx in 11.1.2.
// Xcode receipts use indefinite length encoding, and the parse must succeed across jsrsasign versions.
const receipt = readFile('tests/resources/xcode/xcode-app-receipt-with-transaction')
const receipt_utility = new ReceiptUtility()
expect(() => receipt_utility.extractTransactionIdFromAppReceipt(receipt)).not.toThrow()
expect(receipt_utility.extractTransactionIdFromAppReceipt(receipt)).toBe("0")
})
})