This goes beyond mere Lisp macros, in that ordinary Lisp macro invocations still look like Lisp lists, while with this you can make arbitrary changes to the syntax, you could even make Common Lisp look like Pascal (if you really wanted to)
The designers of Scheme intentionally left this feature out (which was also found in some of Common Lisp’s ancestors, such as Maclisp), but some Scheme implementations/descendants included it anyway (as an extension), such as Racket, Guile and Chicken Scheme.
the following code produces a syntax error if the time is less than 10 seconds after a full minute.
#define T __TIME__
#if T[6]-48
#define X 1
#else
#define X /
#endif
void main()
{
write("%d, %c, %O\n", X, T[6], T);
} if [ $(date +%u) -ne 5 ]
then
exit
fi
(Add `sleep 1`, and detect pause on server. Then, if pause detected - serve attack payload. If not - somebody is careful enough to download and audit, so serve just the script.
Discussed on HN:
2020: https://news.ycombinator.com/item?id=25356757 (133 comments)
2018: https://news.ycombinator.com/item?id=17636032 (146 comments)
2016: https://news.ycombinator.com/item?id=11532599 (122 comments)
But that's not bulletproof; consider this code (adapted from <https://hal.archives-ouvertes.fr/hal-01513750/document>):
if [ $(date +%u) -eq 5 ]
then
alias maybe=''
else
alias maybe=:
fi
maybe for x in; do :; done
"sh -n" always reports syntax error, even thought the script syntax is correct on Fridays.The real Perl parser disambiguates with heuristics and run-time hints.
There exists an unambiguous subset of Perl syntax that is expressible with a BNF grammar, and such is amenable to all parsers. http://p3rl.org/standard#DESCRIPTION