Hi all,
I have read the syntax and semantics chapter and was just wondering why values in the attribute position aren't escaped by default? Or is there something I am missing?
- sim
On 5/21/07, Simon Cusack scusack@fastmail.com.au wrote:
I have read the syntax and semantics chapter and was just wondering why values in the attribute position aren't escaped by default? Or is there something I am missing?
I guess it's the same reason why body text ain't escaped by default, because the lib can't assume too much about that data that you are feeding.
In my experience 95% of the time the attribute values are constant html attributes like :width "100%" or :colspan 2 etc that don't require escaping.
But your use case might be different.
-- Mac
Hi Mac,
----- Original message ----- From: "Mac Chan" emailmac@gmail.com To: "General interest list about cl-who" cl-who-devel@common-lisp.net Date: Mon, 21 May 2007 21:50:12 -0700 Subject: Re: [cl-who-devel] escaping attributes question
On 5/21/07, Simon Cusack scusack@fastmail.com.au wrote:
I have read the syntax and semantics chapter and was just wondering why values in the attribute position aren't escaped by default? Or is there something I am missing?
I guess it's the same reason why body text ain't escaped by default, because the lib can't assume too much about that data that you are feeding.
Values in the attribute position get treated differently to body text already. They are included in the html stream by default and the result of lisp forms are emited when used in this position.
It just feels natural to me that it goes the extra step and also escapes the value so that it is 'safe'.
In my experience 95% of the time the attribute values are constant html attributes like :width "100%" or :colspan 2 etc that don't require escaping.
But your use case might be different. -- Mac
Well I'm in the unfortunate position where we regularly included the results of calculations as attributes for a javascript library to hook into. Something like the following is pretty common.
(defun emit-ajaxy-button (url) (with-html-output (*html-stream*) ((:input :type :button :onclick (format nil "javascript:doMyAjaxyThing('~A')" url)) "whatever...")))
It gets pretty messy having to remember which ones to escape all the time.
I patched my convert-attributes (added calls to escape-string code in all caps) to do the following;
(defun convert-attributes (attr-list) "Helper function for CONVERT-TAG-TO-STRING-LIST which converts the alist ATTR-LIST of attributes into a list of strings and/or Lisp forms." (declare (optimize speed space)) (loop with =var= = (gensym) with attribute-quote = (string *attribute-quote-char*) for (attr . val) in attr-list unless (null val) ;; no attribute at all if VAL is NIL if (constantp val) if (and (eq *html-mode* :sgml) (eq val t)) ; special case for SGML nconc (list " " (string-downcase attr)) else nconc (list " " ;; name of attribute (string-downcase attr) (format nil "=~C" *attribute-quote-char*) ;; value of attribute (cond ((stringp val) ;; a string, just use it - this case is ;; actually not necessary because of ;; the last case (ESCAPE-STRING val)) ((eq val t) ;; VAL is T, use attribute's name (string-downcase attr)) (t ;; constant form, PRINC it - ;; EVAL is OK here because of CONSTANTP (ESCAPE-STRING (FORMAT NIL "~A" (eval val))))) attribute-quote) end else ;; do the same things as above but at runtime nconc (list `(let ((,=var= ,val)) (cond ((null ,=var=)) ((eq ,=var= t) ,(case *html-mode* (:sgml `(htm ,(format nil " ~A" (string-downcase attr)))) ;; otherwise default to :xml mode (t `(htm ,(format nil " ~A=~C~A~C" (string-downcase attr) *attribute-quote-char* (string-downcase attr) *attribute-quote-char*))))) (t (htm ,(format nil " ~A=~C" (string-downcase attr) *attribute-quote-char*) (STR (ESCAPE-STRING (FORMAT NIL "~A" ,=var=))) ,attribute-quote)))))))
It seems like a sane thing to do to me but was wondering if I had missed the CL-WHO way of doing the same thing.
Any comments would be most appreciated.
- sim.
On Tue, 22 May 2007 16:02:51 +1000, "Simon Cusack" scusack@fastmail.com.au wrote:
It seems like a sane thing to do to me
Not to me because you never know where the data you feed into the the macro comes from. It might as well be the case that it is already escaped. Turning escaping on by default with no means of turning it off seems very wrong to me.
Cheers, Edi.
Hi Edi,
----- Original message ----- From: "Edi Weitz" edi@agharta.de Date: Tue, 22 May 2007 08:35:58 +0200 Subject: Re: [cl-who-devel] escaping attributes question
On Tue, 22 May 2007 16:02:51 +1000, "Simon Cusack" scusack@fastmail.com.au wrote:
It seems like a sane thing to do to me
Not to me because you never know where the data you feed into the the macro comes from. It might as well be the case that it is already escaped. Turning escaping on by default with no means of turning it off seems very wrong to me.
Cheers, Edi.
Yeah not being able to control it for special cases is bad.
But you know that all values in the attribute position are always going to the html output stream and for it to be interpreted properly it should be escaped.
The decision to always emit to the html stream rather than requiring an esc, fmt or prn for all attribute values means that the values being emitted here are already getting special treatment from CL-WHO.
If the default position is a hands off one, then strictly speaking shouldn't all attribute values them be enclosed in (str ...), etal?
What if it was optional behaviour?
Regards, sim.
On Tue, 22 May 2007 17:07:59 +1000, "Simon Cusack" scusack@fastmail.com.au wrote:
But you know that all values in the attribute position are always going to the html output stream and for it to be interpreted properly it should be escaped.
The decision to always emit to the html stream rather than requiring an esc, fmt or prn for all attribute values means that the values being emitted here are already getting special treatment from CL-WHO.
If the default position is a hands off one, then strictly speaking shouldn't all attribute values them be enclosed in (str ...), etal?
I don't think so. The "evaluation model" (so to say) for the body is different from the attribute values, because the body can contain other, nested elements while the attribute values can only be character content.