https://tools.ietf.org/html/rfc2045#section-6.7
`In this encoding, octets are to be represented as determined by the
following rules:
`(1) (General 8bit representation) Any octet, except a CR or
LF that is part of a CRLF line break of the canonical
(standard) form of the data being encoded, may be
represented by an "=" followed by a two digit
hexadecimal representation of the octet's value. The
digits of the hexadecimal alphabet, for this purpose,
are "
0123456789ABCDEF". Uppercase letters must be
used; lowercase letters are not allowed. [...]'
(cherry picked from commit
280d8a878893e33d124dd22553890f6c71988008)
--- /dev/null
+Bug fix: The quoted-printable encoder correctly produces uppercase
+hexadecimal digits; a change in the default case of output in
+digit->char had caused it to erroneously produce lowercase hexadecimal
+digits in violation of RFC 2045.
(cond ((fix:< start end)
(let ((char (string-ref string start))
(start (fix:+ start 1)))
- (cond ((not (char-lwsp? char))
+ (cond ((not (char-8-bit? char))
+ (error "Quoted-printable encoder can't handle Unicode"))
+ ((not (char-lwsp? char))
(if (char-in-set? char char-set:qp-encoded)
(write-qp-encoded context char)
(write-qp-clear context char))
(let ((port (qp-encoding-context/port context))
(column (qp-encoding-context/column context))
(d (char->integer char)))
- (let ((c1 (digit->char (fix:lsh d -4) 16))
- (c2 (digit->char (fix:and d #x0F) 16)))
+ (assert (<= 0 d #xff))
+ (define (hex c) (string-ref "0123456789ABCDEF" c))
+ (let ((c1 (hex (fix:lsh d -4)))
+ (c2 (hex (fix:and d #x0F))))
(if (fix:= column 73)
(set-qp-encoding-context/pending-output! context (string #\= c1 c2))
(begin
(define-test 'QUOTED-PRINTABLE/UPPERCASE
(lambda ()
- ;; Currently uses digit->char which no longer produces uppercase.
- (expect-failure
- (lambda ()
- (let* ((string "The quïck brøwn fox jump§ over the lazʒ doﻎ.")
- (utf8 (string->utf8 string))
- (bytestring (iso8859-1->string utf8)))
- (assert-equal
- (encode-quoted-printable bytestring #t)
- (string-append "The qu=C3=AFck br=C3=B8wn=C2=A0fox jump=C2=A7"
- " over the laz=CA=92 do=EF=BB=\n=8E.")))))))
+ (let* ((string "The quïck brøwn fox jump§ over the lazʒ doﻎ.")
+ (utf8 (string->utf8 string))
+ (bytestring (iso8859-1->string utf8)))
+ (assert-equal
+ (encode-quoted-printable bytestring #t)
+ (string-append "The qu=C3=AFck br=C3=B8wn=C2=A0fox jump=C2=A7"
+ " over the laz=CA=92 do=EF=BB=\n=8E.")))))
(define-test 'QUOTED-PRINTABLE/UNICODE-BUG
(lambda ()