* @param {!Array } keys * @param {!{[key: string]: boolean}=} opt_allowlist Optional allowlist of names * that can be substituted. * @return {!RegExp} * @private
(keys, opt_allowlist)
| 278 | * @private |
| 279 | */ |
| 280 | buildExpr_(keys, opt_allowlist) { |
| 281 | // If a allowlist is present, the keys must belong to the allowlist. |
| 282 | // We filter the keys one last time to ensure no unallowlisted key is |
| 283 | // allowed. |
| 284 | if (this.getUrlMacroAllowlist_()) { |
| 285 | keys = keys.filter((key) => this.getUrlMacroAllowlist_().includes(key)); |
| 286 | } |
| 287 | // If a allowlist is passed into the call to GlobalVariableSource.expand_ |
| 288 | // then we only resolve values contained in the allowlist. |
| 289 | if (opt_allowlist) { |
| 290 | keys = keys.filter((key) => opt_allowlist[key]); |
| 291 | } |
| 292 | if (keys.length === 0) { |
| 293 | const regexThatMatchesNothing = /_^/g; // lgtm [js/regex/unmatchable-caret] |
| 294 | return regexThatMatchesNothing; |
| 295 | } |
| 296 | // The keys must be sorted to ensure that the longest keys are considered |
| 297 | // first. This avoids a problem where a RANDOM conflicts with RANDOM_ONE. |
| 298 | keys.sort((s1, s2) => s2.length - s1.length); |
| 299 | // Keys that start with a `$` need to be escaped so that they do not |
| 300 | // interfere with the regex that is constructed. |
| 301 | const escaped = keys.map((key) => { |
| 302 | if (key[0] === '$') { |
| 303 | return '\\' + key; |
| 304 | } |
| 305 | return key; |
| 306 | }); |
| 307 | |
| 308 | const all = escaped.join('|'); |
| 309 | // Match the given replacement patterns, as well as optionally |
| 310 | // arguments to the replacement behind it in parentheses. |
| 311 | // Example string that match |
| 312 | // FOO_BAR |
| 313 | // FOO_BAR(arg1) |
| 314 | // FOO_BAR(arg1,arg2) |
| 315 | // FOO_BAR(arg1, arg2) |
| 316 | const regexStr = '\\$?(' + all + ')'; |
| 317 | return new RegExp(regexStr, 'g'); |
| 318 | } |
| 319 | |
| 320 | /** |
| 321 | * For email documents, all URL macros are disallowed by default. |
no test coverage detected