View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0011989 | Taler | wallet (iOS App) | public | 2026-11-10 09:45 | 2026-11-10 09:45 |
| Reporter | bot-cg [agent] | Assigned To | Resolution deadline | ||
| Implementer | Reviewer | ||||
| Release signed by | Deployed by | ||||
| Verifier | Communicator | CM_7 | |||
| Data protection authority notification required | No | ||||
| CSIRT notification required | No | ||||
| Estimated effort (hours) | Actual effort (hours) | 0 | |||
| Fast-track | No | ||||
| Work package | none | ||||
| Priority | normal | Severity | minor | Reproducibility | have not tried |
| Status | new | Resolution | open | ||
| Summary | 0011989: Wire Transfer: the “Share the PayTo URL” button shares a Swift struct dump instead of the URL | ||||
| Description | On the "Wire Transfer" screen, the PayTo link offered for sharing is not a PayTo link. The text handed to the share sheet begins with the Swift memberwise description of an internal struct, and the URL the screen promises is not in it at all. What the share sheet receives, captured verbatim by UI automation on iPhone 17 (402x874pt), iOS 27.2, GNU_Taler debug build: PayTo(iban: Optional("CH9709000000166556130"), cyclos: nil, xTaler: Optional("unknown payment method"), sender: nil, receiver: Optional("Taler Operations AG"), postalCode: Optional("2502"), town: Optional("Biel-Bienne"), amountStr: Optional("CHF:0.1"), messageStr: Optional("Taler TZYPDSBPKFKAYVGA614PN32GPHR4D3WSNQHB3EN2..."), chQRr: nil, host: Optional("iban")) IBAN: CH9709000000166556130 Receiver: Taler Operations AG Amount: CHF 0.10 Subject: TZYPDSBPKFKAYVGA614PN32GPHR4D3WSNQHB3EN2... The second paragraph is correct and useful. The first is a debugging dump with "Optional(...)" wrappers, a nil field, and the placeholder string "unknown payment method" -- and the user is about to paste it into a message to their bank. Seen twice in one campaign with different accounts, so it is not a one-off: c2h-16 episode 0 (CHF 0.10) and episode 4 (CH1130000001166556117, CHF 25.00). Cause ----- TalerWallet1/Views/Transactions/ManualDetailsV.swift:206 let textToShare = String("\(payto)\n\nIBAN: \(iban)\nReceiver: ...") `payto` is a `PayTo` *struct* (TalerWallet1/Model/Transaction.swift:124). It conforms to nothing that would give it a textual form, so string interpolation falls back to the compiler-synthesised description. The intention is clearly the URL and not the struct: the sentence above the button reads "**Alternative:** If your bank already supports PayTo, you can use this PayTo-Link instead", the button's accessibility label is "Share the PayTo URL", and `PayTo.init` discards the string it parsed, so the struct cannot reproduce it. The URL is in scope two lines up. `ManualDetailsV.swift:164` binds `paytoUri` and `:170` already passes it to the sibling view as `paytoStr:` -- so the fix is to interpolate that instead. There is a second, smaller thing on the next line: let _ = print(textToShare) a stray debug print, left at the wrong indentation, that writes a full IBAN and the reserve subject to the console on every render of the screen. Suggested fix (patch attached, applies to current master) --------------------------------------------------------- Interpolate `paytoUri` rather than `payto`, and drop the `print`. Nothing else changes; the human-readable block below it is already right. Severity -------- Deliberately filed as minor. The whole block is inside `#if DEBUG` and behind `developerMode`, so a release build never shows it -- but it is on by default in the debug builds testers and developers use, and what it offers to share is unusable for the one purpose it exists for. How to reproduce ---------------- 1. Install the GNU_Taler debug build on an iOS 27.2 simulator. 2. Settings -> Developer -> enable Developer Mode (it is on by default in this build). 3. Actions -> Withdraw -> pick an exchange -> enter an amount -> confirm the *manual* (not bank-integrated) withdrawal, so the Wire Transfer screen appears. 4. Scroll to "**Alternative:** If your bank already supports PayTo..." and press the share button beneath it. 5. The share sheet's text begins with `PayTo(iban: Optional("...")...`. Searched the 300 open issues in this project before filing; 11945 and 11987 concern the same file and the same screen, neither this. Filed by an agent (bot-cg) on behalf of Christian Grothoff, from an automated UI exploration campaign (c2h-16). Left unassigned deliberately. | ||||
| Steps To Reproduce | See "How to reproduce" in the description. Observed: the shared text starts with PayTo(iban: Optional("CH97..."), cyclos: nil, ...). Expected: it starts with the payto:// URI. | ||||
| Additional Information | Found by the UI fuzzing harness's raw-payload oracle (branch dev/bot-cg/fuzzbang), which flags a screen rendering an internal representation. Two instances in campaign c2h-16, episodes 0 and 4, with different accounts and amounts. | ||||
| Tags | No tags attached. | ||||
| Attached Files | payto-share.diff (1,005 bytes)
--- a/TalerWallet1/Views/Transactions/ManualDetailsV.swift
+++ b/TalerWallet1/Views/Transactions/ManualDetailsV.swift
@@ -203,8 +203,7 @@
let title = String(localized: "Share the PayTo URL", comment: "a11y")
let minTitle = String(localized: "Share PayTo", comment: "mini")
// TODO: chQRr
- let textToShare = String("\(payto)\n\nIBAN: \(iban)\nReceiver: \(receiverStr)\nAmount: \(amountStr.1)\nSubject: \(reservePub)")
- let _ = print(textToShare)
+ let textToShare = String("\(paytoUri)\n\nIBAN: \(iban)\nReceiver: \(receiverStr)\nAmount: \(amountStr.1)\nSubject: \(reservePub)")
ShareButton(textToShare, title: minimalistic ? minTitle : title)
.frame(maxWidth: .infinity, alignment: .center)
.accessibilityLabel(Text(title))
| ||||