/*
* Copyright (c) 2013 Red Hat Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* * Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* * The names of contributors to this software may not be
* used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* Author: Stef Walter <stefw@redhat.com>
*/
#include "config.h"
#include "test.h"
#include "debug.h"
#include "message.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "url.h"
static void
check_decode_msg (const char *file,
int line,
const char *function,
const char *input,
ssize_t input_len,
const char *expected,
size_t expected_len)
{
unsigned char *decoded;
size_t length;
if (input_len < 0)
input_len = strlen (input);
decoded = p11_url_decode (input, input + input_len, "", &length);
if (expected == NULL) {
if (decoded != NULL)
p11_test_fail (file, line, function, "decoding should have failed");
} else {
if (decoded == NULL)
p11_test_fail (file, line, function, "decoding failed");
if (expected_len != length)
p11_test_fail (file, line, function, "wrong length: (%lu != %lu)",
(unsigned long)expected_len, (unsigned long)length);
if (memcmp (decoded, expected, length) != 0)
p11_test_fail (file, line, function, "decoding wrong");
free (decoded);
}
}
#define check_decode_success(input, input_len, expected, expected_len) \
check_decode_msg (__FILE__, __LINE__, __FUNCTION__, input, input_len, expected, expected_len)
#define check_decode_failure(input, input_len) \
check_decode_msg (__FILE__, __LINE__, __FUNCTION__, input, input_len, NULL, 0)
static void
test_decode_success (void)
{
check_decode_success ("%54%45%53%54%00", -1, "TEST", 5);
check_decode_success ("%54%45%53%54%00", 6, "TE", 2);
check_decode_success ("%54est%00", -1, "Test", 5);
}
static void
test_decode_skip (void)
{
const char *input = "%54 %45 %53 %54 %00";
unsigned char *decoded;
size_t length;
decoded = p11_url_decode (input, input + strlen (input), P11_URL_WHITESPACE, &length);
assert_str_eq ("TEST", (char *)decoded);
assert_num_eq (5, length);
free (decoded);
}
static void
test_decode_failure (void)
{
/* Early termination */
check_decode_failure ("%54%45%53%5", -1);
check_decode_failure ("%54%45%53%", -1);
/* Not hex characters */
check_decode_failure ("%54%XX%53%54%00", -1);
}
static void
test_encode (void)
{
const unsigned char *input = (unsigned char *)"TEST";
p11_buffer buf;
if (!p11_buffer_init_null (&buf, 5))
assert_not_reached ();
p11_url_encode (input, input + 5, "", &buf);
assert (p11_buffer_ok (&buf));
assert_str_eq ("%54%45%53%54%00", (char *)buf.data);
assert_num_eq (15, buf.len);
p11_buffer_uninit (&buf);
}
static void
test_encode_verbatim (void)
{
const unsigned char *input = (unsigned char *)"TEST";
p11_buffer buf;
if (!p11_buffer_init_null (&buf, 5))
assert_not_reached ();
p11_url_encode (input, input + 5, "ES", &buf);
assert (p11_buffer_ok (&buf));
assert_str_eq ("%54ES%54%00", (char *)buf.data);
assert_num_eq (11, buf.len);
p11_buffer_uninit (&buf);
}
static void
test_encode_lower (void)
{
const unsigned char *input = (unsigned char *)",.:;";
p11_buffer buf;
if (!p11_buffer_init_null (&buf, 5))
assert_not_reached ();
p11_url_encode (input, input + 5, "", &buf);
assert (p11_buffer_ok (&buf));
assert_str_eq ("%2C%2E%3A%3B%00", (char *)buf.data);
assert_num_eq (15, buf.len);
if (!p11_buffer_reset (&buf, 5))
assert_not_reached ();
setenv ("P11_KIT_URI_LOWERCASE", "1", 1);
p11_url_encode (input, input + 5, "", &buf);
assert (p11_buffer_ok (&buf));
assert_str_eq ("%2c%2e%3a%3b%00", (char *)buf.data);
assert_num_eq (15, buf.len);
p11_buffer_uninit (&buf);
}
int
main (int argc,
char *argv[])
{
p11_test (test_decode_success, "/url/decode-success");
p11_test (test_decode_skip, "/url/decode-skip");
p11_test (test_decode_failure, "/url/decode-failure");
p11_test (test_encode, "/url/encode");
p11_test (test_encode_verbatim, "/url/encode-verbatim");
p11_test (test_encode_lower, "/url/encode-lower");
return p11_test_run (argc, argv);
}