Skip to content

htaccess/escape-literal-dots ​

Severity: warning · Status: enforced · Applies to: ids/**/.htaccess

What ​

A . in a RewriteRule pattern matches any single character. To match a literal dot — in a filename, a version number, or a media type — escape it as \..

Why ​

^vocab.ttl$ looks like it matches vocab.ttl, and it does. It also matches vocabXttl, vocab-ttl, vocab1ttl, and every other single character in that position.

That is rarely what you want, and it produces redirects for URLs you never intended to serve — which then fail at the destination, giving the user a 404 from your server instead of a clean 404 from w3id.org. In a versioned scheme it can silently route one version's requests to another.

The same applies inside RewriteCond patterns, where media types are the usual victim: application/ld+json is a regular expression in which + means "one or more of the preceding character".

Wrong ​

apache
RewriteRule ^vocab.ttl$ https://example.org/vocab.ttl [R=303,L]
RewriteRule ^(1.0.0)$ https://example.org/$1/vocab.ttl [R=303,L]

RewriteCond %{HTTP_ACCEPT} application/ld+json
apache
RewriteRule ^vocab\.ttl$ https://example.org/vocab.ttl [R=303,L]
RewriteRule ^(1\.0\.0)$ https://example.org/$1/vocab.ttl [R=303,L]

RewriteCond %{HTTP_ACCEPT} application/ld\+json

A version pattern in general:

apache
RewriteRule ^([0-9]+(\.[0-9]+)*)$ https://example.org/$1/vocab.ttl [R=303,L]

Dots in the substitution are literal and need no escaping — only the pattern is a regular expression.

How to fix ​

Escape every . in the pattern that is meant to be a literal dot.

A dot that is a deliberate wildcard is not reported: (.*), (.+) and .? are all doing their job, and so is a dot inside a character class. The check looks only for a dot followed by something shaped like a file extension, which is where the mistake actually lives.

How to check ​

Run w3id-check with --rule htaccess/escape-literal-dots to check this rule on its own; without it the tool runs every rule, as the pull request checks do.

sh
node tools/check/bin/w3id-check.js --rule htaccess/escape-literal-dots ids/my-project

Testing your changes covers installing the tool, and what else is worth checking by hand.

See also ​