Regular-expression syntax inside a shExpMatch pattern
low
shExpMatch(host, "(www|mail).corp.example") works in Chromium, Firefox and pacparser only because their helper converts the glob into a JavaScript RegExp without escaping ( ) and |. That is an implementation accident, not the PAC contract; other engines may treat the characters literally.
Why it matters
The PAC specification defines shExpMatch as shell-style matching with * and ?. The
JavaScript helper library shared by Chromium, Firefox and pacparser escapes dots, rewrites
* and ? and then builds a RegExp, so alternation (a|b) and other regex syntax leak
through and work. WinHTTP implements shExpMatch natively; whether it accepts the same
syntax is unverified. A PAC relying on alternation therefore has an engine dependency that
is invisible in browser tests. Writing the alternatives as separate shExpMatch or host ==
clauses is portable and no slower. Draft until the WinHTTP behaviour is confirmed in the lab.
How to fix
Spell the alternatives out as separate conditions joined with ||.
Examples
Bad
function FindProxyForURL(url, host) {
if (shExpMatch(host, "(www|mail).corp.example")) {
return "DIRECT";
}
return "PROXY proxy.corp.example:8080";
}
Open bad example in checkerGood
function FindProxyForURL(url, host) {
if (host == "www.corp.example" || host == "mail.corp.example") {
return "DIRECT";
}
return "PROXY proxy.corp.example:8080";
}
Open good example in checkerEngine behaviour
| Engine | Behaviour | Source |
|---|---|---|
| chromium | shExpMatch converts the glob to a RegExp without escaping ( ) | ; regex alternation works. | code, verified 2026-10-04 · ref |
| firefox | Same helper-library approach (ascii_pac_utils.js); regex alternation works. | code, unverified |
| winhttp | Unverified; native implementation. | expert, unverified |
Related rules
- Path, port or query characters in a host pattern PAC-C003
- Pattern with leading and trailing * is a substring match PAC-X009