diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2023-05-29 19:14:11 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2023-05-29 19:14:11 -0700 |
commit | 271e541893c4d10b3b4fa8f20cb6c54f0af2527e (patch) | |
tree | d88068ca91fffbacc04359e8084b90551ea884fe /who.tl | |
parent | ff4671eca8e75611a76368eb3f3a3dde334ddb80 (diff) | |
download | tl-who-271e541893c4d10b3b4fa8f20cb6c54f0af2527e.tar.gz tl-who-271e541893c4d10b3b4fa8f20cb6c54f0af2527e.tar.bz2 tl-who-271e541893c4d10b3b4fa8f20cb6c54f0af2527e.zip |
Fix CL-WHO attr bugs: no escaping, poor constant handling.
CL-WHO tries to handle the case when attribute values are
constant NIL and T values, but it bungles it; it applies
the correct behavior only when the constants are literally
these symbols, not when they are constant expressions
which evaluate to these values.
Secondly, CL-WHO neglects to HTML-escape attribute values.
We fix this behavior and introduce a noesc operator to
selectively revert it, as well as a *cl-who-compat* special
to revert the behavior more pervasively, for the daredevils.
* packages.tl (tl-who): New symbols *cl-who-compat* and noesc.
* specials.tl (*cl-who-compat*): New special variable.
* who.tl (convert-attributes): When treating a constant
expression, evaluate it first, then check for nil or t.
Escape interpolated text with html-encode.
Check the original expression for (noesc ...) pattern,
or the presence of *cl-who-compat*. In these cases, don't
generate the escape call.
* test/simple.tl: New tests 28 to 37 providing some coverage
to all these changes.
* README.md: Document.
Diffstat (limited to 'who.tl')
-rw-r--r-- | who.tl | 49 |
1 files changed, 29 insertions, 20 deletions
@@ -92,26 +92,35 @@ (with-gensyms (=var=) (let ((aqc *attribute-quote-char*)) (keep-matches (^(,orig-attr . ,val) attr-list) - (let ((attr (maybe-upcase orig-attr))) - (if val - (if (constantp val) - ;; Handle constant attribute value at macro time - (if (and *empty-attribute-syntax* (eq val t)) - ` @attr` - ` @attr=@aqc@(if (eq val t) - attr - (tostringp (eval val)))@aqc`) - ;; For non-constant, do the same things as above but at runtime - ^(let ((,=var= ,val)) - (cond - ((null ,=var=)) - ((eq ,=var= t) - (str ,(if *empty-attribute-syntax* - ^` @,attr` - ^` @,attr=@,aqc@,attr@,aqc`))) - (t - (str ` @,attr=@,aqc@{,=var=}@,aqc`))))))))))) - + (let ((attr (maybe-upcase orig-attr)) + noesc) + (when-match (noesc . @rest) val + (set noesc t) + (set val ^(progn ,*rest))) + (if (constantp val) + ;; Handle constant attribute value at macro time + (let ((eval (eval val))) + (cond + ((null eval)) + ((eq eval t) + (if *empty-attribute-syntax* + ` @attr` + ` @attr=@aqc@attr@aqc`)) + ((or noesc *cl-who-compat*) ;; no escaping in CL-WHO compat mode + ` @attr=@aqc@(tostringp eval)@aqc`) + (t ` @attr=@aqc@(html-encode (tostringp eval))@aqc`))) + ;; For non-constant, do the same things as above but at runtime + ^(let ((,=var= ,val)) + (cond + ((null ,=var=)) + ((eq ,=var= t) + (str ,(if *empty-attribute-syntax* + ^` @,attr` + ^` @,attr=@,aqc@,attr@,aqc`))) + (t + ,(if (or noesc *cl-who-compat*) + ^(str ` @,attr=@,aqc@{,=var=}@,aqc`) + ^(str ` @,attr=@,aqc@(html-encode ,=var=)@,aqc`))))))))))) ;; Used by process-tag to convert `HTML' into a list ;; of strings. tag is a keyword symbol naming the outer tag, attr-list |