cloudflare / cloudflare/cloudflare-os
Gmail URLs containing a bare % throw an unhandled URIError when binding a resource
- Dominant language
- TypeScript
- Stars
- 9.9k
- Forks
- 1.2k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 107
Description
Binding a Gmail resource from a URL containing a bare `%` throws an unhandled `URIError` instead of the friendly error the surrounding code raises for every other kind of bad input.
```
https://mail.google.com/mail/u/0/#search/50%off
https://mail.google.com/mail/u/0/#label/Q1 100%
```
Both produce:
```
URIError: URI malformed
```
`getGatekeeperClassFor` in `packages/gatekeeper-google/src/google.ts` decodes the hash with a bare `decodeURIComponent`:
- `#search/` at line 941, after the `+` to space normalization
- `#label/` at line 945
Neither is inside a `try`. That sits oddly next to the rest of the same function, which goes out of its way to explain itself when input is wrong: "Invalid Google Sheets URL: no spreadsheet ID found", "Invalid Google Calendar URL: no calendar ID found", "Gmail label name must be between 1 and 320 bytes." A user who pastes a search containing a percent sign gets none of that, just the raw decode failure.
A `%` in a Gmail search or label is not unusual. "50% off", "Q1 100%", any label with a percentage in it.
The calendar branch at line 869 has the same shape, `decodeURIComponent(parsed.pathname.split("/")[2] ?? "")`, though it only throws when the `%` lands in that specific path segment, so it takes a more contrived URL to hit.
### Scope
I have not sent a PR for this. The same bare-decode pattern is in seven gatekeeper packages (confluence, email, homeassistant, linear, notion, slack, google), and there is no shared safe-decode helper to route them through. Fixing one file is arbitrary and fixing all seven is well past the dozen lines CONTRIBUTING.md asks for, so the shape of the fix seems like your call rather than mine.
If a narrow one is useful, wrapping just the two Gmail branches so the existing "Invalid Gmail URL" style error surfaces instead would be a few lines, and I am happy to send that.
Verified on `0eaec6c`.
Contributor guide
Research direction
Start in packages/gatekeeper-google/src/google.ts at getGatekeeperClassFor, especially the Gmail #search/ and #label/ branches and the calendar decode mentioned in the issue. Reproduce the supplied URLs, inspect the surrounding invalid-input handling, and confirm that malformed percent-encoded input produces the project’s friendly error rather than an unhandled URIError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100