CLAUDE WATERMARK REMOVER · PRACTICAL TEST
Does URL.canParse confirm that a cleaned link is an allowed web URL?
No. Our data and mailto controls both parse successfully but fail the example HTTP/HTTPS policy. Cleaning repairs the marked HTTPS scheme. Parseability, allowed protocol and actual reachability remain separate checks.
Open the Claude text cleaner · Full measured data
Measured inputs and outputs
These are locally constructed test strings, not evidence that Claude inserts these characters. We executed the saved homepage script snapshot with a minimal DOM harness and compared exact strings. The invisible-checkbox state and dash mode appear in each row. The observations below test this page's specific question. Destination observations run independently on the exact input and cleaned strings in the recorded Node runtime. We make no detector-score or statistical-watermark removal claim.
| Fixture and mode | Input string and code points | Output and cleaner status | Observed before / after |
|---|---|---|---|
| Marked https scheme direct string / keep / invisible true | "https://example.test/"U+0068 U+0074 U+200B U+0074 U+0070 U+0073 U+003A U+002F U+002F U+0065 U+0078 U+0061 U+006D U+0070 U+006C U+0065 U+002E U+0074 U+00 … | "https://example.test/"Removed 1 invisible character | {"canParse":false,"parsed":null,"allowedHttp":false}{"canParse":true,"parsed":{"href":"https://example.test/","protocol":"https:","hostname":"example.test"},"allowedHttp":true} |
| Https control direct string / keep / invisible true | "https://example.test/"U+0068 U+0074 U+0074 U+0070 U+0073 U+003A U+002F U+002F U+0065 U+0078 U+0061 U+006D U+0070 U+006C U+0065 U+002E U+0074 U+0065 U+00 … | "https://example.test/"No selected invisible characters found | {"canParse":true,"parsed":{"href":"https://example.test/","protocol":"https:","hostname":"example.test"},"allowedHttp":true}{"canParse":true,"parsed":{"href":"https://example.test/","protocol":"https:","hostname":"example.test"},"allowedHttp":true} |
| Data URL direct string / keep / invisible true | "data:text/plain,AB"U+0064 U+0061 U+0074 U+0061 U+003A U+0074 U+0065 U+0078 U+0074 U+002F U+0070 U+006C U+0061 U+0069 U+006E U+002C U+0041 U+0042 | "data:text/plain,AB"No selected invisible characters found | {"canParse":true,"parsed":{"href":"data:text/plain,AB","protocol":"data:","hostname":""},"allowedHttp":false}{"canParse":true,"parsed":{"href":"data:text/plain,AB","protocol":"data:","hostname":""},"allowedHttp":false} |
| Mail URL direct string / keep / invisible true | "mailto:a@example.test"U+006D U+0061 U+0069 U+006C U+0074 U+006F U+003A U+0061 U+0040 U+0065 U+0078 U+0061 U+006D U+0070 U+006C U+0065 U+002E U+0074 U+00 … | "mailto:a@example.test"No selected invisible characters found | {"canParse":true,"parsed":{"href":"mailto:a@example.test","protocol":"mailto:","hostname":""},"allowedHttp":false}{"canParse":true,"parsed":{"href":"mailto:a@example.test","protocol":"mailto:","hostname":""},"allowedHttp":false} |
Syntactic acceptance includes more than web navigation links
We invoke URL.canParse and URL.parse without a base. The marked HTTPS fixture initially has no recognized valid absolute scheme, so canParse is false and parse returns null. Removing the selected marker repairs it to the HTTPS control, which both functions accept. The data and mailto controls are accepted as well, yet their protocols are data: and mailto:, and the hostname fields are empty in these particular examples. Our allowedHttp expression permits only http: or https:, therefore returning false for both. The comparison demonstrates an explicit policy decision after successful parsing rather than assuming that a true parser result implies a usable HTTPS link.
The example allowlist does not establish endpoint trust
No URL in this test is fetched, opened or sent to a remote service. The example.test hostname is a fixture, not evidence of an available website. Even the accepted HTTPS control has only passed syntax and this narrow protocol policy. We do not resolve DNS, examine redirects, check a certificate, classify an address, or implement a complete fetch policy. The earlier scheme-fallback guide supplies a base and measures relative resolution; this test supplies none and uses a nullable parsing interface. Its invalid first row therefore does not contradict acceptance under an explicit base. Runtime support for the two static methods is recorded by the reproducer’s Node version.
Name the validation result according to what it measured
Keep parser failure separate from a policy rejection so an interface can explain whether the spelling is malformed or the supported link type differs. Review the protocol after the intended cleanup because the repaired fixture changes its parser outcome. Add the receiving application’s further requirements where appropriate and test them independently; a boolean named valid can obscure which requirements actually ran. The harness uses inert strings and retains the parsed fields alongside both boolean results. It does not infer a link’s safety, ownership, availability or content from a removal count. These controls answer the narrow question of why a successfully parsed value may still fail a declared HTTP-only input contract.
Reproduce this test
Save reproduce.cjs and tested-app.js in the same folder. Run the command below with Node.js. The harness prints its runtime, script SHA-256 and every measured row. Compare those rows with the original record. Using a newer script or runtime creates a new experiment; retain the version information with your rerun.
node reproduce.cjsReference and next check
WHATWG URL.canParse provides the relevant primary definition. The table and fixture analysis are original measurements. For broader inspection, use our Unicode inspector. Read the scope distinction before interpreting cleanup as a watermark result.