/*
 * QEMU base64 helper test
 *
 * Copyright (c) 2015 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"

#include "qapi/error.h"
#include "qemu/base64.h"

static void test_base64_good(void)
{
    const char input[] =
        "QmVjYXVzZSB3ZSBmb2N1c2VkIG9uIHRoZSBzbmFrZSwgd2UgbW\n"
        "lzc2VkIHRoZSBzY29ycGlvbi4=";
    const char expect[] = "Because we focused on the snake, "
        "we missed the scorpion.";

    size_t len;
    uint8_t *actual = qbase64_decode(input,
                                     -1,
                                     &len,
                                     &error_abort);

    g_assert(actual != NULL);
    g_assert_cmpint(len, ==, strlen(expect));
    g_assert_cmpstr((char *)actual, ==, expect);
    g_free(actual);
}


static void test_base64_bad(const char *input,
                            size_t input_len)
{
    size_t len;
    Error *err = NULL;
    uint8_t *actual = qbase64_decode(input,
                                     input_len,
                                     &len,
                                     &err);

    error_free_or_abort(&err);
    g_assert(actual == NULL);
    g_assert_cmpint(len, ==, 0);
}


static void test_base64_embedded_nul(void)
{
    /* We put a NUL character in the middle of the base64
     * text which is invalid data, given the expected length */
    const char input[] =
        "QmVjYXVzZSB3ZSBmb2N1c2VkIG9uIHRoZSBzbmFrZSwgd2UgbW\0"
        "lzc2VkIHRoZSBzY29ycGlvbi4=";

    test_base64_bad(input, G_N_ELEMENTS(input) - 1);
}


static void test_base64_not_nul_terminated(void)
{
    const char input[] =
        "QmVjYXVzZSB3ZSBmb2N1c2VkIG9uIHRoZSBzbmFrZSwgd2UgbW\n"
        "lzc2VkIHRoZSBzY29ycGlvbi4=";

    /* Using '-2' to make us drop the trailing NUL, thus
     * creating an invalid base64 sequence for decoding */
    test_base64_bad(input, G_N_ELEMENTS(input) - 2);
}


static void test_base64_invalid_chars(void)
{
    /* We put a single quote character in the middle
     * of the base64 text which is invalid data */
    const char input[] =
        "QmVjYXVzZSB3ZSBmb2N1c2VkIG9uIHRoZSBzbmFrZSwgd2UgbW'"
        "lzc2VkIHRoZSBzY29ycGlvbi4=";

    test_base64_bad(input, strlen(input));
}


int main(int argc, char **argv)
{
    g_test_init(&argc, &argv, NULL);
    g_test_add_func("/util/base64/good", test_base64_good);
    g_test_add_func("/util/base64/embedded-nul", test_base64_embedded_nul);
    g_test_add_func("/util/base64/not-nul-terminated",
                    test_base64_not_nul_terminated);
    g_test_add_func("/util/base64/invalid-chars", test_base64_invalid_chars);
    return g_test_run();
}
