[bknr-cvs] hans changed trunk/thirdparty/hunchentoot/util.lisp
BKNR Commits
bknr at bknr.net
Thu Sep 4 09:24:47 UTC 2008
Revision: 3785
Author: hans
URL: http://bknr.net/trac/changeset/3785
support non-standard %u notation in URL-DECODE
U trunk/thirdparty/hunchentoot/util.lisp
Modified: trunk/thirdparty/hunchentoot/util.lisp
===================================================================
--- trunk/thirdparty/hunchentoot/util.lisp 2008-09-03 16:50:27 UTC (rev 3784)
+++ trunk/thirdparty/hunchentoot/util.lisp 2008-09-04 09:24:47 UTC (rev 3785)
@@ -229,32 +229,57 @@
((#\") (write-string "\\\"" out))
(otherwise (write-char char out)))))))
+(defmacro upgrade-vector (vector new-type &key converter (new-length `(array-total-size ,vector)))
+ `(setf ,vector (loop
+ with new-vector = (make-array ,new-length
+ :element-type ,new-type
+ :fill-pointer (length vector))
+ for i from 0 below (length ,vector)
+ do (setf (aref new-vector i) ,(if converter
+ `(funcall ,converter (aref ,vector i))
+ `(aref ,vector i)))
+ finally (return new-vector))))
+
(defun url-decode (string &optional (external-format *hunchentoot-default-external-format*))
"Decodes a URL-encoded STRING which is assumed to be encoded using
the external format EXTERNAL-FORMAT."
- (let ((vector (make-array (length string)
- :element-type 'octet
- :fill-pointer 0)))
- (loop with percent-p and buff
- for char of-type character across string
- for i from 0
- when buff do
- (vector-push (parse-integer string
- :start (1- i)
- :end (1+ i)
- :radix 16)
- vector)
- (setq buff nil)
- else when percent-p
- do (setq buff t
- percent-p nil)
- else when (char= char #\%)
- do (setq percent-p t)
- else do (vector-push (char-code (case char
- ((#\+) #\Space)
- (otherwise char)))
- vector))
- (octets-to-string vector :external-format external-format)))
+ (loop
+ with vector = (make-array (length string) :element-type 'octet :fill-pointer 0)
+ with i = 0
+ with unicode
+ for char = (aref string i)
+ do (labels ((decode-hex (length)
+ (prog1
+ (parse-integer string :start i :end (+ i length) :radix 16)
+ (incf i length)))
+ (push-integer (integer)
+ (vector-push integer vector))
+ (peek ()
+ (aref string i))
+ (advance ()
+ (setf char (peek))
+ (incf i)))
+ (cond
+ ((char= #\% char)
+ (advance)
+ (cond
+ ((char= #\u (peek))
+ (unless unicode
+ (setf unicode t)
+ (upgrade-vector vector '(integer 0 65535)))
+ (advance)
+ (push-integer (decode-hex 4)))
+ (t
+ (push-integer (decode-hex 2)))))
+ (t
+ (push-integer (char-code (case char
+ ((#\+) #\Space)
+ (otherwise char))))
+ (advance))))
+ while (< i (length string))
+ finally (return (if unicode
+ (upgrade-vector vector 'character :converter #'code-char)
+ (octets-to-string vector :external-format external-format)))))
(defun form-url-encoded-list-to-alist (form-url-encoded-list
&optional (external-format *hunchentoot-default-external-format*))
More information about the Bknr-cvs
mailing list