;;; guile-email --- Guile email parser ;;; Copyright © 2020 Arun Isaac ;;; ;;; This file is part of guile-email. ;;; ;;; guile-email is free software; you can redistribute it and/or modify ;;; it under the terms of the GNU Affero General Public License as ;;; published by the Free Software Foundation; either version 3 of the ;;; License, or (at your option) any later version. ;;; ;;; guile-email is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; Affero General Public License for more details. ;;; ;;; You should have received a copy of the GNU Affero General Public ;;; License along with guile-email. If not, see ;;; . (use-modules (email base64) (ice-9 iconv) (srfi srfi-64)) (load "encoding.scm") (define (string-has-only-valid-base64-characters? str) (string-every (char-set-union (char-set #\newline #\return #\space) (ucs-range->char-set (char->integer #\A) (1+ (char->integer #\Z))) (ucs-range->char-set (char->integer #\a) (1+ (char->integer #\z))) (ucs-range->char-set (char->integer #\0) (1+ (char->integer #\9))) (char-set #\+ #\/ #\=)) str)) (test-begin "base64") (let ((decoded-text "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.") (encoded-text "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=") (charset "UTF-8")) (test-equal "base64 wikipedia example: decoding" (bytevector->string (base64-decode encoded-text) charset) decoded-text) (test-equal "base64 wikipedia example: encoding" (base64-encode (string->bytevector decoded-text charset)) encoded-text) (test-assert "base64 wikipedia example: encoded output should not be more than 76 columns wide" (each-line-has-a-maximum-of-76-characters? (base64-encode (string->bytevector decoded-text charset))))) (test-assert "base64 random bytevector: base64-encode and base64-decode are inverses of each other" (every (lambda (len) (let ((x (random-bytevector len))) (equal? x (base64-decode (base64-encode x))))) (iota 1000))) (test-assert "base64 random bytevector: encoded output should not be more than 76 columns wide" (every (lambda (len) (each-line-has-a-maximum-of-76-characters? (base64-encode (random-bytevector len)))) (iota 1000))) (test-assert "base64 random bytevector: encoded output must only consist of characters from the base64 alphabet" (every (lambda (len) (string-has-only-valid-base64-characters? (base64-encode (random-bytevector len)))) (iota 1000))) (test-equal "base64 decoding should ignore invalid characters" (bytevector->string (base64-decode "..TWFu,") "utf-8") "Man") (test-end "base64")