summaryrefslogtreecommitdiffstats
path: root/src/lib/test-istream-base64-encoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/test-istream-base64-encoder.c')
-rw-r--r--src/lib/test-istream-base64-encoder.c222
1 files changed, 222 insertions, 0 deletions
diff --git a/src/lib/test-istream-base64-encoder.c b/src/lib/test-istream-base64-encoder.c
new file mode 100644
index 0000000..9fc0608
--- /dev/null
+++ b/src/lib/test-istream-base64-encoder.c
@@ -0,0 +1,222 @@
+/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "str.h"
+#include "istream-private.h"
+#include "istream-base64.h"
+
+struct base64_istream_test {
+ const char *input;
+ unsigned int chars_per_line;
+ bool crlf;
+ const char *output;
+};
+
+static const struct base64_istream_test base64_tests[] = {
+ { "", 80, FALSE, "" },
+ { "1", 80, FALSE, "MQ==" },
+ { "12", 80, FALSE, "MTI=" },
+ { "123", 80, FALSE, "MTIz" },
+ { "1234", 80, FALSE, "MTIzNA==" },
+ { "12345", 80, FALSE, "MTIzNDU=" },
+ { "hello world", 80, FALSE, "aGVsbG8gd29ybGQ=" },
+ { "hello world", 4, FALSE, "aGVs\nbG8g\nd29y\nbGQ=" },
+ { "hello world", 4, TRUE, "aGVs\r\nbG8g\r\nd29y\r\nbGQ=" },
+ { "hello worlds", 80, FALSE, "aGVsbG8gd29ybGRz" },
+ { "hello worlds", 4, FALSE, "aGVs\nbG8g\nd29y\nbGRz" },
+ { "hello worlds", 4, TRUE, "aGVs\r\nbG8g\r\nd29y\r\nbGRz" },
+ { "hell world", 80, FALSE, "aGVsbCB3b3JsZA==" },
+ { "hell world", 4, FALSE, "aGVs\nbCB3\nb3Js\nZA==" },
+ { "hell world", 4, TRUE, "aGVs\r\nbCB3\r\nb3Js\r\nZA==" },
+ { "hello to the world!!", 80, FALSE,
+ "aGVsbG8gdG8gdGhlIHdvcmxkISE=" },
+ { "hello to the world!!", 8, FALSE,
+ "aGVsbG8g\ndG8gdGhl\nIHdvcmxk\nISE=" },
+ { "hello to the world!!", 8, TRUE,
+ "aGVsbG8g\r\ndG8gdGhl\r\nIHdvcmxk\r\nISE=" },
+ { "\xd0\x93\xd0\xbe\xd0\xb2\xd0\xbe\xd1\x80\xd1\x8f\xcc"
+ "\x81\xd1\x82\x2c\x20\xd1\x87\xd1\x82\xd0\xbe\x20\xd0"
+ "\xba\xd1\x83\xd1\x80\x20\xd0\xb4\xd0\xbe\xd1\x8f\xcc"
+ "\x81\xd1\x82\x2e", 80, FALSE,
+ "0JPQvtCy0L7RgNGPzIHRgiwg0YfRgtC+INC60YPRgCDQtNC+0Y/MgdGCLg==" },
+};
+
+static const struct base64_istream_test base64url_tests[] = {
+ { "", 80, FALSE, "" },
+ { "1", 80, FALSE, "MQ==" },
+ { "12", 80, FALSE, "MTI=" },
+ { "123", 80, FALSE, "MTIz" },
+ { "1234", 80, FALSE, "MTIzNA==" },
+ { "12345", 80, FALSE, "MTIzNDU=" },
+ { "hello world", 80, FALSE, "aGVsbG8gd29ybGQ=" },
+ { "hello world", 4, FALSE, "aGVs\nbG8g\nd29y\nbGQ=" },
+ { "hello world", 4, TRUE, "aGVs\r\nbG8g\r\nd29y\r\nbGQ=" },
+ { "hello worlds", 80, FALSE, "aGVsbG8gd29ybGRz" },
+ { "hello worlds", 4, FALSE, "aGVs\nbG8g\nd29y\nbGRz" },
+ { "hello worlds", 4, TRUE, "aGVs\r\nbG8g\r\nd29y\r\nbGRz" },
+ { "hell world", 80, FALSE, "aGVsbCB3b3JsZA==" },
+ { "hell world", 4, FALSE, "aGVs\nbCB3\nb3Js\nZA==" },
+ { "hell world", 4, TRUE, "aGVs\r\nbCB3\r\nb3Js\r\nZA==" },
+ { "hello to the world!!", 80, FALSE,
+ "aGVsbG8gdG8gdGhlIHdvcmxkISE=" },
+ { "hello to the world!!", 8, FALSE,
+ "aGVsbG8g\ndG8gdGhl\nIHdvcmxk\nISE=" },
+ { "hello to the world!!", 8, TRUE,
+ "aGVsbG8g\r\ndG8gdGhl\r\nIHdvcmxk\r\nISE=" },
+ { "\xd0\x93\xd0\xbe\xd0\xb2\xd0\xbe\xd1\x80\xd1\x8f\xcc"
+ "\x81\xd1\x82\x2c\x20\xd1\x87\xd1\x82\xd0\xbe\x20\xd0"
+ "\xba\xd1\x83\xd1\x80\x20\xd0\xb4\xd0\xbe\xd1\x8f\xcc"
+ "\x81\xd1\x82\x2e", 80, FALSE,
+ "0JPQvtCy0L7RgNGPzIHRgiwg0YfRgtC-INC60YPRgCDQtNC-0Y_MgdGCLg==" },
+};
+
+static const char *hello = "hello world";
+
+static void encode_test(unsigned int text_len,
+ struct istream *input, struct istream *input_data,
+ const char *output)
+{
+ unsigned int i;
+ const unsigned char *data;
+ uoff_t stream_size;
+ size_t size;
+ ssize_t ret;
+
+ for (i = 1; i <= text_len; i++) {
+ test_istream_set_size(input_data, i);
+ while ((ret = i_stream_read(input)) > 0) ;
+ test_assert(ret == 0);
+ }
+ test_istream_set_allow_eof(input_data, TRUE);
+ while ((ret = i_stream_read(input)) > 0) ;
+ test_assert(ret == -1);
+
+ data = i_stream_get_data(input, &size);
+ test_assert(size == strlen(output) && memcmp(data, output, size) == 0);
+
+ ret = i_stream_get_size(input, TRUE, &stream_size);
+ test_assert(ret > 0);
+ test_assert(size == stream_size);
+}
+
+static void
+encode_base64_test(const char *text, unsigned int chars_per_line,
+ bool crlf, const char *output)
+{
+ unsigned int text_len = strlen(text);
+ struct istream *input, *input_data;
+
+ input_data = test_istream_create_data(text, text_len);
+ test_istream_set_allow_eof(input_data, FALSE);
+ input = i_stream_create_base64_encoder(input_data, chars_per_line,
+ crlf);
+
+ encode_test(text_len, input, input_data, output);
+
+ i_stream_unref(&input);
+ i_stream_unref(&input_data);
+}
+
+static void
+encode_base64url_test(const char *text, unsigned int chars_per_line,
+ bool crlf, const char *output)
+{
+ unsigned int text_len = strlen(text);
+ struct istream *input, *input_data;
+
+ input_data = test_istream_create_data(text, text_len);
+ test_istream_set_allow_eof(input_data, FALSE);
+ input = i_stream_create_base64url_encoder(input_data, chars_per_line,
+ crlf);
+
+ encode_test(text_len, input, input_data, output);
+
+ i_stream_unref(&input);
+ i_stream_unref(&input_data);
+}
+
+static void
+test_encoder_seek(struct istream *input, const char *textout)
+{
+ unsigned int offset, len = strlen(textout);
+ const unsigned char *data;
+ size_t size;
+ ssize_t ret;
+
+ while (i_stream_read(input) > 0) ;
+ i_stream_skip(input, i_stream_get_data_size(input));
+
+ for (offset = 0; offset < len; offset++) {
+ i_stream_seek(input, offset);
+ while ((ret = i_stream_read(input)) > 0) ;
+ test_assert(ret == -1);
+
+ data = i_stream_get_data(input, &size);
+ test_assert(size == len-offset);
+ test_assert(memcmp(data, textout+offset, size) == 0);
+ i_stream_skip(input, size);
+ }
+}
+
+static void
+test_istream_base64_encoder_seek(const char *textin, const char *textout)
+{
+ struct istream *input, *input_data;
+
+ input_data = i_stream_create_from_data(textin, strlen(textin));
+ input = i_stream_create_base64_encoder(input_data, 4, TRUE);
+
+ test_encoder_seek(input, textout);
+
+ i_stream_unref(&input);
+ i_stream_unref(&input_data);
+}
+
+static void
+test_istream_base64url_encoder_seek(const char *textin, const char *textout)
+{
+ struct istream *input, *input_data;
+
+ input_data = i_stream_create_from_data(textin, strlen(textin));
+ input = i_stream_create_base64url_encoder(input_data, 4, TRUE);
+
+ test_encoder_seek(input, textout);
+
+ i_stream_unref(&input);
+ i_stream_unref(&input_data);
+}
+
+void test_istream_base64_encoder(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < N_ELEMENTS(base64_tests); i++) {
+ const struct base64_istream_test *test = &base64_tests[i];
+
+ test_begin(t_strdup_printf(
+ "istream base64 encoder %u", i+1));
+ encode_base64_test(test->input, test->chars_per_line,
+ test->crlf, test->output);
+ test_end();
+ }
+
+ for (i = 0; i < N_ELEMENTS(base64url_tests); i++) {
+ const struct base64_istream_test *test = &base64url_tests[i];
+
+ test_begin(t_strdup_printf(
+ "istream base64url encoder %u", i+1));
+ encode_base64url_test(test->input, test->chars_per_line,
+ test->crlf, test->output);
+ test_end();
+ }
+
+ test_begin("istream base64 encoder seek");
+ test_istream_base64_encoder_seek(
+ hello, "aGVs\r\nbG8g\r\nd29y\r\nbGQ=");
+ test_end();
+
+ test_begin("istream base64url encoder seek");
+ test_istream_base64url_encoder_seek(
+ hello, "aGVs\r\nbG8g\r\nd29y\r\nbGQ=");
+ test_end();
+}