uttrflow / uttrflow/uttrflow-swift

HTML-only clipboard conversion drops a link destination when URL paths differ only by case

Open
#805 0 comments 0 reactions 0 assignees View on GitHub
bug P2
Dominant language
Swift
Stars
4
Forks
17
Avg merge
4h 27m
Merged PRs (30d)
286

Description

## Problem

`PlainTextRenderer.sameDestination` lowercases the entire link label and href before comparing them. Paths can be case-sensitive, so two different destinations can be treated as identical. `closeLink` then omits the href and retains only the displayed text, defeating the converter's purpose of preserving a link's destination in plain text.

## Reproduction

```html
https://example.com/report
```

Expected plain text: `https://example.com/report (https://example.com/Report)`.

Actual plain text: `https://example.com/report`. The actual destination `/Report` is absent. Both the direct converter assertion and the watcher clip-text assertion fail.

[RFC 3986 section 6.2.2.1](https://www.rfc-editor.org/rfc/rfc3986#section-6.2.2.1) distinguishes case-insensitive scheme/host components from other components, which are assumed case-sensitive unless their scheme defines otherwise. The reproduction uses reserved example addresses and makes no request to a real server.

## Reachability and verification limits

Reviewed unmodified main `8d93f5b8574f3c7b8c30086d9c817bf7f5d4827d`. Verified both the converter and `PasteboardWatcher.newClip(at:)`, supplying HTML with no plain-string or image representation through the existing `FakeClipboard` test seam. The watcher returns a clip whose `text` has the incorrect conversion; its `richText` retains the original HTML. A control with an explicit plain-string representation passes, because that representation bypasses conversion. This is an HTML-only clipboard path, not a claim that all browser copies are affected. No live application clipboard or UI was exercised.

The existing rich-text suites passed in the preceding review pass. The new tests assert expected content independently of the converter.

## Fix and acceptance checks

Compare URL components with their appropriate equivalence rules instead of lowercasing the complete strings. Preserve destination text whenever equivalence is uncertain. Add path-case and query-case fixtures, while retaining the existing host-case and identical-URL controls. Keep the exact destination when printing it.

Code: `Sources/UttrflowClipboard/RichTextPlainForm.swift:628-666` (`closeLink`, `sameDestination`) and `PasteboardWatcher.swift:118-121`. `Docs/clipboard-plain-form.md` promises to preserve destinations except when already present in the text. #742 covers empty labels and tokenizer branches; #741 covers the fallback path, neither this false-equivalence behavior.

Contributor guide

Open the contributing guide

Research direction

Start in Sources/UttrflowClipboard/RichTextPlainForm.swift:628-666, reading sameDestination and closeLink, then inspect PasteboardWatcher.swift:118-121 and the existing FakeClipboard-based converter and watcher assertions. Verify that path-case and query-case differences preserve the destination, while host-case and identical-URL controls retain their existing behavior; the documented destination-preservation promise should remain satisfied.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, swift
Domain
desktop
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.