ironclad
ironclad copied to clipboard
Under ECL 24.5.10 byte-array-to-hex-string (v0.59) miscompiles due to (safety 0)
(In the exhibit below, scroll to the right to see the mismatch.)
CL-USER> (asdf:test-system :aws-sign4)
Expected presigned url:
"https://examplebucket.s3.amazonaws.com/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=aeeed9bbccd4d02ee5c0109b86d86835f995330da4c265957d157751f604d404"
Got:
"https://examplebucket.s3.amazonaws.com/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=3\0\0\0\0\0\0\0\0\0\001\0\0\0\0\0\0\0\03\0\0\0\02\03\0\0\0\0\01\0\0\01\003\02\0\0\03\0\0\02\03\0\03\0\0\0\0\0\00"
Simply changing safety to 1 solves this:
(defun byte-array-to-hex-string (vector &key (start 0) end (element-type 'base-char))
"Return a string containing the hexadecimal representation of the
subsequence of VECTOR between START and END. ELEMENT-TYPE controls
the element-type of the returned string."
(declare (type (vector (unsigned-byte 8)) vector)
(type fixnum start)
(type (or null fixnum) end)
(optimize (speed 3) (safety 1)))
(let* ((end (or end (length vector)))
(length (- end start))
(hexdigits #.(coerce "0123456789abcdef" 'simple-base-string)))
(loop with string = (ecase element-type
;; so that the compiler optimization can jump in
(base-char (make-string (* length 2)
:element-type 'base-char))
(character (make-string (* length 2)
:element-type 'character)))
for i from start below end
for j from 0 below (* length 2) by 2
do (let ((byte (aref vector i)))
#+ecl
(declare (optimize (safety 1)))
#-ecl
(declare (optimize (safety 0)))
(setf (aref string j)
(aref hexdigits (ldb (byte 4 4) byte))
(aref string (1+ j))
(aref hexdigits (ldb (byte 4 0) byte))))
finally (return string))))
Notes:
- I am using Ubuntu 22.04 on x64.
- Ironclad tests pass.